myName = nameRepository.getNamesByOwner(myAddress);
if (Account.isFounder(accountData.getFlags())) {
- return accountData.getBlocksMintedPenalty() == 0 && !myName.isEmpty() && groupRepository.memberExists(groupIdToMint, myAddress);
+ return accountData.getBlocksMintedPenalty() == 0 && !myName.isEmpty() && (isGroupValidated || groupRepository.memberExists(groupIdToMint, myAddress));
} else {
- return level >= levelToMint && !myName.isEmpty() && groupRepository.memberExists(groupIdToMint, myAddress);
+ return level >= levelToMint && !myName.isEmpty() && (isGroupValidated || groupRepository.memberExists(groupIdToMint, myAddress));
}
}
@@ -262,9 +263,9 @@ public class Account {
// Account's address is a member of the minter group
if (blockchainHeight >= removeNameCheckHeight) {
if (Account.isFounder(accountData.getFlags())) {
- return accountData.getBlocksMintedPenalty() == 0 && groupRepository.memberExists(groupIdToMint, myAddress);
+ return accountData.getBlocksMintedPenalty() == 0 && (isGroupValidated || groupRepository.memberExists(groupIdToMint, myAddress));
} else {
- return level >= levelToMint && groupRepository.memberExists(groupIdToMint, myAddress);
+ return level >= levelToMint && (isGroupValidated || groupRepository.memberExists(groupIdToMint, myAddress));
}
}
diff --git a/src/main/java/org/qortal/api/restricted/resource/AdminResource.java b/src/main/java/org/qortal/api/restricted/resource/AdminResource.java
index 9a61a21b..279485bc 100644
--- a/src/main/java/org/qortal/api/restricted/resource/AdminResource.java
+++ b/src/main/java/org/qortal/api/restricted/resource/AdminResource.java
@@ -459,7 +459,7 @@ public class AdminResource {
// Qortal: check reward-share's minting account is still allowed to mint
Account rewardShareMintingAccount = new Account(repository, rewardShareData.getMinter());
- if (!rewardShareMintingAccount.canMint())
+ if (!rewardShareMintingAccount.canMint(false))
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.CANNOT_MINT);
MintingAccountData mintingAccountData = new MintingAccountData(mintingAccount.getPrivateKey(), mintingAccount.getPublicKey());
diff --git a/src/main/java/org/qortal/block/Block.java b/src/main/java/org/qortal/block/Block.java
index eba55069..918a20ae 100644
--- a/src/main/java/org/qortal/block/Block.java
+++ b/src/main/java/org/qortal/block/Block.java
@@ -25,10 +25,7 @@ import org.qortal.data.block.BlockSummaryData;
import org.qortal.data.block.BlockTransactionData;
import org.qortal.data.network.OnlineAccountData;
import org.qortal.data.transaction.TransactionData;
-import org.qortal.repository.ATRepository;
-import org.qortal.repository.DataException;
-import org.qortal.repository.Repository;
-import org.qortal.repository.TransactionRepository;
+import org.qortal.repository.*;
import org.qortal.settings.Settings;
import org.qortal.transaction.AtTransaction;
import org.qortal.transaction.Transaction;
@@ -144,9 +141,12 @@ public class Block {
private final Account mintingAccount;
private final AccountData mintingAccountData;
private final boolean isMinterFounder;
+ private final boolean isMinterMember;
private final Account recipientAccount;
private final AccountData recipientAccountData;
+
+ final BlockChain blockChain = BlockChain.getInstance();
ExpandedAccount(Repository repository, RewardShareData rewardShareData) throws DataException {
this.rewardShareData = rewardShareData;
@@ -157,6 +157,7 @@ public class Block {
this.isMinterFounder = Account.isFounder(mintingAccountData.getFlags());
this.isRecipientAlsoMinter = this.rewardShareData.getRecipient().equals(this.mintingAccount.getAddress());
+ this.isMinterMember = repository.getGroupRepository().memberExists(BlockChain.getInstance().getMintingGroupId(), this.mintingAccount.getAddress());
if (this.isRecipientAlsoMinter) {
// Self-share: minter is also recipient
@@ -181,7 +182,7 @@ public class Block {
*
* 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 getExpandedAccounts() throws DataException {
@@ -715,8 +720,18 @@ public class Block {
List expandedAccounts = new ArrayList<>();
- for (RewardShareData rewardShare : this.cachedOnlineRewardShares)
- expandedAccounts.add(new ExpandedAccount(repository, rewardShare));
+ for (RewardShareData rewardShare : this.cachedOnlineRewardShares) {
+ 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));
+ }
+ }
+ }
+
this.cachedExpandedAccounts = expandedAccounts;
@@ -727,7 +742,7 @@ public class Block {
/**
* Load parent block's data from repository via this block's reference.
- *
+ *
* @return parent's BlockData, or null if no parent found
* @throws DataException
*/
@@ -741,7 +756,7 @@ public class Block {
/**
* Load child block's data from repository via this block's signature.
- *
+ *
* @return child's BlockData, or null if no parent found
* @throws DataException
*/
@@ -761,7 +776,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
* @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.
* 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 {
*
* NOTE: will execute ATs locally if not already done.
* 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().
*
* 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.
@@ -1518,7 +1533,7 @@ public class Block {
return false;
Account mintingAccount = new PublicKeyAccount(this.repository, rewardShareData.getMinterPublicKey());
- return mintingAccount.canMint();
+ return mintingAccount.canMint(false);
}
/**
@@ -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 accountBalanceDeltas = balanceChanges.entrySet().stream()
.map(entry -> new AccountBalanceData(entry.getKey(), Asset.QORT, entry.getValue()))
.collect(Collectors.toList());
+ LOGGER.trace("Account Balance Deltas: {}", accountBalanceDeltas);
this.repository.getAccountRepository().modifyAssetBalances(accountBalanceDeltas);
}
@@ -2225,30 +2241,30 @@ public class Block {
/*
* Distribution rules:
- *
+ *
* Distribution is based on the minting account of 'online' reward-shares.
- *
+ *
* If ANY founders are online, then they receive the leftover non-distributed reward.
* If NO founders are online, then account-level-based rewards are scaled up so 100% of reward is allocated.
- *
+ *
* If ANY non-maxxed legacy QORA holders exist then they are always allocated their fixed share (e.g. 20%).
- *
+ *
* There has to be either at least one 'online' account for blocks to be minted
* so there is always either one account-level-based or founder reward candidate.
- *
+ *
* Examples:
- *
+ *
* With at least one founder online:
* Level 1/2 accounts: 5%
* Legacy QORA holders: 20%
* Founders: ~75%
- *
+ *
* No online founders:
* Level 1/2 accounts: 5%
* Level 5/6 accounts: 15%
* Legacy QORA holders: 20%
* Total: 40%
- *
+ *
* After scaling account-level-based shares to fill 100%:
* Level 1/2 accounts: 20%
* Level 5/6 accounts: 60%
diff --git a/src/main/java/org/qortal/block/BlockChain.java b/src/main/java/org/qortal/block/BlockChain.java
index 34097f0f..3e98d4a0 100644
--- a/src/main/java/org/qortal/block/BlockChain.java
+++ b/src/main/java/org/qortal/block/BlockChain.java
@@ -87,7 +87,8 @@ public class BlockChain {
enableRewardshareHeight,
onlyMintWithNameHeight,
removeOnlyMintWithNameHeight,
- groupMemberCheckHeight
+ groupMemberCheckHeight,
+ fixBatchRewardHeight
}
// Custom transaction fees
@@ -657,6 +658,10 @@ public class BlockChain {
return this.featureTriggers.get(FeatureTrigger.groupMemberCheckHeight.name()).intValue();
}
+ public int getFixBatchRewardHeight() {
+ return this.featureTriggers.get(FeatureTrigger.fixBatchRewardHeight.name()).intValue();
+ }
+
// More complex getters for aspects that change by height or timestamp
public long getRewardAtHeight(int ourHeight) {
diff --git a/src/main/java/org/qortal/controller/BlockMinter.java b/src/main/java/org/qortal/controller/BlockMinter.java
index 7ea2242c..a1fb9769 100644
--- a/src/main/java/org/qortal/controller/BlockMinter.java
+++ b/src/main/java/org/qortal/controller/BlockMinter.java
@@ -148,7 +148,7 @@ public class BlockMinter extends Thread {
}
Account mintingAccount = new Account(repository, rewardShareData.getMinter());
- if (!mintingAccount.canMint()) {
+ if (!mintingAccount.canMint(true)) {
// Minting-account component of reward-share can no longer mint - disregard
madi.remove();
continue;
diff --git a/src/main/java/org/qortal/controller/OnlineAccountsManager.java b/src/main/java/org/qortal/controller/OnlineAccountsManager.java
index 5572dee1..332bf867 100644
--- a/src/main/java/org/qortal/controller/OnlineAccountsManager.java
+++ b/src/main/java/org/qortal/controller/OnlineAccountsManager.java
@@ -13,6 +13,7 @@ import org.qortal.crypto.MemoryPoW;
import org.qortal.crypto.Qortal25519Extras;
import org.qortal.data.account.MintingAccountData;
import org.qortal.data.account.RewardShareData;
+import org.qortal.data.group.GroupMemberData;
import org.qortal.data.network.OnlineAccountData;
import org.qortal.network.Network;
import org.qortal.network.Peer;
@@ -224,6 +225,12 @@ public class OnlineAccountsManager {
Set onlineAccountsToAdd = new HashSet<>();
Set onlineAccountsToRemove = new HashSet<>();
try (final Repository repository = RepositoryManager.getRepository()) {
+ List mintingGroupMemberAddresses
+ = repository.getGroupRepository()
+ .getGroupMembers(BlockChain.getInstance().getMintingGroupId()).stream()
+ .map(GroupMemberData::getMember)
+ .collect(Collectors.toList());
+
for (OnlineAccountData onlineAccountData : this.onlineAccountsImportQueue) {
if (isStopping)
return;
@@ -236,7 +243,7 @@ public class OnlineAccountsManager {
continue;
}
- boolean isValid = this.isValidCurrentAccount(repository, onlineAccountData);
+ boolean isValid = this.isValidCurrentAccount(repository, mintingGroupMemberAddresses, onlineAccountData);
if (isValid)
onlineAccountsToAdd.add(onlineAccountData);
@@ -315,7 +322,7 @@ public class OnlineAccountsManager {
return inplaceArray;
}
- private static boolean isValidCurrentAccount(Repository repository, OnlineAccountData onlineAccountData) throws DataException {
+ private static boolean isValidCurrentAccount(Repository repository, List mintingGroupMemberAddresses, OnlineAccountData onlineAccountData) throws DataException {
final Long now = NTP.getTime();
if (now == null)
return false;
@@ -350,9 +357,14 @@ public class OnlineAccountsManager {
LOGGER.trace(() -> String.format("Rejecting unknown online reward-share public key %s", Base58.encode(rewardSharePublicKey)));
return false;
}
+ // reject account address that are not in the MINTER Group
+ else if( !mintingGroupMemberAddresses.contains(rewardShareData.getMinter())) {
+ LOGGER.trace(() -> String.format("Rejecting online reward-share that is not in MINTER Group, account %s", rewardShareData.getMinter()));
+ return false;
+ }
Account mintingAccount = new Account(repository, rewardShareData.getMinter());
- if (!mintingAccount.canMint()) {
+ if (!mintingAccount.canMint(true)) { // group validation is a few lines above
// Minting-account component of reward-share can no longer mint - disregard
LOGGER.trace(() -> String.format("Rejecting online reward-share with non-minting account %s", mintingAccount.getAddress()));
return false;
@@ -539,7 +551,7 @@ public class OnlineAccountsManager {
}
Account mintingAccount = new Account(repository, rewardShareData.getMinter());
- if (!mintingAccount.canMint()) {
+ if (!mintingAccount.canMint(true)) {
// Minting-account component of reward-share can no longer mint - disregard
iterator.remove();
continue;
diff --git a/src/main/java/org/qortal/network/task/PeerConnectTask.java b/src/main/java/org/qortal/network/task/PeerConnectTask.java
index 7eec4e6b..3ae1b640 100644
--- a/src/main/java/org/qortal/network/task/PeerConnectTask.java
+++ b/src/main/java/org/qortal/network/task/PeerConnectTask.java
@@ -4,10 +4,15 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.qortal.network.Network;
import org.qortal.network.Peer;
+import org.qortal.utils.DaemonThreadFactory;
import org.qortal.utils.ExecuteProduceConsume.Task;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
public class PeerConnectTask implements Task {
private static final Logger LOGGER = LogManager.getLogger(PeerConnectTask.class);
+ private static final ExecutorService connectionExecutor = Executors.newCachedThreadPool(new DaemonThreadFactory(8));
private final Peer peer;
private final String name;
@@ -24,6 +29,24 @@ public class PeerConnectTask implements Task {
@Override
public void perform() throws InterruptedException {
- Network.getInstance().connectPeer(peer);
+ // Submit connection task to a dedicated thread pool for non-blocking I/O
+ connectionExecutor.submit(() -> {
+ try {
+ connectPeerAsync(peer);
+ } catch (InterruptedException e) {
+ LOGGER.error("Connection attempt interrupted for peer {}", peer, e);
+ Thread.currentThread().interrupt(); // Reset interrupt flag
+ }
+ });
+ }
+
+ private void connectPeerAsync(Peer peer) throws InterruptedException {
+ // Perform peer connection in a separate thread to avoid blocking main task execution
+ try {
+ Network.getInstance().connectPeer(peer);
+ LOGGER.trace("Successfully connected to peer {}", peer);
+ } catch (Exception e) {
+ LOGGER.error("Error connecting to peer {}", peer, e);
+ }
}
}
diff --git a/src/main/java/org/qortal/settings/Settings.java b/src/main/java/org/qortal/settings/Settings.java
index 937d352a..305021d5 100644
--- a/src/main/java/org/qortal/settings/Settings.java
+++ b/src/main/java/org/qortal/settings/Settings.java
@@ -213,7 +213,7 @@ public class Settings {
public long recoveryModeTimeout = 9999999999999L;
/** Minimum peer version number required in order to sync with them */
- private String minPeerVersion = "4.6.2";
+ private String minPeerVersion = "4.6.3";
/** Whether to allow connections with peers below minPeerVersion
* If true, we won't sync with them but they can still sync with us, and will show in the peers list
* If false, sync will be blocked both ways, and they will not appear in the peers list */
diff --git a/src/main/java/org/qortal/transaction/RewardShareTransaction.java b/src/main/java/org/qortal/transaction/RewardShareTransaction.java
index 50eead31..31734204 100644
--- a/src/main/java/org/qortal/transaction/RewardShareTransaction.java
+++ b/src/main/java/org/qortal/transaction/RewardShareTransaction.java
@@ -123,7 +123,7 @@ public class RewardShareTransaction extends Transaction {
final boolean isCancellingSharePercent = this.rewardShareTransactionData.getSharePercent() < 0;
// Creator themselves needs to be allowed to mint (unless cancelling)
- if (!isCancellingSharePercent && !creator.canMint())
+ if (!isCancellingSharePercent && !creator.canMint(false))
return ValidationResult.NOT_MINTING_ACCOUNT;
// Qortal: special rules in play depending whether recipient is also minter
diff --git a/src/main/resources/blockchain.json b/src/main/resources/blockchain.json
index 1dcd9e46..762a5708 100644
--- a/src/main/resources/blockchain.json
+++ b/src/main/resources/blockchain.json
@@ -112,7 +112,8 @@
"enableRewardshareHeight": 1905100,
"onlyMintWithNameHeight": 1900300,
"removeOnlyMintWithNameHeight": 1935500,
- "groupMemberCheckHeight": 1902700
+ "groupMemberCheckHeight": 1902700,
+ "fixBatchRewardHeight": 1945900
},
"checkpoints": [
{ "height": 1136300, "signature": "3BbwawEF2uN8Ni5ofpJXkukoU8ctAPxYoFB7whq9pKfBnjfZcpfEJT4R95NvBDoTP8WDyWvsUvbfHbcr9qSZuYpSKZjUQTvdFf6eqznHGEwhZApWfvXu6zjGCxYCp65F4jsVYYJjkzbjmkCg5WAwN5voudngA23kMK6PpTNygapCzXt" }
diff --git a/src/test/java/org/qortal/test/TransferPrivsTests.java b/src/test/java/org/qortal/test/TransferPrivsTests.java
index 86a0e743..ad1d2a2a 100644
--- a/src/test/java/org/qortal/test/TransferPrivsTests.java
+++ b/src/test/java/org/qortal/test/TransferPrivsTests.java
@@ -74,7 +74,7 @@ public class TransferPrivsTests extends Common {
public void testAliceIntoNewAccountTransferPrivs() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
TestAccount alice = Common.getTestAccount(repository, "alice");
- assertTrue(alice.canMint());
+ assertTrue(alice.canMint(false));
PrivateKeyAccount aliceMintingAccount = Common.getTestAccount(repository, "alice-reward-share");
@@ -86,8 +86,8 @@ public class TransferPrivsTests extends Common {
combineAccounts(repository, alice, randomAccount, aliceMintingAccount);
- assertFalse(alice.canMint());
- assertTrue(randomAccount.canMint());
+ assertFalse(alice.canMint(false));
+ assertTrue(randomAccount.canMint(false));
}
}
@@ -97,8 +97,8 @@ public class TransferPrivsTests extends Common {
TestAccount alice = Common.getTestAccount(repository, "alice");
TestAccount dilbert = Common.getTestAccount(repository, "dilbert");
- assertTrue(alice.canMint());
- assertTrue(dilbert.canMint());
+ assertTrue(alice.canMint(false));
+ assertTrue(dilbert.canMint(false));
// Dilbert has level, Alice does not so we need Alice to mint enough blocks to bump Dilbert's level post-combine
final int expectedPostCombineLevel = dilbert.getLevel() + 1;
@@ -118,11 +118,11 @@ public class TransferPrivsTests extends Common {
// Post-combine sender checks
checkSenderPostTransfer(postCombineAliceData);
- assertFalse(alice.canMint());
+ assertFalse(alice.canMint(false));
// Post-combine recipient checks
checkRecipientPostTransfer(preCombineAliceData, preCombineDilbertData, postCombineDilbertData, expectedPostCombineLevel);
- assertTrue(dilbert.canMint());
+ assertTrue(dilbert.canMint(false));
// Orphan previous block
BlockUtils.orphanLastBlock(repository);
@@ -130,12 +130,12 @@ public class TransferPrivsTests extends Common {
// Sender checks
AccountData orphanedAliceData = repository.getAccountRepository().getAccount(alice.getAddress());
checkAccountDataRestored("sender", preCombineAliceData, orphanedAliceData);
- assertTrue(alice.canMint());
+ assertTrue(alice.canMint(false));
// Recipient checks
AccountData orphanedDilbertData = repository.getAccountRepository().getAccount(dilbert.getAddress());
checkAccountDataRestored("recipient", preCombineDilbertData, orphanedDilbertData);
- assertTrue(dilbert.canMint());
+ assertTrue(dilbert.canMint(false));
}
}
@@ -145,8 +145,8 @@ public class TransferPrivsTests extends Common {
TestAccount alice = Common.getTestAccount(repository, "alice");
TestAccount dilbert = Common.getTestAccount(repository, "dilbert");
- assertTrue(dilbert.canMint());
- assertTrue(alice.canMint());
+ assertTrue(dilbert.canMint(false));
+ assertTrue(alice.canMint(false));
// Dilbert has level, Alice does not so we need Alice to mint enough blocks to surpass Dilbert's level post-combine
final int expectedPostCombineLevel = dilbert.getLevel() + 1;
@@ -166,11 +166,11 @@ public class TransferPrivsTests extends Common {
// Post-combine sender checks
checkSenderPostTransfer(postCombineDilbertData);
- assertFalse(dilbert.canMint());
+ assertFalse(dilbert.canMint(false));
// Post-combine recipient checks
checkRecipientPostTransfer(preCombineDilbertData, preCombineAliceData, postCombineAliceData, expectedPostCombineLevel);
- assertTrue(alice.canMint());
+ assertTrue(alice.canMint(false));
// Orphan previous block
BlockUtils.orphanLastBlock(repository);
@@ -178,12 +178,12 @@ public class TransferPrivsTests extends Common {
// Sender checks
AccountData orphanedDilbertData = repository.getAccountRepository().getAccount(dilbert.getAddress());
checkAccountDataRestored("sender", preCombineDilbertData, orphanedDilbertData);
- assertTrue(dilbert.canMint());
+ assertTrue(dilbert.canMint(false));
// Recipient checks
AccountData orphanedAliceData = repository.getAccountRepository().getAccount(alice.getAddress());
checkAccountDataRestored("recipient", preCombineAliceData, orphanedAliceData);
- assertTrue(alice.canMint());
+ assertTrue(alice.canMint(false));
}
}
@@ -202,8 +202,8 @@ public class TransferPrivsTests extends Common {
TestAccount chloe = Common.getTestAccount(repository, "chloe");
TestAccount dilbert = Common.getTestAccount(repository, "dilbert");
- assertTrue(dilbert.canMint());
- assertFalse(chloe.canMint());
+ assertTrue(dilbert.canMint(false));
+ assertFalse(chloe.canMint(false));
// COMBINE DILBERT INTO CHLOE
@@ -225,16 +225,16 @@ public class TransferPrivsTests extends Common {
// Post-combine sender checks
checkSenderPostTransfer(post1stCombineDilbertData);
- assertFalse(dilbert.canMint());
+ assertFalse(dilbert.canMint(false));
// Post-combine recipient checks
checkRecipientPostTransfer(pre1stCombineDilbertData, pre1stCombineChloeData, post1stCombineChloeData, expectedPost1stCombineLevel);
- assertTrue(chloe.canMint());
+ assertTrue(chloe.canMint(false));
// COMBINE ALICE INTO CHLOE
- assertTrue(alice.canMint());
- assertTrue(chloe.canMint());
+ assertTrue(alice.canMint(false));
+ assertTrue(chloe.canMint(false));
// Alice needs to mint enough blocks to surpass Chloe's level post-combine
final int expectedPost2ndCombineLevel = chloe.getLevel() + 1;
@@ -254,11 +254,11 @@ public class TransferPrivsTests extends Common {
// Post-combine sender checks
checkSenderPostTransfer(post2ndCombineAliceData);
- assertFalse(alice.canMint());
+ assertFalse(alice.canMint(false));
// Post-combine recipient checks
checkRecipientPostTransfer(pre2ndCombineAliceData, pre2ndCombineChloeData, post2ndCombineChloeData, expectedPost2ndCombineLevel);
- assertTrue(chloe.canMint());
+ assertTrue(chloe.canMint(false));
// Orphan 2nd combine
BlockUtils.orphanLastBlock(repository);
@@ -266,12 +266,12 @@ public class TransferPrivsTests extends Common {
// Sender checks
AccountData orphanedAliceData = repository.getAccountRepository().getAccount(alice.getAddress());
checkAccountDataRestored("sender", pre2ndCombineAliceData, orphanedAliceData);
- assertTrue(alice.canMint());
+ assertTrue(alice.canMint(false));
// Recipient checks
AccountData orphanedChloeData = repository.getAccountRepository().getAccount(chloe.getAddress());
checkAccountDataRestored("recipient", pre2ndCombineChloeData, orphanedChloeData);
- assertTrue(chloe.canMint());
+ assertTrue(chloe.canMint(false));
// Orphan 1nd combine
BlockUtils.orphanToBlock(repository, pre1stCombineBlockHeight);
@@ -279,7 +279,7 @@ public class TransferPrivsTests extends Common {
// Sender checks
AccountData orphanedDilbertData = repository.getAccountRepository().getAccount(dilbert.getAddress());
checkAccountDataRestored("sender", pre1stCombineDilbertData, orphanedDilbertData);
- assertTrue(dilbert.canMint());
+ assertTrue(dilbert.canMint(false));
// Recipient checks
orphanedChloeData = repository.getAccountRepository().getAccount(chloe.getAddress());
@@ -287,7 +287,7 @@ public class TransferPrivsTests extends Common {
// Chloe canMint() would return true here due to Alice-Chloe reward-share minting at top of method, so undo that minting by orphaning back to block 1
BlockUtils.orphanToBlock(repository, 1);
- assertFalse(chloe.canMint());
+ assertFalse(chloe.canMint(false));
}
}