forked from Qortal/qortal
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:
parent
1d5497e484
commit
b3273ff01a
@ -366,14 +366,9 @@ public class Block {
|
||||
long timestamp = calcTimestamp(parentBlockData, minter.getPublicKey(), minterLevel);
|
||||
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);
|
||||
|
||||
// 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()) {
|
||||
LOGGER.debug("No online accounts - not even our own?");
|
||||
return null;
|
||||
@ -412,29 +407,27 @@ public class Block {
|
||||
// Aggregated, single signature
|
||||
byte[] onlineAccountsSignatures = Qortal25519Extras.aggregateSignatures(signaturesToAggregate);
|
||||
|
||||
// Add nonces to the end of the online accounts signatures if mempow is active
|
||||
if (timestamp >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp()) {
|
||||
try {
|
||||
// Create ordered list of nonce values
|
||||
List<Integer> nonces = new ArrayList<>();
|
||||
for (int i = 0; i < onlineAccountsCount; ++i) {
|
||||
Integer accountIndex = accountIndexes.get(i);
|
||||
OnlineAccountData onlineAccountData = indexedOnlineAccounts.get(accountIndex);
|
||||
nonces.add(onlineAccountData.getNonce());
|
||||
}
|
||||
|
||||
// Encode the nonces to a byte array
|
||||
byte[] encodedNonces = BlockTransformer.encodeOnlineAccountNonces(nonces);
|
||||
|
||||
// Append the encoded nonces to the encoded online account signatures
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
outputStream.write(onlineAccountsSignatures);
|
||||
outputStream.write(encodedNonces);
|
||||
onlineAccountsSignatures = outputStream.toByteArray();
|
||||
}
|
||||
catch (TransformationException | IOException e) {
|
||||
return null;
|
||||
// Add nonces to the end of the online accounts signatures
|
||||
try {
|
||||
// Create ordered list of nonce values
|
||||
List<Integer> nonces = new ArrayList<>();
|
||||
for (int i = 0; i < onlineAccountsCount; ++i) {
|
||||
Integer accountIndex = accountIndexes.get(i);
|
||||
OnlineAccountData onlineAccountData = indexedOnlineAccounts.get(accountIndex);
|
||||
nonces.add(onlineAccountData.getNonce());
|
||||
}
|
||||
|
||||
// Encode the nonces to a byte array
|
||||
byte[] encodedNonces = BlockTransformer.encodeOnlineAccountNonces(nonces);
|
||||
|
||||
// Append the encoded nonces to the encoded online account signatures
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
outputStream.write(onlineAccountsSignatures);
|
||||
outputStream.write(encodedNonces);
|
||||
onlineAccountsSignatures = outputStream.toByteArray();
|
||||
}
|
||||
catch (TransformationException | IOException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] minterSignature = minter.sign(BlockTransformer.getBytesForMinterSignature(parentBlockData,
|
||||
@ -1047,14 +1040,9 @@ public class Block {
|
||||
final int signaturesLength = Transformer.SIGNATURE_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
|
||||
if (this.blockData.getOnlineAccountsSignatures().length != signaturesLength + noncesLength)
|
||||
return ValidationResult.ONLINE_ACCOUNT_SIGNATURES_MALFORMED;
|
||||
} else {
|
||||
if (this.blockData.getOnlineAccountsSignatures().length != signaturesLength)
|
||||
return ValidationResult.ONLINE_ACCOUNT_SIGNATURES_MALFORMED;
|
||||
}
|
||||
// We expect nonces to be appended to the online accounts signatures
|
||||
if (this.blockData.getOnlineAccountsSignatures().length != signaturesLength + noncesLength)
|
||||
return ValidationResult.ONLINE_ACCOUNT_SIGNATURES_MALFORMED;
|
||||
|
||||
// Check signatures
|
||||
long onlineTimestamp = this.blockData.getOnlineAccountsTimestamp();
|
||||
@ -1063,32 +1051,30 @@ public class Block {
|
||||
byte[] encodedOnlineAccountSignatures = this.blockData.getOnlineAccountsSignatures();
|
||||
|
||||
// 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[] extractedNonces = BlockTransformer.extract(encodedOnlineAccountSignatures, signaturesLength, onlineRewardShares.size() * Transformer.INT_LENGTH);
|
||||
encodedOnlineAccountSignatures = extractedSignatures;
|
||||
byte[] extractedSignatures = BlockTransformer.extract(encodedOnlineAccountSignatures, 0, signaturesLength);
|
||||
byte[] extractedNonces = BlockTransformer.extract(encodedOnlineAccountSignatures, signaturesLength, onlineRewardShares.size() * Transformer.INT_LENGTH);
|
||||
encodedOnlineAccountSignatures = extractedSignatures;
|
||||
|
||||
List<Integer> nonces = BlockTransformer.decodeOnlineAccountNonces(extractedNonces);
|
||||
List<Integer> nonces = BlockTransformer.decodeOnlineAccountNonces(extractedNonces);
|
||||
|
||||
// Build block's view of online accounts (without signatures, as we don't need them here)
|
||||
Set<OnlineAccountData> onlineAccounts = new HashSet<>();
|
||||
for (int i = 0; i < onlineRewardShares.size(); ++i) {
|
||||
Integer nonce = nonces.get(i);
|
||||
byte[] publicKey = onlineRewardShares.get(i).getRewardSharePublicKey();
|
||||
// Build block's view of online accounts (without signatures, as we don't need them here)
|
||||
Set<OnlineAccountData> onlineAccounts = new HashSet<>();
|
||||
for (int i = 0; i < onlineRewardShares.size(); ++i) {
|
||||
Integer nonce = nonces.get(i);
|
||||
byte[] publicKey = onlineRewardShares.get(i).getRewardSharePublicKey();
|
||||
|
||||
OnlineAccountData onlineAccountData = new OnlineAccountData(onlineTimestamp, null, publicKey, nonce);
|
||||
onlineAccounts.add(onlineAccountData);
|
||||
}
|
||||
|
||||
// Remove those already validated & cached by online accounts manager - no need to re-validate them
|
||||
OnlineAccountsManager.getInstance().removeKnown(onlineAccounts, onlineTimestamp);
|
||||
|
||||
// Validate the rest
|
||||
for (OnlineAccountData onlineAccount : onlineAccounts)
|
||||
if (!OnlineAccountsManager.getInstance().verifyMemoryPoW(onlineAccount, this.blockData.getTimestamp()))
|
||||
return ValidationResult.ONLINE_ACCOUNT_NONCE_INCORRECT;
|
||||
OnlineAccountData onlineAccountData = new OnlineAccountData(onlineTimestamp, null, publicKey, nonce);
|
||||
onlineAccounts.add(onlineAccountData);
|
||||
}
|
||||
|
||||
// Remove those already validated & cached by online accounts manager - no need to re-validate them
|
||||
OnlineAccountsManager.getInstance().removeKnown(onlineAccounts, onlineTimestamp);
|
||||
|
||||
// Validate the rest
|
||||
for (OnlineAccountData onlineAccount : onlineAccounts)
|
||||
if (!OnlineAccountsManager.getInstance().verifyMemoryPoW(onlineAccount, this.blockData.getTimestamp()))
|
||||
return ValidationResult.ONLINE_ACCOUNT_NONCE_INCORRECT;
|
||||
|
||||
// Extract online accounts' timestamp signatures from block data. Only one signature if aggregated.
|
||||
List<byte[]> onlineAccountsSignatures = BlockTransformer.decodeTimestampSignatures(encodedOnlineAccountSignatures);
|
||||
|
||||
|
@ -195,10 +195,6 @@ public class BlockChain {
|
||||
* featureTriggers because unit tests need to set this value via Reflection. */
|
||||
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 */
|
||||
public static class MaxRewardSharesByTimestamp {
|
||||
public long timestamp;
|
||||
@ -359,10 +355,6 @@ public class BlockChain {
|
||||
return this.onlineAccountsModulusV2Timestamp;
|
||||
}
|
||||
|
||||
public long getOnlineAccountsMemoryPoWTimestamp() {
|
||||
return this.onlineAccountsMemoryPoWTimestamp;
|
||||
}
|
||||
|
||||
/** Returns true if approval-needing transaction types require a txGroupId other than NO_GROUP. */
|
||||
public boolean getRequireGroupForApproval() {
|
||||
return this.requireGroupForApproval;
|
||||
|
@ -20,7 +20,6 @@ import org.qortal.network.message.*;
|
||||
import org.qortal.repository.DataException;
|
||||
import org.qortal.repository.Repository;
|
||||
import org.qortal.repository.RepositoryManager;
|
||||
import org.qortal.settings.Settings;
|
||||
import org.qortal.utils.Base58;
|
||||
import org.qortal.utils.NTP;
|
||||
import org.qortal.utils.NamedThreadFactory;
|
||||
@ -156,7 +155,6 @@ public class OnlineAccountsManager {
|
||||
return;
|
||||
|
||||
byte[] timestampBytes = Longs.toByteArray(onlineAccountsTimestamp);
|
||||
final boolean mempowActive = onlineAccountsTimestamp >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp();
|
||||
|
||||
Set<OnlineAccountData> replacementAccounts = new HashSet<>();
|
||||
for (PrivateKeyAccount onlineAccount : onlineAccounts) {
|
||||
@ -165,7 +163,7 @@ public class OnlineAccountsManager {
|
||||
byte[] signature = Qortal25519Extras.signForAggregation(onlineAccount.getPrivateKey(), timestampBytes);
|
||||
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);
|
||||
replacementAccounts.add(ourOnlineAccountData);
|
||||
@ -321,13 +319,10 @@ public class OnlineAccountsManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate mempow if feature trigger is active (or if online account's timestamp is past the trigger timestamp)
|
||||
long memoryPoWStartTimestamp = BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp();
|
||||
if (now >= memoryPoWStartTimestamp || onlineAccountTimestamp >= memoryPoWStartTimestamp) {
|
||||
if (!getInstance().verifyMemoryPoW(onlineAccountData, now)) {
|
||||
LOGGER.trace(() -> String.format("Rejecting online reward-share for account %s due to invalid PoW nonce", mintingAccount.getAddress()));
|
||||
return false;
|
||||
}
|
||||
// Validate mempow
|
||||
if (!getInstance().verifyMemoryPoW(onlineAccountData, now)) {
|
||||
LOGGER.trace(() -> String.format("Rejecting online reward-share for account %s due to invalid PoW nonce", mintingAccount.getAddress()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -471,12 +466,10 @@ public class OnlineAccountsManager {
|
||||
|
||||
// 'next' timestamp (prioritize this as it's the most important, if mempow active)
|
||||
final long nextOnlineAccountsTimestamp = toOnlineAccountTimestamp(now) + getOnlineTimestampModulus();
|
||||
if (isMemoryPoWActive(now)) {
|
||||
boolean success = computeOurAccountsForTimestamp(nextOnlineAccountsTimestamp);
|
||||
if (!success) {
|
||||
// We didn't compute the required nonce value(s), and so can't proceed until they have been retried
|
||||
return;
|
||||
}
|
||||
boolean success = computeOurAccountsForTimestamp(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
|
||||
@ -553,21 +546,15 @@ public class OnlineAccountsManager {
|
||||
|
||||
// Compute nonce
|
||||
Integer nonce;
|
||||
if (isMemoryPoWActive(NTP.getTime())) {
|
||||
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)));
|
||||
try {
|
||||
nonce = this.computeMemoryPoW(mempowBytes, publicKey, onlineAccountsTimestamp);
|
||||
if (nonce == null) {
|
||||
// A nonce is required
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Send -1 if we haven't computed a nonce due to feature trigger timestamp
|
||||
nonce = -1;
|
||||
} catch (TimeoutException e) {
|
||||
LOGGER.info(String.format("Timed out computing nonce for account %.8s", Base58.encode(publicKey)));
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] signature = Qortal25519Extras.signForAggregation(privateKey, timestampBytes);
|
||||
@ -599,12 +586,6 @@ public class OnlineAccountsManager {
|
||||
|
||||
// MemoryPoW
|
||||
|
||||
private boolean isMemoryPoWActive(Long timestamp) {
|
||||
if (timestamp >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private byte[] getMemoryPoWBytes(byte[] publicKey, long onlineAccountsTimestamp) throws IOException {
|
||||
byte[] timestampBytes = Longs.toByteArray(onlineAccountsTimestamp);
|
||||
|
||||
@ -616,11 +597,6 @@ public class OnlineAccountsManager {
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
// 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) {
|
||||
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
|
||||
if (onlineAccountData.getNonce() == null || onlineAccountData.getNonce() < 0) {
|
||||
return false;
|
||||
|
@ -235,7 +235,7 @@ public class BlockTransformer extends Transformer {
|
||||
// Online accounts timestamp is only present if there are also signatures
|
||||
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())
|
||||
throw new TransformationException("Byte data too long for online accounts signatures");
|
||||
|
||||
@ -511,16 +511,6 @@ public class BlockTransformer extends Transformer {
|
||||
|
||||
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) {
|
||||
byte[] output = new byte[length];
|
||||
|
@ -24,7 +24,6 @@
|
||||
"onlineAccountSignaturesMinLifetime": 43200000,
|
||||
"onlineAccountSignaturesMaxLifetime": 86400000,
|
||||
"onlineAccountsModulusV2Timestamp": 1659801600000,
|
||||
"onlineAccountsMemoryPoWTimestamp": 1666454400000,
|
||||
"rewardsByHeight": [
|
||||
{ "height": 1, "reward": 5.00 },
|
||||
{ "height": 259201, "reward": 4.75 },
|
||||
|
@ -124,8 +124,6 @@ public class AccountUtils {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
byte[] timestampBytes = Longs.toByteArray(timestamp);
|
||||
|
||||
final boolean mempowActive = timestamp >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp();
|
||||
|
||||
for (int a = 0; a < numAccounts; ++a) {
|
||||
byte[] privateKey = new byte[Transformer.PUBLIC_KEY_LENGTH];
|
||||
SECURE_RANDOM.nextBytes(privateKey);
|
||||
@ -135,7 +133,7 @@ public class AccountUtils {
|
||||
|
||||
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));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user