diff --git a/src/main/java/org/qortal/data/account/AccountData.java b/src/main/java/org/qortal/data/account/AccountData.java
index 4d662f04..868d1bc1 100644
--- a/src/main/java/org/qortal/data/account/AccountData.java
+++ b/src/main/java/org/qortal/data/account/AccountData.java
@@ -18,6 +18,7 @@ public class AccountData {
protected int level;
protected int blocksMinted;
protected int blocksMintedAdjustment;
+ protected int blocksMintedPenalty;
// Constructors
@@ -25,7 +26,7 @@ public class AccountData {
protected AccountData() {
}
- public AccountData(String address, byte[] reference, byte[] publicKey, int defaultGroupId, int flags, int level, int blocksMinted, int blocksMintedAdjustment) {
+ public AccountData(String address, byte[] reference, byte[] publicKey, int defaultGroupId, int flags, int level, int blocksMinted, int blocksMintedAdjustment, int blocksMintedPenalty) {
this.address = address;
this.reference = reference;
this.publicKey = publicKey;
@@ -34,10 +35,11 @@ public class AccountData {
this.level = level;
this.blocksMinted = blocksMinted;
this.blocksMintedAdjustment = blocksMintedAdjustment;
+ this.blocksMintedPenalty = blocksMintedPenalty;
}
public AccountData(String address) {
- this(address, null, null, Group.NO_GROUP, 0, 0, 0, 0);
+ this(address, null, null, Group.NO_GROUP, 0, 0, 0, 0, 0);
}
// Getters/Setters
@@ -102,6 +104,14 @@ public class AccountData {
this.blocksMintedAdjustment = blocksMintedAdjustment;
}
+ public int getBlocksMintedPenalty() {
+ return this.blocksMintedPenalty;
+ }
+
+ public void setBlocksMintedPenalty(int blocksMintedPenalty) {
+ this.blocksMintedPenalty = blocksMintedPenalty;
+ }
+
// Comparison
@Override
diff --git a/src/main/java/org/qortal/network/message/AccountMessage.java b/src/main/java/org/qortal/network/message/AccountMessage.java
index d22ef879..453862b0 100644
--- a/src/main/java/org/qortal/network/message/AccountMessage.java
+++ b/src/main/java/org/qortal/network/message/AccountMessage.java
@@ -41,6 +41,8 @@ public class AccountMessage extends Message {
bytes.write(Ints.toByteArray(accountData.getBlocksMintedAdjustment()));
+ bytes.write(Ints.toByteArray(accountData.getBlocksMintedPenalty()));
+
} catch (IOException e) {
throw new AssertionError("IOException shouldn't occur with ByteArrayOutputStream");
}
@@ -80,7 +82,9 @@ public class AccountMessage extends Message {
int blocksMintedAdjustment = byteBuffer.getInt();
- AccountData accountData = new AccountData(address, reference, publicKey, defaultGroupId, flags, level, blocksMinted, blocksMintedAdjustment);
+ int blocksMintedPenalty = byteBuffer.getInt();
+
+ AccountData accountData = new AccountData(address, reference, publicKey, defaultGroupId, flags, level, blocksMinted, blocksMintedAdjustment, blocksMintedPenalty);
return new AccountMessage(id, accountData);
}
diff --git a/src/main/java/org/qortal/repository/AccountRepository.java b/src/main/java/org/qortal/repository/AccountRepository.java
index 281f34f1..1175337c 100644
--- a/src/main/java/org/qortal/repository/AccountRepository.java
+++ b/src/main/java/org/qortal/repository/AccountRepository.java
@@ -1,13 +1,9 @@
package org.qortal.repository;
import java.util.List;
+import java.util.Set;
-import org.qortal.data.account.AccountBalanceData;
-import org.qortal.data.account.AccountData;
-import org.qortal.data.account.EligibleQoraHolderData;
-import org.qortal.data.account.MintingAccountData;
-import org.qortal.data.account.QortFromQoraData;
-import org.qortal.data.account.RewardShareData;
+import org.qortal.data.account.*;
public interface AccountRepository {
@@ -19,6 +15,9 @@ public interface AccountRepository {
/** Returns accounts with any bit set in given mask. */
public List getFlaggedAccounts(int mask) throws DataException;
+ /** Returns accounts with a blockedMintedPenalty */
+ public List getPenaltyAccounts() throws DataException;
+
/** Returns account's last reference or null if not set or account not found. */
public byte[] getLastReference(String address) throws DataException;
@@ -100,6 +99,18 @@ public interface AccountRepository {
*/
public void modifyMintedBlockCounts(List addresses, int delta) throws DataException;
+ /** Returns account's block minted penalty count or null if account not found. */
+ public Integer getBlocksMintedPenaltyCount(String address) throws DataException;
+
+ /**
+ * Sets blocks minted penalties for given list of accounts.
+ * This replaces the existing values rather than modifying them by a delta.
+ *
+ * @param accountPenalties
+ * @throws DataException
+ */
+ public void updateBlocksMintedPenalties(Set accountPenalties) throws DataException;
+
/** Delete account from repository. */
public void delete(String address) throws DataException;
diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBAccountRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBAccountRepository.java
index 9fdb0a3f..cb188502 100644
--- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBAccountRepository.java
+++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBAccountRepository.java
@@ -6,15 +6,11 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import java.util.stream.Collectors;
import org.qortal.asset.Asset;
-import org.qortal.data.account.AccountBalanceData;
-import org.qortal.data.account.AccountData;
-import org.qortal.data.account.EligibleQoraHolderData;
-import org.qortal.data.account.MintingAccountData;
-import org.qortal.data.account.QortFromQoraData;
-import org.qortal.data.account.RewardShareData;
+import org.qortal.data.account.*;
import org.qortal.repository.AccountRepository;
import org.qortal.repository.DataException;
@@ -30,7 +26,7 @@ public class HSQLDBAccountRepository implements AccountRepository {
@Override
public AccountData getAccount(String address) throws DataException {
- String sql = "SELECT reference, public_key, default_group_id, flags, level, blocks_minted, blocks_minted_adjustment FROM Accounts WHERE account = ?";
+ String sql = "SELECT reference, public_key, default_group_id, flags, level, blocks_minted, blocks_minted_adjustment, blocks_minted_penalty FROM Accounts WHERE account = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, address)) {
if (resultSet == null)
@@ -43,8 +39,9 @@ public class HSQLDBAccountRepository implements AccountRepository {
int level = resultSet.getInt(5);
int blocksMinted = resultSet.getInt(6);
int blocksMintedAdjustment = resultSet.getInt(7);
+ int blocksMintedPenalty = resultSet.getInt(8);
- return new AccountData(address, reference, publicKey, defaultGroupId, flags, level, blocksMinted, blocksMintedAdjustment);
+ return new AccountData(address, reference, publicKey, defaultGroupId, flags, level, blocksMinted, blocksMintedAdjustment, blocksMintedPenalty);
} catch (SQLException e) {
throw new DataException("Unable to fetch account info from repository", e);
}
@@ -52,7 +49,7 @@ public class HSQLDBAccountRepository implements AccountRepository {
@Override
public List getFlaggedAccounts(int mask) throws DataException {
- String sql = "SELECT reference, public_key, default_group_id, flags, level, blocks_minted, blocks_minted_adjustment, account FROM Accounts WHERE BITAND(flags, ?) != 0";
+ String sql = "SELECT reference, public_key, default_group_id, flags, level, blocks_minted, blocks_minted_adjustment, blocks_minted_penalty, account FROM Accounts WHERE BITAND(flags, ?) != 0";
List accounts = new ArrayList<>();
@@ -68,9 +65,10 @@ public class HSQLDBAccountRepository implements AccountRepository {
int level = resultSet.getInt(5);
int blocksMinted = resultSet.getInt(6);
int blocksMintedAdjustment = resultSet.getInt(7);
- String address = resultSet.getString(8);
+ int blocksMintedPenalty = resultSet.getInt(8);
+ String address = resultSet.getString(9);
- accounts.add(new AccountData(address, reference, publicKey, defaultGroupId, flags, level, blocksMinted, blocksMintedAdjustment));
+ accounts.add(new AccountData(address, reference, publicKey, defaultGroupId, flags, level, blocksMinted, blocksMintedAdjustment, blocksMintedPenalty));
} while (resultSet.next());
return accounts;
@@ -79,6 +77,36 @@ public class HSQLDBAccountRepository implements AccountRepository {
}
}
+ @Override
+ public List getPenaltyAccounts() throws DataException {
+ String sql = "SELECT reference, public_key, default_group_id, flags, level, blocks_minted, blocks_minted_adjustment, blocks_minted_penalty, account FROM Accounts WHERE blocks_minted_penalty != 0";
+
+ List accounts = new ArrayList<>();
+
+ try (ResultSet resultSet = this.repository.checkedExecute(sql)) {
+ if (resultSet == null)
+ return accounts;
+
+ do {
+ byte[] reference = resultSet.getBytes(1);
+ byte[] publicKey = resultSet.getBytes(2);
+ int defaultGroupId = resultSet.getInt(3);
+ int flags = resultSet.getInt(4);
+ int level = resultSet.getInt(5);
+ int blocksMinted = resultSet.getInt(6);
+ int blocksMintedAdjustment = resultSet.getInt(7);
+ int blocksMintedPenalty = resultSet.getInt(8);
+ String address = resultSet.getString(9);
+
+ accounts.add(new AccountData(address, reference, publicKey, defaultGroupId, flags, level, blocksMinted, blocksMintedAdjustment, blocksMintedPenalty));
+ } while (resultSet.next());
+
+ return accounts;
+ } catch (SQLException e) {
+ throw new DataException("Unable to fetch penalty accounts from repository", e);
+ }
+ }
+
@Override
public byte[] getLastReference(String address) throws DataException {
String sql = "SELECT reference FROM Accounts WHERE account = ?";
@@ -298,6 +326,39 @@ public class HSQLDBAccountRepository implements AccountRepository {
}
}
+ @Override
+ public Integer getBlocksMintedPenaltyCount(String address) throws DataException {
+ String sql = "SELECT blocks_minted_penalty FROM Accounts WHERE account = ?";
+
+ try (ResultSet resultSet = this.repository.checkedExecute(sql, address)) {
+ if (resultSet == null)
+ return null;
+
+ return resultSet.getInt(1);
+ } catch (SQLException e) {
+ throw new DataException("Unable to fetch account's block minted penalty count from repository", e);
+ }
+ }
+ public void updateBlocksMintedPenalties(Set accountPenalties) throws DataException {
+ // Nothing to do?
+ if (accountPenalties == null || accountPenalties.isEmpty())
+ return;
+
+ // Map balance changes into SQL bind params, filtering out no-op changes
+ List