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 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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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];
|
||||||
|
@ -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 },
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user