* This is a method, not a final variable, because account's level can change between construction and call, * e.g. during Block.process() where account levels are bumped right before Block.distributeBlockReward(). - * + * * @return account-level share "bin" from blockchain config, or null if founder / none found */ public AccountLevelShareBin getShareBin(int blockHeight) { @@ -192,8 +193,12 @@ public class Block { if (accountLevel <= 0) return null; // level 0 isn't included in any share bins + if (blockHeight >= blockChain.getFixBatchRewardHeight()) { + if (!this.isMinterMember) + return null; // not member of minter group isn't included in any share bins + } + // Select the correct set of share bins based on block height - final BlockChain blockChain = BlockChain.getInstance(); final AccountLevelShareBin[] shareBinsByLevel = (blockHeight >= blockChain.getSharesByLevelV2Height()) ? blockChain.getShareBinsByAccountLevelV2() : blockChain.getShareBinsByAccountLevelV1(); @@ -262,7 +267,7 @@ public class Block { * Constructs new Block without loading transactions and AT states. *
* Transactions and AT states are loaded on first call to getTransactions() or getATStates() respectively. - * + * * @param repository * @param blockData */ @@ -333,7 +338,7 @@ public class Block { /** * Constructs new Block with empty transaction list, using passed minter account. - * + * * @param repository * @param blockData * @param minter @@ -351,7 +356,7 @@ public class Block { * This constructor typically used when minting a new block. *
* Note that CIYAM ATs will be executed and AT-Transactions prepended to this block, along with AT state data and fees. - * + * * @param repository * @param parentBlockData * @param minter @@ -377,7 +382,7 @@ public class Block { byte[] encodedOnlineAccounts = new byte[0]; int onlineAccountsCount = 0; byte[] onlineAccountsSignatures = null; - + if (isBatchRewardDistributionBlock(height)) { // Batch reward distribution block - copy online accounts from recent block with highest online accounts count @@ -512,7 +517,7 @@ public class Block { * Mints new block using this block as template, but with different minting account. *
* NOTE: uses the same transactions list, AT states, etc. - * + * * @param minter * @return * @throws DataException @@ -598,7 +603,7 @@ public class Block { /** * Return composite block signature (minterSignature + transactionsSignature). - * + * * @return byte[], or null if either component signature is null. */ public byte[] getSignature() { @@ -613,7 +618,7 @@ public class Block { *
* We're starting with version 4 as a nod to being newer than successor Qora, * whose latest block version was 3. - * + * * @return 1, 2, 3 or 4 */ public int getNextBlockVersion() { @@ -627,7 +632,7 @@ public class Block { * Return block's transactions. *
* If the block was loaded from repository then it's possible this method will call the repository to fetch the transactions if not done already. - * + * * @return * @throws DataException */ @@ -661,7 +666,7 @@ public class Block { * If the block was loaded from repository then it's possible this method will call the repository to fetch the AT states if not done already. *
* Note: AT states fetched from repository only contain summary info, not actual data like serialized state data or AT creation timestamps! - * + * * @return * @throws DataException */ @@ -697,7 +702,7 @@ public class Block { *
* Typically called as part of Block.process() or Block.orphan()
* so ideally after any calls to Block.isValid().
- *
+ *
* @throws DataException
*/
public List
* Requires block's {@code minter} being a {@code PrivateKeyAccount} so block's transactions signature can be recalculated.
- *
+ *
* @param transactionData
* @return true if transaction successfully added to block, false otherwise
* @throws IllegalStateException
@@ -814,7 +829,7 @@ public class Block {
* Used when constructing a new block during minting.
*
* Requires block's {@code minter} being a {@code PrivateKeyAccount} so block's transactions signature can be recalculated.
- *
+ *
* @param transactionData
* @throws IllegalStateException
* if block's {@code minter} is not a {@code PrivateKeyAccount}.
@@ -859,7 +874,7 @@ public class Block {
* previous block's minter signature + minter's public key + (encoded) online-accounts data
*
* (Previous block's minter signature is extracted from this block's reference).
- *
+ *
* @throws IllegalStateException
* if block's {@code minter} is not a {@code PrivateKeyAccount}.
* @throws RuntimeException
@@ -876,7 +891,7 @@ public class Block {
* Recalculate block's transactions signature.
*
* Requires block's {@code minter} being a {@code PrivateKeyAccount}.
- *
+ *
* @throws IllegalStateException
* if block's {@code minter} is not a {@code PrivateKeyAccount}.
* @throws RuntimeException
@@ -998,7 +1013,7 @@ public class Block {
* Recalculate block's minter and transactions signatures, thus giving block full signature.
*
* Note: Block instance must have been constructed with a PrivateKeyAccount minter or this call will throw an IllegalStateException.
- *
+ *
* @throws IllegalStateException
* if block's {@code minter} is not a {@code PrivateKeyAccount}.
*/
@@ -1011,7 +1026,7 @@ public class Block {
/**
* Returns whether this block's signatures are valid.
- *
+ *
* @return true if both minter and transaction signatures are valid, false otherwise
*/
public boolean isSignatureValid() {
@@ -1035,7 +1050,7 @@ public class Block {
*
* Used by BlockMinter to check whether it's time to mint a new block,
* and also used by Block.isValid for checks (if not a testchain).
- *
+ *
* @return ValidationResult.OK if timestamp valid, or some other ValidationResult otherwise.
* @throws DataException
*/
@@ -1215,7 +1230,7 @@ public class Block {
*
* Checks block's transactions by testing their validity then processing them.
* NOTE: will execute ATs locally if not already done.
* This method is not needed if fetching an existing block from the repository as AT state data will be loaded from repository as well.
- *
+ *
* @see #isValid()
- *
+ *
* @throws DataException
- *
+ *
*/
private void executeATs() throws DataException {
// We're expecting a lack of AT state data at this point.
@@ -1538,7 +1553,7 @@ public class Block {
/**
* Process block, and its transactions, adding them to the blockchain.
- *
+ *
* @throws DataException
*/
public void process() throws DataException {
@@ -1839,7 +1854,7 @@ public class Block {
/**
* Removes block from blockchain undoing transactions and adding them to unconfirmed pile.
- *
+ *
* @throws DataException
*/
public void orphan() throws DataException {
@@ -1879,7 +1894,7 @@ public class Block {
SelfSponsorshipAlgoV3Block.orphanAccountPenalties(this);
}
}
-
+
// Account levels and block rewards are only processed/orphaned on block reward distribution blocks
if (this.isRewardDistributionBlock()) {
// Block rewards, including transaction fees, removed after transactions undone
@@ -2213,6 +2228,7 @@ public class Block {
List
* Hence uses a repository savepoint during execution.
- *
+ *
* @return ValidationResult.OK if block is valid, or some other ValidationResult otherwise.
* @throws DataException
*/
@@ -1386,7 +1401,7 @@ public class Block {
*
* This is so we have locally-generated AT states for comparison.
- *
+ *
* @return OK, or some AT-related validation result
* @throws DataException
*/
@@ -1462,11 +1477,11 @@ public class Block {
* Note: this method does not store new AT state data into repository - that is handled by process().
*