forked from Qortal/qortal
Reuse the work buffer when verifying online accounts from the OnlineAccountsManager import queue.
This is a hopeful fix for extra memory usage since mempow activated, due to adding a lot of load to the garbage collector. It only applies to accounts verified from the import queue; the optimization hasn't been applied to block processing. But verifying online accounts when processing blocks is rare and generally would only last a short amount of time.
This commit is contained in:
parent
30cd56165a
commit
b64c053531
@ -1072,7 +1072,7 @@ public class Block {
|
|||||||
|
|
||||||
// Validate the rest
|
// Validate the rest
|
||||||
for (OnlineAccountData onlineAccount : onlineAccounts)
|
for (OnlineAccountData onlineAccount : onlineAccounts)
|
||||||
if (!OnlineAccountsManager.getInstance().verifyMemoryPoW(onlineAccount))
|
if (!OnlineAccountsManager.getInstance().verifyMemoryPoW(onlineAccount, null))
|
||||||
return ValidationResult.ONLINE_ACCOUNT_NONCE_INCORRECT;
|
return ValidationResult.ONLINE_ACCOUNT_NONCE_INCORRECT;
|
||||||
|
|
||||||
// Cache the valid online accounts as they will likely be needed for the next block
|
// Cache the valid online accounts as they will likely be needed for the next block
|
||||||
|
@ -72,6 +72,11 @@ public class OnlineAccountsManager {
|
|||||||
public static final int POW_BUFFER_SIZE_TESTNET = 1 * 1024 * 1024; // bytes
|
public static final int POW_BUFFER_SIZE_TESTNET = 1 * 1024 * 1024; // bytes
|
||||||
public static final int POW_DIFFICULTY_TESTNET = 5; // leading zero bits
|
public static final int POW_DIFFICULTY_TESTNET = 5; // leading zero bits
|
||||||
|
|
||||||
|
// IMPORTANT: if we ever need to dynamically modify the buffer size using a feature trigger, the
|
||||||
|
// pre-allocated buffer below will NOT work, and we should instead use a dynamically allocated
|
||||||
|
// one for the transition period.
|
||||||
|
private static long[] POW_VERIFY_WORK_BUFFER = new long[getPoWBufferSize() / 8];
|
||||||
|
|
||||||
private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(4, new NamedThreadFactory("OnlineAccounts"));
|
private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(4, new NamedThreadFactory("OnlineAccounts"));
|
||||||
private volatile boolean isStopping = false;
|
private volatile boolean isStopping = false;
|
||||||
|
|
||||||
@ -339,7 +344,7 @@ public class OnlineAccountsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate mempow
|
// Validate mempow
|
||||||
if (!getInstance().verifyMemoryPoW(onlineAccountData)) {
|
if (!getInstance().verifyMemoryPoW(onlineAccountData, POW_VERIFY_WORK_BUFFER)) {
|
||||||
LOGGER.trace(() -> String.format("Rejecting online reward-share for account %s due to invalid PoW nonce", mintingAccount.getAddress()));
|
LOGGER.trace(() -> String.format("Rejecting online reward-share for account %s due to invalid PoW nonce", mintingAccount.getAddress()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -582,7 +587,7 @@ public class OnlineAccountsManager {
|
|||||||
OnlineAccountData ourOnlineAccountData = new OnlineAccountData(onlineAccountsTimestamp, signature, publicKey, nonce);
|
OnlineAccountData ourOnlineAccountData = new OnlineAccountData(onlineAccountsTimestamp, signature, publicKey, nonce);
|
||||||
|
|
||||||
// Make sure to verify before adding
|
// Make sure to verify before adding
|
||||||
if (verifyMemoryPoW(ourOnlineAccountData)) {
|
if (verifyMemoryPoW(ourOnlineAccountData, null)) {
|
||||||
ourOnlineAccounts.add(ourOnlineAccountData);
|
ourOnlineAccounts.add(ourOnlineAccountData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -637,7 +642,7 @@ public class OnlineAccountsManager {
|
|||||||
return nonce;
|
return nonce;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean verifyMemoryPoW(OnlineAccountData onlineAccountData) {
|
public boolean verifyMemoryPoW(OnlineAccountData onlineAccountData, long[] workBuffer) {
|
||||||
// Require a valid nonce value
|
// Require a valid nonce value
|
||||||
if (onlineAccountData.getNonce() == null || onlineAccountData.getNonce() < 0) {
|
if (onlineAccountData.getNonce() == null || onlineAccountData.getNonce() < 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -653,7 +658,7 @@ public class OnlineAccountsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify the nonce
|
// Verify the nonce
|
||||||
return MemoryPoW.verify2(mempowBytes, getPoWBufferSize(), getPoWDifficulty(), nonce);
|
return MemoryPoW.verify2(mempowBytes, workBuffer, getPoWBufferSize(), getPoWDifficulty(), nonce);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,6 +99,10 @@ public class MemoryPoW {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean verify2(byte[] data, int workBufferLength, long difficulty, int nonce) {
|
public static boolean verify2(byte[] data, int workBufferLength, long difficulty, int nonce) {
|
||||||
|
return verify2(data, null, workBufferLength, difficulty, nonce);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean verify2(byte[] data, long[] workBuffer, int workBufferLength, long difficulty, int nonce) {
|
||||||
// Hash data with SHA256
|
// Hash data with SHA256
|
||||||
byte[] hash = Crypto.digest(data);
|
byte[] hash = Crypto.digest(data);
|
||||||
|
|
||||||
@ -111,7 +115,10 @@ public class MemoryPoW {
|
|||||||
byteBuffer = null;
|
byteBuffer = null;
|
||||||
|
|
||||||
int longBufferLength = workBufferLength / 8;
|
int longBufferLength = workBufferLength / 8;
|
||||||
long[] workBuffer = new long[longBufferLength];
|
|
||||||
|
if (workBuffer == null)
|
||||||
|
workBuffer = new long[longBufferLength];
|
||||||
|
|
||||||
long[] state = new long[4];
|
long[] state = new long[4];
|
||||||
|
|
||||||
long seed = 8682522807148012L;
|
long seed = 8682522807148012L;
|
||||||
|
Loading…
Reference in New Issue
Block a user