Skip to content

Commit

Permalink
Merge pull request #241 from crowetic/master
Browse files Browse the repository at this point in the history
Selective acceptance of recent PRs to Qortal master branch, and updated start.sh script. See description for details.
  • Loading branch information
crowetic authored Dec 4, 2024
2 parents 9b20192 + 448b536 commit 749143e
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 20 deletions.
20 changes: 19 additions & 1 deletion src/main/java/org/qortal/account/Account.java
Original file line number Diff line number Diff line change
Expand Up @@ -349,10 +349,28 @@ public int getEffectiveMintingLevel() throws DataException {
}

/**
* Returns 'effective' minting level, or zero if reward-share does not exist.
* Returns reward-share minting address, or unknown if reward-share does not exist.
*
* @param repository
* @param rewardSharePublicKey
* @return address or unknown
* @throws DataException
*/
public static String getRewardShareMintingAddress(Repository repository, byte[] rewardSharePublicKey) throws DataException {
// Find actual minter address
RewardShareData rewardShareData = repository.getAccountRepository().getRewardShare(rewardSharePublicKey);

if (rewardShareData == null)
return "Unknown";

return rewardShareData.getMinter();
}

/**
* Returns 'effective' minting level, or zero if reward-share does not exist.
*
* @param repository
* @param rewardSharePublicKey
* @return 0+
* @throws DataException
*/
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/org/qortal/api/model/ApiOnlineAccount.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package org.qortal.api.model;

import org.qortal.account.Account;
import org.qortal.repository.DataException;
import org.qortal.repository.RepositoryManager;
import org.qortal.repository.Repository;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

// All properties to be converted to JSON via JAXB
@XmlAccessorType(XmlAccessType.FIELD)
Expand Down Expand Up @@ -47,4 +53,31 @@ public String getRecipientAddress() {
return this.recipientAddress;
}

public int getMinterLevelFromPublicKey() {
try (final Repository repository = RepositoryManager.getRepository()) {
return Account.getRewardShareEffectiveMintingLevel(repository, this.rewardSharePublicKey);
} catch (DataException e) {
return 0;
}
}

public boolean getIsMember() {
try (final Repository repository = RepositoryManager.getRepository()) {
return repository.getGroupRepository().memberExists(694, getMinterAddress());
} catch (DataException e) {
return false;
}
}

// JAXB special

@XmlElement(name = "minterLevel")
protected int getMinterLevel() {
return getMinterLevelFromPublicKey();
}

@XmlElement(name = "isMinterMember")
protected boolean getMinterMember() {
return getIsMember();
}
}
2 changes: 1 addition & 1 deletion src/main/java/org/qortal/api/model/BlockMintingInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
public class BlockMintingInfo {

public byte[] minterPublicKey;
public String minterAddress;
public int minterLevel;
public int onlineAccountsCount;
public BigDecimal maxDistance;
Expand All @@ -19,5 +20,4 @@ public class BlockMintingInfo {

public BlockMintingInfo() {
}

}
3 changes: 2 additions & 1 deletion src/main/java/org/qortal/api/resource/BlocksResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ public BlockMintingInfo getBlockMintingInfoByHeight(@PathParam("height") int hei
}
}

String minterAddress = Account.getRewardShareMintingAddress(repository, blockData.getMinterPublicKey());
int minterLevel = Account.getRewardShareEffectiveMintingLevel(repository, blockData.getMinterPublicKey());
if (minterLevel == 0)
// This may be unavailable when requesting a trimmed block
Expand All @@ -554,6 +555,7 @@ public BlockMintingInfo getBlockMintingInfoByHeight(@PathParam("height") int hei

BlockMintingInfo blockMintingInfo = new BlockMintingInfo();
blockMintingInfo.minterPublicKey = blockData.getMinterPublicKey();
blockMintingInfo.minterAddress = minterAddress;
blockMintingInfo.minterLevel = minterLevel;
blockMintingInfo.onlineAccountsCount = blockData.getOnlineAccountsCount();
blockMintingInfo.maxDistance = new BigDecimal(block.MAX_DISTANCE);
Expand Down Expand Up @@ -887,5 +889,4 @@ public List<BlockSummaryData> getBlockSummaries(
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
}
}

}
51 changes: 39 additions & 12 deletions src/main/java/org/qortal/block/Block.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public static class ExpandedAccount {

private final Account recipientAccount;
private final AccountData recipientAccountData;

final BlockChain blockChain = BlockChain.getInstance();

ExpandedAccount(Repository repository, RewardShareData rewardShareData) throws DataException {
Expand Down Expand Up @@ -414,6 +414,21 @@ else if (isOnlineAccountsBlock(height)) {
});
}

