diff --git a/pom.xml b/pom.xml index 18269bcb..8ef3f7f5 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ 33.3.1-jre 2.2 1.2.1 - 2.5.1 + 2.7.4 76.1 4.12 4.0.1 diff --git a/src/main/java/org/qortal/account/Account.java b/src/main/java/org/qortal/account/Account.java index 2cc031fe..1aaceffb 100644 --- a/src/main/java/org/qortal/account/Account.java +++ b/src/main/java/org/qortal/account/Account.java @@ -198,11 +198,11 @@ public class Account { /** Returns whether account can be considered a "minting account". *

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

* * @return true if account can be considered "minting account" @@ -212,64 +212,61 @@ public class Account { AccountData accountData = this.repository.getAccountRepository().getAccount(this.address); NameRepository nameRepository = this.repository.getNameRepository(); GroupRepository groupRepository = this.repository.getGroupRepository(); + String myAddress = accountData.getAddress(); 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 nameCheckHeight = BlockChain.getInstance().getOnlyMintWithNameHeight(); int groupCheckHeight = BlockChain.getInstance().getGroupMemberCheckHeight(); int removeNameCheckHeight = BlockChain.getInstance().getRemoveOnlyMintWithNameHeight(); - String myAddress = accountData.getAddress(); - List myName = nameRepository.getNamesByOwner(myAddress); - boolean isMember = groupRepository.memberExists(groupIdToMint, myAddress); + // Can only mint if: + // Account's level is at least minAccountLevelToMint from blockchain config + if (blockchainHeight < nameCheckHeight) { + if (Account.isFounder(accountData.getFlags())) { + return accountData.getBlocksMintedPenalty() == 0; + } else { + return level >= levelToMint; + } + } - if (accountData == null) - return false; + // Can only mint on onlyMintWithNameHeight from blockchain config if: + // Account's level is at least minAccountLevelToMint from blockchain config + // Account's address has registered a name + if (blockchainHeight >= nameCheckHeight && blockchainHeight < groupCheckHeight) { + List myName = nameRepository.getNamesByOwner(myAddress); + if (Account.isFounder(accountData.getFlags())) { + return accountData.getBlocksMintedPenalty() == 0 && !myName.isEmpty(); + } else { + return level >= levelToMint && !myName.isEmpty(); + } + } - // Can only mint if level is at least minAccountLevelToMint< from blockchain config - if (blockchainHeight < nameCheckHeight && level >= levelToMint) - return true; + // Can only mint on groupMemberCheckHeight from blockchain config if: + // Account's level is at least minAccountLevelToMint from blockchain config + // Account's address has registered a name + // Account's address is a member of the minter group + if (blockchainHeight >= groupCheckHeight && blockchainHeight < removeNameCheckHeight) { + List myName = nameRepository.getNamesByOwner(myAddress); + if (Account.isFounder(accountData.getFlags())) { + return accountData.getBlocksMintedPenalty() == 0 && !myName.isEmpty() && groupRepository.memberExists(groupIdToMint, myAddress); + } else { + return level >= levelToMint && !myName.isEmpty() && groupRepository.memberExists(groupIdToMint, myAddress); + } + } - // Can only mint if have registered a name - if (blockchainHeight >= nameCheckHeight && blockchainHeight < groupCheckHeight && level >= levelToMint && !myName.isEmpty()) - return true; - - // Can only mint if have registered a name and is member of minter group id - if (blockchainHeight >= groupCheckHeight && blockchainHeight < removeNameCheckHeight && level >= levelToMint && !myName.isEmpty() && isMember) - return true; - - // Can only mint if is member of minter group id - if (blockchainHeight >= removeNameCheckHeight && level >= levelToMint && 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 && - blockchainHeight < removeNameCheckHeight && - Account.isFounder(accountData.getFlags()) && - accountData.getBlocksMintedPenalty() == 0 && - !myName.isEmpty() && - isMember) - return true; - - if (blockchainHeight >= removeNameCheckHeight && - Account.isFounder(accountData.getFlags()) && - accountData.getBlocksMintedPenalty() == 0 && - isMember) - return true; + // Can only mint on removeOnlyMintWithNameHeight from blockchain config if: + // Account's level is at least minAccountLevelToMint from blockchain config + // 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); + } else { + return level >= levelToMint && groupRepository.memberExists(groupIdToMint, myAddress); + } + } return false; } @@ -284,7 +281,6 @@ public class Account { return this.repository.getAccountRepository().getBlocksMintedPenaltyCount(this.address); } - /** Returns whether account can build reward-shares. *

* To be able to create reward-shares, the account needs to pass at least one of these tests:
@@ -298,6 +294,7 @@ public class Account { */ public boolean canRewardShare() throws DataException { AccountData accountData = this.repository.getAccountRepository().getAccount(this.address); + if (accountData == null) return false; @@ -367,6 +364,7 @@ public class Account { Account rewardShareMinter = new Account(repository, rewardShareData.getMinter()); return rewardShareMinter.getEffectiveMintingLevel(); } + /** * Returns 'effective' minting level, with a fix for the zero level. *

diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java index 54af22e9..0027e13a 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -454,40 +454,41 @@ public class HSQLDBDatabaseUpdates { case 12: // Groups - stmt.execute("CREATE TABLE Groups (group_id GroupID, owner QortalAddress NOT NULL, group_name GroupName NOT NULL, " + // NOTE: We need to set Groups to `Groups` here to avoid SQL Standard Keywords in HSQLDB v2.7.4 + stmt.execute("CREATE TABLE `Groups` (group_id GroupID, owner QortalAddress NOT NULL, group_name GroupName NOT NULL, " + "created_when EpochMillis NOT NULL, updated_when EpochMillis, is_open BOOLEAN NOT NULL, " + "approval_threshold TINYINT NOT NULL, min_block_delay INTEGER NOT NULL, max_block_delay INTEGER NOT NULL, " + "reference Signature, creation_group_id GroupID, reduced_group_name GroupName NOT NULL, " + "description GenericDescription NOT NULL, PRIMARY KEY (group_id))"); // For finding groups by name - stmt.execute("CREATE INDEX GroupNameIndex on Groups (group_name)"); + stmt.execute("CREATE INDEX GroupNameIndex on `Groups` (group_name)"); // For finding groups by reduced name - stmt.execute("CREATE INDEX GroupReducedNameIndex on Groups (reduced_group_name)"); + stmt.execute("CREATE INDEX GroupReducedNameIndex on `Groups` (reduced_group_name)"); // For finding groups by owner - stmt.execute("CREATE INDEX GroupOwnerIndex ON Groups (owner)"); + stmt.execute("CREATE INDEX GroupOwnerIndex ON `Groups` (owner)"); // We need a corresponding trigger to make sure new group_id values are assigned sequentially starting from 1 - stmt.execute("CREATE TRIGGER Group_ID_Trigger BEFORE INSERT ON Groups " + stmt.execute("CREATE TRIGGER Group_ID_Trigger BEFORE INSERT ON `Groups` " + "REFERENCING NEW ROW AS new_row FOR EACH ROW WHEN (new_row.group_id IS NULL) " - + "SET new_row.group_id = (SELECT IFNULL(MAX(group_id) + 1, 1) FROM Groups)"); + + "SET new_row.group_id = (SELECT IFNULL(MAX(group_id) + 1, 1) FROM `Groups`)"); // Admins stmt.execute("CREATE TABLE GroupAdmins (group_id GroupID, admin QortalAddress, reference Signature NOT NULL, " - + "PRIMARY KEY (group_id, admin), FOREIGN KEY (group_id) REFERENCES Groups (group_id) ON DELETE CASCADE)"); + + "PRIMARY KEY (group_id, admin), FOREIGN KEY (group_id) REFERENCES `Groups` (group_id) ON DELETE CASCADE)"); // For finding groups by admin address stmt.execute("CREATE INDEX GroupAdminIndex ON GroupAdmins (admin)"); // Members stmt.execute("CREATE TABLE GroupMembers (group_id GroupID, address QortalAddress, " + "joined_when EpochMillis NOT NULL, reference Signature NOT NULL, " - + "PRIMARY KEY (group_id, address), FOREIGN KEY (group_id) REFERENCES Groups (group_id) ON DELETE CASCADE)"); + + "PRIMARY KEY (group_id, address), FOREIGN KEY (group_id) REFERENCES `Groups` (group_id) ON DELETE CASCADE)"); // For finding groups by member address stmt.execute("CREATE INDEX GroupMemberIndex ON GroupMembers (address)"); // Invites stmt.execute("CREATE TABLE GroupInvites (group_id GroupID, inviter QortalAddress, invitee QortalAddress, " + "expires_when EpochMillis, reference Signature, " - + "PRIMARY KEY (group_id, invitee), FOREIGN KEY (group_id) REFERENCES Groups (group_id) ON DELETE CASCADE)"); + + "PRIMARY KEY (group_id, invitee), FOREIGN KEY (group_id) REFERENCES `Groups` (group_id) ON DELETE CASCADE)"); // For finding invites sent by inviter stmt.execute("CREATE INDEX GroupInviteInviterIndex ON GroupInvites (inviter)"); // For finding invites by group @@ -503,7 +504,7 @@ public class HSQLDBDatabaseUpdates { // NULL expires_when means does not expire! stmt.execute("CREATE TABLE GroupBans (group_id GroupID, offender QortalAddress, admin QortalAddress NOT NULL, " + "banned_when EpochMillis NOT NULL, reason GenericDescription NOT NULL, expires_when EpochMillis, reference Signature NOT NULL, " - + "PRIMARY KEY (group_id, offender), FOREIGN KEY (group_id) REFERENCES Groups (group_id) ON DELETE CASCADE)"); + + "PRIMARY KEY (group_id, offender), FOREIGN KEY (group_id) REFERENCES `Groups` (group_id) ON DELETE CASCADE)"); // For expiry maintenance stmt.execute("CREATE INDEX GroupBanExpiryIndex ON GroupBans (expires_when)"); break;