mirror of
https://github.com/Qortal/qortal.git
synced 2025-04-30 06:47:50 +00:00
Compute the nonce for the 'next' timestamp before the 'current' timestamp.
Nodes use each 30 minute period to compute the nonce for the next 30 minute period, so this should be prioritized. Once calculated, the 'current' timestamp is attempted if there is enough time. Doing it in this order avoids falling behind and then struggling to catch up. We will need to think about how to handle node restarts, since otherwise an auto update could cause a gap in online accounts due to all nodes computing the 'next' timestamp before the 'current' one.
This commit is contained in:
parent
32a0b02ea4
commit
abc9cb3958
@ -351,13 +351,17 @@ public class OnlineAccountsManager extends Thread {
|
||||
return;
|
||||
}
|
||||
|
||||
// 'current' timestamp
|
||||
// 'next' timestamp (prioritize this as it's the most important)
|
||||
final long nextOnlineAccountsTimestamp = toOnlineAccountTimestamp(now) + getOnlineTimestampModulus();
|
||||
boolean success = computeOurAccountsForTimestamp(mintingAccounts, nextOnlineAccountsTimestamp);
|
||||
if (!success) {
|
||||
// We didn't compute the required nonce value(s), and so can't proceed until they have been retried
|
||||
return;
|
||||
}
|
||||
|
||||
// 'current' timestamp (if there's enough time after successfully computing the 'next' timestamps)
|
||||
final long onlineAccountsTimestamp = toOnlineAccountTimestamp(now);
|
||||
computeOurAccountsForTimestamp(mintingAccounts, onlineAccountsTimestamp);
|
||||
|
||||
// 'next' timestamp // TODO
|
||||
// final long nextOnlineAccountsTimestamp = toOnlineAccountTimestamp(now) + getOnlineTimestampModulus();
|
||||
// computeOurAccountsForTimestamp(mintingAccounts, nextOnlineAccountsTimestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -365,7 +369,7 @@ public class OnlineAccountsManager extends Thread {
|
||||
* @param mintingAccounts - the online accounts
|
||||
* @param onlineAccountsTimestamp - the online accounts timestamp
|
||||
*/
|
||||
private void computeOurAccountsForTimestamp(List<MintingAccountData> mintingAccounts, long onlineAccountsTimestamp) {
|
||||
private boolean computeOurAccountsForTimestamp(List<MintingAccountData> mintingAccounts, long onlineAccountsTimestamp) {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
|
||||
boolean hasInfoChanged = false;
|
||||
@ -409,7 +413,7 @@ public class OnlineAccountsManager extends Thread {
|
||||
BlockData recentBlockData = repository.getBlockRepository().fromHeight(referenceHeight);
|
||||
if (recentBlockData == null || recentBlockData.getSignature() == null) {
|
||||
LOGGER.info("Unable to compute online accounts without having a recent block");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
byte[] reducedRecentBlockSignature = Arrays.copyOfRange(recentBlockData.getSignature(), 0, 8);
|
||||
|
||||
@ -422,8 +426,20 @@ public class OnlineAccountsManager extends Thread {
|
||||
continue MINTING_ACCOUNTS;
|
||||
}
|
||||
|
||||
Integer nonce = this.computeMemoryPoW(mempowBytes, publicKey);
|
||||
Integer nonce;
|
||||
if (isMemoryPoWActive()) {
|
||||
try {
|
||||
nonce = this.computeMemoryPoW(mempowBytes, publicKey, onlineAccountsTimestamp);
|
||||
if (nonce == null) {
|
||||
// A nonce is required
|
||||
return false;
|
||||
}
|
||||
} catch (TimeoutException e) {
|
||||
LOGGER.info(String.format("Timed out computing nonce for account %.8s", Base58.encode(publicKey)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Send zero if we haven't computed a nonce due to feature trigger timestamp
|
||||
nonce = 0;
|
||||
}
|
||||
@ -432,15 +448,20 @@ public class OnlineAccountsManager extends Thread {
|
||||
|
||||
OnlineAccountData ourOnlineAccountData = new OnlineAccountData(onlineAccountsTimestamp, signature, publicKey, Arrays.asList(nonce), reducedRecentBlockSignature);
|
||||
|
||||
// Make sure to verify before adding
|
||||
if (verifyMemoryPoW(ourOnlineAccountData)) {
|
||||
this.onlineAccounts.add(ourOnlineAccountData);
|
||||
|
||||
LOGGER.trace(() -> String.format("Added our online account %s with timestamp %d", mintingAccount.getAddress(), onlineAccountsTimestamp));
|
||||
ourOnlineAccounts.add(ourOnlineAccountData);
|
||||
hasInfoChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasInfoChanged)
|
||||
return;
|
||||
if (!hasInfoChanged) {
|
||||
// Nothing to do
|
||||
return true;
|
||||
}
|
||||
|
||||
Message messageV2 = new OnlineAccountsV2Message(ourOnlineAccounts);
|
||||
Message messageV3 = new OnlineAccountsV3Message(ourOnlineAccounts);
|
||||
@ -450,9 +471,11 @@ public class OnlineAccountsManager extends Thread {
|
||||
);
|
||||
|
||||
LOGGER.trace(() -> String.format("Broadcasted %d online account%s with timestamp %d", ourOnlineAccounts.size(), (ourOnlineAccounts.size() != 1 ? "s" : ""), onlineAccountsTimestamp));
|
||||
return true;
|
||||
|
||||
} catch (DataException e) {
|
||||
LOGGER.error(String.format("Repository issue while computing online accounts"), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -467,35 +490,29 @@ public class OnlineAccountsManager extends Thread {
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
private Integer computeMemoryPoW(byte[] bytes, byte[] publicKey) {
|
||||
Long startTime = NTP.getTime();
|
||||
if (startTime < BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp() || Settings.getInstance().isOnlineAccountsMemPoWEnabled()) {
|
||||
private Integer computeMemoryPoW(byte[] bytes, byte[] publicKey, long onlineAccountsTimestamp) throws TimeoutException {
|
||||
if (!isMemoryPoWActive()) {
|
||||
LOGGER.info("Mempow start timestamp not yet reached, and onlineAccountsMemPoWEnabled not enabled in settings");
|
||||
return null;
|
||||
}
|
||||
|
||||
LOGGER.info(String.format("Computing nonce for account %.8s...", Base58.encode(publicKey)));
|
||||
LOGGER.info(String.format("Computing nonce for account %.8s and timestamp %d...", Base58.encode(publicKey), onlineAccountsTimestamp));
|
||||
|
||||
// Calculate the time until the next online timestamp and use it as a timeout when computing the nonce
|
||||
Long startTime = NTP.getTime();
|
||||
final long nextOnlineAccountsTimestamp = toOnlineAccountTimestamp(startTime) + getOnlineTimestampModulus();
|
||||
long timeUntilNextTimestamp = nextOnlineAccountsTimestamp - startTime;
|
||||
|
||||
Integer nonce;
|
||||
try {
|
||||
nonce = MemoryPoW.compute2(bytes, POW_BUFFER_SIZE, POW_DIFFICULTY, timeUntilNextTimestamp);
|
||||
} catch (TimeoutException e) {
|
||||
LOGGER.info(String.format("Timed out computing nonce for account %.8s", Base58.encode(publicKey)));
|
||||
return null;
|
||||
}
|
||||
Integer nonce = MemoryPoW.compute2(bytes, POW_BUFFER_SIZE, POW_DIFFICULTY, timeUntilNextTimestamp);
|
||||
|
||||
double totalSeconds = (NTP.getTime() - startTime) / 1000.0f;
|
||||
int minutes = (int) ((totalSeconds % 3600) / 60);
|
||||
int seconds = (int) (totalSeconds % 60);
|
||||
double hashRate = nonce / totalSeconds;
|
||||
|
||||
LOGGER.info(String.format("Computed nonce for account %.8s: %d. Buffer size: %d. Difficulty: %d. " +
|
||||
"Time taken: %02d:%02d. Hashrate: %f", Base58.encode(publicKey), nonce,
|
||||
POW_BUFFER_SIZE, POW_DIFFICULTY, minutes, seconds, hashRate));
|
||||
LOGGER.info(String.format("Computed nonce for timestamp %d and account %.8s: %d. Buffer size: %d. Difficulty: %d. " +
|
||||
"Time taken: %02d:%02d. Hashrate: %f", onlineAccountsTimestamp, Base58.encode(publicKey),
|
||||
nonce, POW_BUFFER_SIZE, POW_DIFFICULTY, minutes, seconds, hashRate));
|
||||
|
||||
return nonce;
|
||||
}
|
||||
@ -572,6 +589,14 @@ public class OnlineAccountsManager extends Thread {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMemoryPoWActive() {
|
||||
Long now = NTP.getTime();
|
||||
if (now < BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp() || Settings.getInstance().isOnlineAccountsMemPoWEnabled()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Network handlers
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user