// After feature trigger, remove any online accounts that are not minter group member
if (height >= BlockChain.getInstance().getGroupMemberCheckHeight()) {
onlineAccounts.removeIf(a -> {
try {
int groupId = BlockChain.getInstance().getMintingGroupId();
String address = Account.getRewardShareMintingAddress(repository, a.getPublicKey());
boolean isMinterGroupMember = repository.getGroupRepository().memberExists(groupId, address);
return !isMinterGroupMember;
} catch (DataException e) {
// Something went wrong, so remove the account
return true;
}
});
}

if (onlineAccounts.isEmpty()) {
LOGGER.debug("No online accounts - not even our own?");
return null;
Expand Down Expand Up @@ -721,19 +736,19 @@ public List<ExpandedAccount> getExpandedAccounts() throws DataException {
List<ExpandedAccount> expandedAccounts = new ArrayList<>();

for (RewardShareData rewardShare : this.cachedOnlineRewardShares) {
if (this.getBlockData().getHeight() < BlockChain.getInstance().getFixBatchRewardHeight()) {
int groupId = BlockChain.getInstance().getMintingGroupId();
String address = rewardShare.getMinter();
boolean isMinterGroupMember = repository.getGroupRepository().memberExists(groupId, address);

if (this.getBlockData().getHeight() < BlockChain.getInstance().getFixBatchRewardHeight())
expandedAccounts.add(new ExpandedAccount(repository, rewardShare));
}
if (this.getBlockData().getHeight() >= BlockChain.getInstance().getFixBatchRewardHeight()) {
boolean isMinterGroupMember = repository.getGroupRepository().memberExists(BlockChain.getInstance().getMintingGroupId(), rewardShare.getMinter());
if (isMinterGroupMember) {
expandedAccounts.add(new ExpandedAccount(repository, rewardShare));
}
}
}

if (this.getBlockData().getHeight() >= BlockChain.getInstance().getFixBatchRewardHeight() && isMinterGroupMember)
expandedAccounts.add(new ExpandedAccount(repository, rewardShare));
}

this.cachedExpandedAccounts = expandedAccounts;
LOGGER.trace(() -> String.format("Online reward-shares after expanded accounts %s", this.cachedOnlineRewardShares));

return this.cachedExpandedAccounts;
}
Expand Down Expand Up @@ -1143,8 +1158,17 @@ public ValidationResult areOnlineAccountsValid() throws DataException {
if (this.getBlockData().getHeight() >= BlockChain.getInstance().getOnlineAccountMinterLevelValidationHeight()) {
List<ExpandedAccount> expandedAccounts = this.getExpandedAccounts();
for (ExpandedAccount account : expandedAccounts) {
int groupId = BlockChain.getInstance().getMintingGroupId();
String address = account.getMintingAccount().getAddress();
boolean isMinterGroupMember = repository.getGroupRepository().memberExists(groupId, address);

if (account.getMintingAccount().getEffectiveMintingLevel() == 0)
return ValidationResult.ONLINE_ACCOUNTS_INVALID;

if (this.getBlockData().getHeight() >= BlockChain.getInstance().getFixBatchRewardHeight()) {
if (!isMinterGroupMember)
return ValidationResult.ONLINE_ACCOUNTS_INVALID;
}
}
}

Expand Down Expand Up @@ -1273,6 +1297,7 @@ public ValidationResult isValid() throws DataException {

// Online Accounts
ValidationResult onlineAccountsResult = this.areOnlineAccountsValid();
LOGGER.trace("Accounts valid = {}", onlineAccountsResult);
if (onlineAccountsResult != ValidationResult.OK)
return onlineAccountsResult;

Expand Down Expand Up @@ -1361,7 +1386,7 @@ private ValidationResult areTransactionsValid() throws DataException {
// Check transaction can even be processed
validationResult = transaction.isProcessable();
if (validationResult != Transaction.ValidationResult.OK) {
LOGGER.info(String.format("Error during transaction validation, tx %s: %s", Base58.encode(transactionData.getSignature()), validationResult.name()));
LOGGER.debug(String.format("Error during transaction validation, tx %s: %s", Base58.encode(transactionData.getSignature()), validationResult.name()));
return ValidationResult.TRANSACTION_INVALID;
}

Expand Down Expand Up @@ -1562,6 +1587,7 @@ public void process() throws DataException {
this.blockData.setHeight(blockchainHeight + 1);

LOGGER.trace(() -> String.format("Processing block %d", this.blockData.getHeight()));
LOGGER.trace(() -> String.format("Online Reward Shares in process %s", this.cachedOnlineRewardShares));

if (this.blockData.getHeight() > 1) {

Expand Down Expand Up @@ -2280,7 +2306,6 @@ protected List<BlockRewardCandidate> determineBlockRewardCandidates(boolean isPr
// Select the correct set of share bins based on block height
List<AccountLevelShareBin> accountLevelShareBinsForBlock = (this.blockData.getHeight() >= BlockChain.getInstance().getSharesByLevelV2Height()) ?
BlockChain.getInstance().getAccountLevelShareBinsV2() : BlockChain.getInstance().getAccountLevelShareBinsV1();

// Determine reward candidates based on account level
// This needs a deep copy, so the shares can be modified when tiers aren't activated yet
List<AccountLevelShareBin> accountLevelShareBins = new ArrayList<>();
Expand Down Expand Up @@ -2570,9 +2595,11 @@ private void logDebugInfo() {
return;

int minterLevel = Account.getRewardShareEffectiveMintingLevel(this.repository, this.getMinter().getPublicKey());
String minterAddress = Account.getRewardShareMintingAddress(this.repository, this.getMinter().getPublicKey());

LOGGER.debug(String.format("======= BLOCK %d (%.8s) =======", this.getBlockData().getHeight(), Base58.encode(this.getSignature())));
LOGGER.debug(String.format("Timestamp: %d", this.getBlockData().getTimestamp()));
LOGGER.debug(String.format("Minter address: %s", minterAddress));
LOGGER.debug(String.format("Minter level: %d", minterLevel));
LOGGER.debug(String.format("Online accounts: %d", this.getBlockData().getOnlineAccountsCount()));
LOGGER.debug(String.format("AT count: %d", this.getBlockData().getATCount()));
Expand Down
29 changes: 26 additions & 3 deletions src/main/java/org/qortal/data/block/BlockData.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package org.qortal.data.block;

import com.google.common.primitives.Bytes;
import org.qortal.account.Account;
import org.qortal.block.BlockChain;
import org.qortal.crypto.Crypto;
import org.qortal.repository.DataException;
import org.qortal.repository.Repository;
import org.qortal.repository.RepositoryManager;
import org.qortal.settings.Settings;
import org.qortal.utils.NTP;

Expand Down Expand Up @@ -224,19 +227,39 @@ public int getOnlineAccountsSignaturesCount() {
}
return 0;
}

public boolean isTrimmed() {
long onlineAccountSignaturesTrimmedTimestamp = NTP.getTime() - BlockChain.getInstance().getOnlineAccountSignaturesMaxLifetime();
long currentTrimmableTimestamp = NTP.getTime() - Settings.getInstance().getAtStatesMaxLifetime();
long blockTimestamp = this.getTimestamp();
return blockTimestamp < onlineAccountSignaturesTrimmedTimestamp && blockTimestamp < currentTrimmableTimestamp;
}

public String getMinterAddressFromPublicKey() {
try (final Repository repository = RepositoryManager.getRepository()) {
return Account.getRewardShareMintingAddress(repository, this.minterPublicKey);
} catch (DataException e) {
return "Unknown";
}
}

public int getMinterLevelFromPublicKey() {
try (final Repository repository = RepositoryManager.getRepository()) {
return Account.getRewardShareEffectiveMintingLevel(repository, this.minterPublicKey);
} catch (DataException e) {
return 0;
}
}

// JAXB special

@XmlElement(name = "minterAddress")
protected String getMinterAddress() {
return Crypto.toAddress(this.minterPublicKey);
return getMinterAddressFromPublicKey();
}

@XmlElement(name = "minterLevel")
protected int getMinterLevel() {
return getMinterLevelFromPublicKey();
}
}
9 changes: 7 additions & 2 deletions start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@ fi
# Limits Java JVM stack size and maximum heap usage.
# Comment out for bigger systems, e.g. non-routers
# or when API documentation is enabled
# Uncomment (remove '#' sign) line below if your system has less than 12GB of RAM for optimal RAM defaults
JVM_MEMORY_ARGS="-Xss256m -XX:+UseSerialGC"
# JAVA MEMORY SETTINGS BELOW - These settings are essentially optimized default settings.
# Combined with the latest changes on the Qortal Core in version 4.6.6 and beyond,
# should give a dramatic increase In performance due to optimized Garbage Collection.
# These memory arguments should work on machines with as little as 6GB of RAM.
# If you want to run on a machine with less than 6GB of RAM, it is suggested to increase the '50' below to '75'
# The Qortal Core will utilize only as much RAM as it needs, but up-to the amount set in percentage below.
JVM_MEMORY_ARGS="-XX:MaxRAMPercentage=50 -XX:+UseG1GC -Xss1024k"

# Although java.net.preferIPv4Stack is supposed to be false
# by default in Java 11, on some platforms (e.g. FreeBSD 12),
Expand Down

0 comments on commit 749143e

Please sign in to comment.