Removed all mempow feature trigger conditionals.

We no longer need all the code complexity, now that 24 hours have passed since activation. We don't validate online accounts beyond 12 hours, and the data is trimmed after 24 hours.
This commit is contained in:
CalDescent 2022-10-23 16:47:42 +01:00
parent 1d5497e484
commit b3273ff01a
6 changed files with 62 additions and 127 deletions

View File

@ -366,14 +366,9 @@ public class Block {
long timestamp = calcTimestamp(parentBlockData, minter.getPublicKey(), minterLevel); long timestamp = calcTimestamp(parentBlockData, minter.getPublicKey(), minterLevel);
long onlineAccountsTimestamp = OnlineAccountsManager.getCurrentOnlineAccountTimestamp(); long onlineAccountsTimestamp = OnlineAccountsManager.getCurrentOnlineAccountTimestamp();
// Fetch our list of online accounts // Fetch our list of online accounts, removing any that are missing a nonce
List<OnlineAccountData> onlineAccounts = OnlineAccountsManager.getInstance().getOnlineAccounts(onlineAccountsTimestamp); List<OnlineAccountData> onlineAccounts = OnlineAccountsManager.getInstance().getOnlineAccounts(onlineAccountsTimestamp);
// If mempow is active, remove any legacy accounts that are missing a nonce
if (timestamp >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp()) {
onlineAccounts.removeIf(a -> a.getNonce() == null || a.getNonce() < 0); onlineAccounts.removeIf(a -> a.getNonce() == null || a.getNonce() < 0);
}
if (onlineAccounts.isEmpty()) { if (onlineAccounts.isEmpty()) {
LOGGER.debug("No online accounts - not even our own?"); LOGGER.debug("No online accounts - not even our own?");
return null; return null;
@ -412,8 +407,7 @@ public class Block {
// Aggregated, single signature // Aggregated, single signature
byte[] onlineAccountsSignatures = Qortal25519Extras.aggregateSignatures(signaturesToAggregate); byte[] onlineAccountsSignatures = Qortal25519Extras.aggregateSignatures(signaturesToAggregate);
// Add nonces to the end of the online accounts signatures if mempow is active // Add nonces to the end of the online accounts signatures
if (timestamp >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp()) {
try { try {
// Create ordered list of nonce values // Create ordered list of nonce values
List<Integer> nonces = new ArrayList<>(); List<Integer> nonces = new ArrayList<>();
@ -435,7 +429,6 @@ public class Block {
catch (TransformationException | IOException e) { catch (TransformationException | IOException e) {
return null; return null;
} }
}
byte[] minterSignature = minter.sign(BlockTransformer.getBytesForMinterSignature(parentBlockData, byte[] minterSignature = minter.sign(BlockTransformer.getBytesForMinterSignature(parentBlockData,
minter.getPublicKey(), encodedOnlineAccounts)); minter.getPublicKey(), encodedOnlineAccounts));
@ -1047,14 +1040,9 @@ public class Block {
final int signaturesLength = Transformer.SIGNATURE_LENGTH; final int signaturesLength = Transformer.SIGNATURE_LENGTH;
final int noncesLength = onlineRewardShares.size() * Transformer.INT_LENGTH; final int noncesLength = onlineRewardShares.size() * Transformer.INT_LENGTH;
if (this.blockData.getTimestamp() >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp()) {
// We expect nonces to be appended to the online accounts signatures // We expect nonces to be appended to the online accounts signatures
if (this.blockData.getOnlineAccountsSignatures().length != signaturesLength + noncesLength) if (this.blockData.getOnlineAccountsSignatures().length != signaturesLength + noncesLength)
return ValidationResult.ONLINE_ACCOUNT_SIGNATURES_MALFORMED; return ValidationResult.ONLINE_ACCOUNT_SIGNATURES_MALFORMED;
} else {
if (this.blockData.getOnlineAccountsSignatures().length != signaturesLength)
return ValidationResult.ONLINE_ACCOUNT_SIGNATURES_MALFORMED;
}
// Check signatures // Check signatures
long onlineTimestamp = this.blockData.getOnlineAccountsTimestamp(); long onlineTimestamp = this.blockData.getOnlineAccountsTimestamp();
@ -1063,7 +1051,6 @@ public class Block {
byte[] encodedOnlineAccountSignatures = this.blockData.getOnlineAccountsSignatures(); byte[] encodedOnlineAccountSignatures = this.blockData.getOnlineAccountsSignatures();
// Split online account signatures into signature(s) + nonces, then validate the nonces // Split online account signatures into signature(s) + nonces, then validate the nonces
if (this.blockData.getTimestamp() >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp()) {
byte[] extractedSignatures = BlockTransformer.extract(encodedOnlineAccountSignatures, 0, signaturesLength); byte[] extractedSignatures = BlockTransformer.extract(encodedOnlineAccountSignatures, 0, signaturesLength);
byte[] extractedNonces = BlockTransformer.extract(encodedOnlineAccountSignatures, signaturesLength, onlineRewardShares.size() * Transformer.INT_LENGTH); byte[] extractedNonces = BlockTransformer.extract(encodedOnlineAccountSignatures, signaturesLength, onlineRewardShares.size() * Transformer.INT_LENGTH);
encodedOnlineAccountSignatures = extractedSignatures; encodedOnlineAccountSignatures = extractedSignatures;
@ -1087,7 +1074,6 @@ public class Block {
for (OnlineAccountData onlineAccount : onlineAccounts) for (OnlineAccountData onlineAccount : onlineAccounts)
if (!OnlineAccountsManager.getInstance().verifyMemoryPoW(onlineAccount, this.blockData.getTimestamp())) if (!OnlineAccountsManager.getInstance().verifyMemoryPoW(onlineAccount, this.blockData.getTimestamp()))
return ValidationResult.ONLINE_ACCOUNT_NONCE_INCORRECT; return ValidationResult.ONLINE_ACCOUNT_NONCE_INCORRECT;
}
// Extract online accounts' timestamp signatures from block data. Only one signature if aggregated. // Extract online accounts' timestamp signatures from block data. Only one signature if aggregated.
List<byte[]> onlineAccountsSignatures = BlockTransformer.decodeTimestampSignatures(encodedOnlineAccountSignatures); List<byte[]> onlineAccountsSignatures = BlockTransformer.decodeTimestampSignatures(encodedOnlineAccountSignatures);

View File

@ -195,10 +195,6 @@ public class BlockChain {
* featureTriggers because unit tests need to set this value via Reflection. */ * featureTriggers because unit tests need to set this value via Reflection. */
private long onlineAccountsModulusV2Timestamp; private long onlineAccountsModulusV2Timestamp;
/** Feature trigger timestamp for online accounts mempow verification. Can't use featureTriggers
* because unit tests need to set this value via Reflection. */
private long onlineAccountsMemoryPoWTimestamp;
/** Max reward shares by block height */ /** Max reward shares by block height */
public static class MaxRewardSharesByTimestamp { public static class MaxRewardSharesByTimestamp {
public long timestamp; public long timestamp;
@ -359,10 +355,6 @@ public class BlockChain {
return this.onlineAccountsModulusV2Timestamp; return this.onlineAccountsModulusV2Timestamp;
} }
public long getOnlineAccountsMemoryPoWTimestamp() {
return this.onlineAccountsMemoryPoWTimestamp;
}
/** Returns true if approval-needing transaction types require a txGroupId other than NO_GROUP. */ /** Returns true if approval-needing transaction types require a txGroupId other than NO_GROUP. */
public boolean getRequireGroupForApproval() { public boolean getRequireGroupForApproval() {
return this.requireGroupForApproval; return this.requireGroupForApproval;

View File

@ -20,7 +20,6 @@ import org.qortal.network.message.*;
import org.qortal.repository.DataException; import org.qortal.repository.DataException;
import org.qortal.repository.Repository; import org.qortal.repository.Repository;
import org.qortal.repository.RepositoryManager; import org.qortal.repository.RepositoryManager;
import org.qortal.settings.Settings;
import org.qortal.utils.Base58; import org.qortal.utils.Base58;
import org.qortal.utils.NTP; import org.qortal.utils.NTP;
import org.qortal.utils.NamedThreadFactory; import org.qortal.utils.NamedThreadFactory;
@ -156,7 +155,6 @@ public class OnlineAccountsManager {
return; return;
byte[] timestampBytes = Longs.toByteArray(onlineAccountsTimestamp); byte[] timestampBytes = Longs.toByteArray(onlineAccountsTimestamp);
final boolean mempowActive = onlineAccountsTimestamp >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp();
Set<OnlineAccountData> replacementAccounts = new HashSet<>(); Set<OnlineAccountData> replacementAccounts = new HashSet<>();
for (PrivateKeyAccount onlineAccount : onlineAccounts) { for (PrivateKeyAccount onlineAccount : onlineAccounts) {
@ -165,7 +163,7 @@ public class OnlineAccountsManager {
byte[] signature = Qortal25519Extras.signForAggregation(onlineAccount.getPrivateKey(), timestampBytes); byte[] signature = Qortal25519Extras.signForAggregation(onlineAccount.getPrivateKey(), timestampBytes);
byte[] publicKey = onlineAccount.getPublicKey(); byte[] publicKey = onlineAccount.getPublicKey();
Integer nonce = mempowActive ? new Random().nextInt(500000) : null; Integer nonce = new Random().nextInt(500000);
OnlineAccountData ourOnlineAccountData = new OnlineAccountData(onlineAccountsTimestamp, signature, publicKey, nonce); OnlineAccountData ourOnlineAccountData = new OnlineAccountData(onlineAccountsTimestamp, signature, publicKey, nonce);
replacementAccounts.add(ourOnlineAccountData); replacementAccounts.add(ourOnlineAccountData);
@ -321,14 +319,11 @@ public class OnlineAccountsManager {
return false; return false;
} }
// Validate mempow if feature trigger is active (or if online account's timestamp is past the trigger timestamp) // Validate mempow
long memoryPoWStartTimestamp = BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp();
if (now >= memoryPoWStartTimestamp || onlineAccountTimestamp >= memoryPoWStartTimestamp) {
if (!getInstance().verifyMemoryPoW(onlineAccountData, now)) { if (!getInstance().verifyMemoryPoW(onlineAccountData, now)) {
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;
} }
}
return true; return true;
} }
@ -471,13 +466,11 @@ public class OnlineAccountsManager {
// 'next' timestamp (prioritize this as it's the most important, if mempow active) // 'next' timestamp (prioritize this as it's the most important, if mempow active)
final long nextOnlineAccountsTimestamp = toOnlineAccountTimestamp(now) + getOnlineTimestampModulus(); final long nextOnlineAccountsTimestamp = toOnlineAccountTimestamp(now) + getOnlineTimestampModulus();
if (isMemoryPoWActive(now)) {
boolean success = computeOurAccountsForTimestamp(nextOnlineAccountsTimestamp); boolean success = computeOurAccountsForTimestamp(nextOnlineAccountsTimestamp);
if (!success) { if (!success) {
// We didn't compute the required nonce value(s), and so can't proceed until they have been retried // We didn't compute the required nonce value(s), and so can't proceed until they have been retried
return; return;
} }
}
// 'current' timestamp // 'current' timestamp
computeOurAccountsForTimestamp(onlineAccountsTimestamp); computeOurAccountsForTimestamp(onlineAccountsTimestamp);
@ -553,7 +546,6 @@ public class OnlineAccountsManager {
// Compute nonce // Compute nonce
Integer nonce; Integer nonce;
if (isMemoryPoWActive(NTP.getTime())) {
try { try {
nonce = this.computeMemoryPoW(mempowBytes, publicKey, onlineAccountsTimestamp); nonce = this.computeMemoryPoW(mempowBytes, publicKey, onlineAccountsTimestamp);
if (nonce == null) { if (nonce == null) {
@ -564,11 +556,6 @@ public class OnlineAccountsManager {
LOGGER.info(String.format("Timed out computing nonce for account %.8s", Base58.encode(publicKey))); LOGGER.info(String.format("Timed out computing nonce for account %.8s", Base58.encode(publicKey)));
return false; return false;
} }
}
else {
// Send -1 if we haven't computed a nonce due to feature trigger timestamp
nonce = -1;
}
byte[] signature = Qortal25519Extras.signForAggregation(privateKey, timestampBytes); byte[] signature = Qortal25519Extras.signForAggregation(privateKey, timestampBytes);
@ -599,12 +586,6 @@ public class OnlineAccountsManager {
// MemoryPoW // MemoryPoW
private boolean isMemoryPoWActive(Long timestamp) {
if (timestamp >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp()) {
return true;
}
return false;
}
private byte[] getMemoryPoWBytes(byte[] publicKey, long onlineAccountsTimestamp) throws IOException { private byte[] getMemoryPoWBytes(byte[] publicKey, long onlineAccountsTimestamp) throws IOException {
byte[] timestampBytes = Longs.toByteArray(onlineAccountsTimestamp); byte[] timestampBytes = Longs.toByteArray(onlineAccountsTimestamp);
@ -616,11 +597,6 @@ public class OnlineAccountsManager {
} }
private Integer computeMemoryPoW(byte[] bytes, byte[] publicKey, long onlineAccountsTimestamp) throws TimeoutException { private Integer computeMemoryPoW(byte[] bytes, byte[] publicKey, long onlineAccountsTimestamp) throws TimeoutException {
if (!isMemoryPoWActive(NTP.getTime())) {
LOGGER.info("Mempow start timestamp not yet reached");
return null;
}
LOGGER.info(String.format("Computing nonce for account %.8s and timestamp %d...", Base58.encode(publicKey), onlineAccountsTimestamp)); 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 // Calculate the time until the next online timestamp and use it as a timeout when computing the nonce
@ -643,12 +619,6 @@ public class OnlineAccountsManager {
} }
public boolean verifyMemoryPoW(OnlineAccountData onlineAccountData, Long timestamp) { public boolean verifyMemoryPoW(OnlineAccountData onlineAccountData, Long timestamp) {
long memoryPoWStartTimestamp = BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp();
if (timestamp < memoryPoWStartTimestamp && onlineAccountData.getTimestamp() < memoryPoWStartTimestamp) {
// Not active yet, so treat it as valid
return true;
}
// 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;

View File

@ -235,7 +235,7 @@ public class BlockTransformer extends Transformer {
// Online accounts timestamp is only present if there are also signatures // Online accounts timestamp is only present if there are also signatures
onlineAccountsTimestamp = byteBuffer.getLong(); onlineAccountsTimestamp = byteBuffer.getLong();
final int signaturesByteLength = getOnlineAccountSignaturesLength(onlineAccountsSignaturesCount, onlineAccountsCount, timestamp); final int signaturesByteLength = (onlineAccountsSignaturesCount * Transformer.SIGNATURE_LENGTH) + (onlineAccountsCount * INT_LENGTH);
if (signaturesByteLength > BlockChain.getInstance().getMaxBlockSize()) if (signaturesByteLength > BlockChain.getInstance().getMaxBlockSize())
throw new TransformationException("Byte data too long for online accounts signatures"); throw new TransformationException("Byte data too long for online accounts signatures");
@ -511,16 +511,6 @@ public class BlockTransformer extends Transformer {
return nonces; return nonces;
} }
public static int getOnlineAccountSignaturesLength(int onlineAccountsSignaturesCount, int onlineAccountCount, long blockTimestamp) {
if (blockTimestamp >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp()) {
// Once mempow is active, we expect the online account signatures to be appended with the nonce values
return (onlineAccountsSignaturesCount * Transformer.SIGNATURE_LENGTH) + (onlineAccountCount * INT_LENGTH);
}
else {
// Before mempow, only the online account signatures were included (which will likely be a single signature)
return onlineAccountsSignaturesCount * Transformer.SIGNATURE_LENGTH;
}
}
public static byte[] extract(byte[] input, int pos, int length) { public static byte[] extract(byte[] input, int pos, int length) {
byte[] output = new byte[length]; byte[] output = new byte[length];

View File

@ -24,7 +24,6 @@
"onlineAccountSignaturesMinLifetime": 43200000, "onlineAccountSignaturesMinLifetime": 43200000,
"onlineAccountSignaturesMaxLifetime": 86400000, "onlineAccountSignaturesMaxLifetime": 86400000,
"onlineAccountsModulusV2Timestamp": 1659801600000, "onlineAccountsModulusV2Timestamp": 1659801600000,
"onlineAccountsMemoryPoWTimestamp": 1666454400000,
"rewardsByHeight": [ "rewardsByHeight": [
{ "height": 1, "reward": 5.00 }, { "height": 1, "reward": 5.00 },
{ "height": 259201, "reward": 4.75 }, { "height": 259201, "reward": 4.75 },

View File

@ -124,8 +124,6 @@ public class AccountUtils {
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
byte[] timestampBytes = Longs.toByteArray(timestamp); byte[] timestampBytes = Longs.toByteArray(timestamp);
final boolean mempowActive = timestamp >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp();
for (int a = 0; a < numAccounts; ++a) { for (int a = 0; a < numAccounts; ++a) {
byte[] privateKey = new byte[Transformer.PUBLIC_KEY_LENGTH]; byte[] privateKey = new byte[Transformer.PUBLIC_KEY_LENGTH];
SECURE_RANDOM.nextBytes(privateKey); SECURE_RANDOM.nextBytes(privateKey);
@ -135,7 +133,7 @@ public class AccountUtils {
byte[] signature = signForAggregation(privateKey, timestampBytes); byte[] signature = signForAggregation(privateKey, timestampBytes);
Integer nonce = mempowActive ? new Random().nextInt(500000) : null; Integer nonce = new Random().nextInt(500000);
onlineAccounts.add(new OnlineAccountData(timestamp, signature, publicKey, nonce)); onlineAccounts.add(new OnlineAccountData(timestamp, signature, publicKey, nonce));
} }