diff --git a/pom.xml b/pom.xml index 3f34011cc..c662c03dc 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 1.4.2 3.8.0 1.12.0 - 2.16.1 + 2.17.0 1.27.1 3.17.0 1.2.2 diff --git a/src/main/java/org/qortal/account/Account.java b/src/main/java/org/qortal/account/Account.java index 274739d07..8d79e3c87 100644 --- a/src/main/java/org/qortal/account/Account.java +++ b/src/main/java/org/qortal/account/Account.java @@ -9,6 +9,7 @@ import org.qortal.data.account.RewardShareData; import org.qortal.data.naming.NameData; import org.qortal.repository.DataException; +import org.qortal.repository.GroupRepository; import org.qortal.repository.NameRepository; import org.qortal.repository.Repository; import org.qortal.settings.Settings; @@ -197,40 +198,65 @@ public boolean isFounder() throws DataException { /** Returns whether account can be considered a "minting account". *

- * To be considered a "minting account", the account needs to pass at least one of these tests:
+ * To be considered a "minting account", the account needs to pass all of these tests:
*

- * + * * @return true if account can be considered "minting account" * @throws DataException */ public boolean canMint() throws DataException { AccountData accountData = this.repository.getAccountRepository().getAccount(this.address); NameRepository nameRepository = this.repository.getNameRepository(); + GroupRepository groupRepository = this.repository.getGroupRepository(); int blockchainHeight = this.repository.getBlockRepository().getBlockchainHeight(); int nameCheckHeight = BlockChain.getInstance().getOnlyMintWithNameHeight(); int levelToMint = BlockChain.getInstance().getMinAccountLevelToMint(); int level = accountData.getLevel(); + int groupIdToMint = BlockChain.getInstance().getMintingGroupId(); + int groupCheckHeight = BlockChain.getInstance().getGroupMemberCheckHeight(); String myAddress = accountData.getAddress(); List myName = nameRepository.getNamesByOwner(myAddress); + boolean isMember = groupRepository.memberExists(groupIdToMint, myAddress); if (accountData == null) return false; - + + // Can only mint if level is at least minAccountLevelToMint< from blockchain config if (blockchainHeight < nameCheckHeight && level >= levelToMint) return true; - + // Can only mint if have registered a name - if (blockchainHeight >= nameCheckHeight && level >= levelToMint && !myName.isEmpty()) + if (blockchainHeight >= nameCheckHeight && blockchainHeight < groupCheckHeight && level >= levelToMint && !myName.isEmpty()) return true; - - // Founders can always mint, unless they have a penalty - if (Account.isFounder(accountData.getFlags()) && accountData.getBlocksMintedPenalty() == 0) + + // Can only mint if have registered a name and is member of minter group id + if (blockchainHeight >= groupCheckHeight && level >= levelToMint && !myName.isEmpty() && isMember) + return true; + + // Founders needs to pass same tests like minters + if (blockchainHeight < nameCheckHeight && + Account.isFounder(accountData.getFlags()) && + accountData.getBlocksMintedPenalty() == 0) + return true; + + if (blockchainHeight >= nameCheckHeight && + blockchainHeight < groupCheckHeight && + Account.isFounder(accountData.getFlags()) && + accountData.getBlocksMintedPenalty() == 0 && + !myName.isEmpty()) + return true; + + if (blockchainHeight >= groupCheckHeight && + Account.isFounder(accountData.getFlags()) && + accountData.getBlocksMintedPenalty() == 0 && + !myName.isEmpty() && + isMember) return true; return false; diff --git a/src/main/java/org/qortal/block/BlockChain.java b/src/main/java/org/qortal/block/BlockChain.java index 94657ed96..451d7c98a 100644 --- a/src/main/java/org/qortal/block/BlockChain.java +++ b/src/main/java/org/qortal/block/BlockChain.java @@ -83,7 +83,9 @@ public enum FeatureTrigger { enableTransferPrivsTimestamp, cancelSellNameValidationTimestamp, disableRewardshareHeight, - onlyMintWithNameHeight + enableRewardshareHeight, + onlyMintWithNameHeight, + groupMemberCheckHeight } // Custom transaction fees @@ -203,6 +205,7 @@ public static class BlockTimingByHeight { private int minAccountLevelToRewardShare; private int maxRewardSharesPerFounderMintingAccount; private int founderEffectiveMintingLevel; + private int mintingGroupId; /** Minimum time to retain online account signatures (ms) for block validity checks. */ private long onlineAccountSignaturesMinLifetime; @@ -526,6 +529,10 @@ public long getOnlineAccountSignaturesMaxLifetime() { return this.onlineAccountSignaturesMaxLifetime; } + public int getMintingGroupId() { + return this.mintingGroupId; + } + public CiyamAtSettings getCiyamAtSettings() { return this.ciyamAtSettings; } @@ -620,10 +627,18 @@ public int getDisableRewardshareHeight() { return this.featureTriggers.get(FeatureTrigger.disableRewardshareHeight.name()).intValue(); } + public int getEnableRewardshareHeight() { + return this.featureTriggers.get(FeatureTrigger.enableRewardshareHeight.name()).intValue(); + } + public int getOnlyMintWithNameHeight() { return this.featureTriggers.get(FeatureTrigger.onlyMintWithNameHeight.name()).intValue(); } + public int getGroupMemberCheckHeight() { + return this.featureTriggers.get(FeatureTrigger.groupMemberCheckHeight.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/transaction/RewardShareTransaction.java b/src/main/java/org/qortal/transaction/RewardShareTransaction.java index e9abcb71b..50eead310 100644 --- a/src/main/java/org/qortal/transaction/RewardShareTransaction.java +++ b/src/main/java/org/qortal/transaction/RewardShareTransaction.java @@ -99,10 +99,11 @@ public ValidationResult isFeeValid() throws DataException { @Override public ValidationResult isValid() throws DataException { final int disableRs = BlockChain.getInstance().getDisableRewardshareHeight(); + final int enableRs = BlockChain.getInstance().getEnableRewardshareHeight(); int blockchainHeight = this.repository.getBlockRepository().getBlockchainHeight(); // Check if reward share is disabled. - if (blockchainHeight >= disableRs) + if (blockchainHeight >= disableRs && blockchainHeight < enableRs) return ValidationResult.GENERAL_TEMPORARY_DISABLED; // Check reward share given to recipient. Negative is potentially OK to end a current reward-share. Zero also fine. diff --git a/src/main/resources/blockchain.json b/src/main/resources/blockchain.json index 0e2b0a8f0..85de477d7 100644 --- a/src/main/resources/blockchain.json +++ b/src/main/resources/blockchain.json @@ -37,6 +37,7 @@ "blockRewardBatchStartHeight": 1508000, "blockRewardBatchSize": 1000, "blockRewardBatchAccountsBlockCount": 25, + "mintingGroupId": 99999, "rewardsByHeight": [ { "height": 1, "reward": 5.00 }, { "height": 259201, "reward": 4.75 }, @@ -105,8 +106,10 @@ "disableTransferPrivsTimestamp": 1706745000000, "enableTransferPrivsTimestamp": 1709251200000, "cancelSellNameValidationTimestamp": 1676986362069, - "disableRewardshareHeight": 9999990, - "onlyMintWithNameHeight": 9999900 + "disableRewardshareHeight": 9999800, + "enableRewardshareHeight": 9999850, + "onlyMintWithNameHeight": 9999900, + "groupMemberCheckHeight": 9999950 }, "checkpoints": [ { "height": 1136300, "signature": "3BbwawEF2uN8Ni5ofpJXkukoU8ctAPxYoFB7whq9pKfBnjfZcpfEJT4R95NvBDoTP8WDyWvsUvbfHbcr9qSZuYpSKZjUQTvdFf6eqznHGEwhZApWfvXu6zjGCxYCp65F4jsVYYJjkzbjmkCg5WAwN5voudngA23kMK6PpTNygapCzXt" } diff --git a/testnet/testchain.json b/testnet/testchain.json index 98c67c341..06f5df122 100644 --- a/testnet/testchain.json +++ b/testnet/testchain.json @@ -33,6 +33,7 @@ "blockRewardBatchStartHeight": 2000000, "blockRewardBatchSize": 1000, "blockRewardBatchAccountsBlockCount": 25, + "mintingGroupId": 2, "rewardsByHeight": [ { "height": 1, "reward": 5.00 }, { "height": 259201, "reward": 4.75 }, @@ -103,7 +104,9 @@ "enableTransferPrivsTimestamp": 9999999999999, "cancelSellNameValidationTimestamp": 9999999999999, "disableRewardshareHeight": 8450, - "onlyMintWithNameHeight": 8500 + "enableRewardshareHeight": 11400, + "onlyMintWithNameHeight": 8500, + "groupMemberCheckHeight": 11200 }, "genesisInfo": { "version": 4,