forked from Qortal/qortal
Increase ONLINE_ACCOUNTS_MODULUS from 5 to 30 mins at a future undecided timestamp.
Note: it's important that this timestamp is set on a 1-hour boundary (such as 16:00:00) to ensure a clean switchover. # Conflicts: # src/main/java/org/qortal/block/BlockChain.java
This commit is contained in:
parent
6c201db3dd
commit
f7dabcaeb0
@ -987,7 +987,7 @@ public class Block {
|
|||||||
byte[] onlineTimestampBytes = Longs.toByteArray(onlineTimestamp);
|
byte[] onlineTimestampBytes = Longs.toByteArray(onlineTimestamp);
|
||||||
|
|
||||||
// If this block is much older than current online timestamp, then there's no point checking current online accounts
|
// If this block is much older than current online timestamp, then there's no point checking current online accounts
|
||||||
List<OnlineAccountData> currentOnlineAccounts = onlineTimestamp < NTP.getTime() - OnlineAccountsManager.ONLINE_TIMESTAMP_MODULUS
|
List<OnlineAccountData> currentOnlineAccounts = onlineTimestamp < NTP.getTime() - OnlineAccountsManager.getOnlineTimestampModulus()
|
||||||
? null
|
? null
|
||||||
: OnlineAccountsManager.getInstance().getOnlineAccounts();
|
: OnlineAccountsManager.getInstance().getOnlineAccounts();
|
||||||
List<OnlineAccountData> latestBlocksOnlineAccounts = OnlineAccountsManager.getInstance().getLatestBlocksOnlineAccounts();
|
List<OnlineAccountData> latestBlocksOnlineAccounts = OnlineAccountsManager.getInstance().getLatestBlocksOnlineAccounts();
|
||||||
|
@ -162,6 +162,10 @@ public class BlockChain {
|
|||||||
/** Maximum time to retain online account signatures (ms) for block validity checks, to allow for clock variance. */
|
/** Maximum time to retain online account signatures (ms) for block validity checks, to allow for clock variance. */
|
||||||
private long onlineAccountSignaturesMaxLifetime;
|
private long onlineAccountSignaturesMaxLifetime;
|
||||||
|
|
||||||
|
/** Feature trigger timestamp for ONLINE_ACCOUNTS_MODULUS time interval increase. Can't use
|
||||||
|
* featureTriggers because unit tests need to set this value via Reflection. */
|
||||||
|
private long onlineAccountsModulusV2Timestamp;
|
||||||
|
|
||||||
/** Settings relating to CIYAM AT feature. */
|
/** Settings relating to CIYAM AT feature. */
|
||||||
public static class CiyamAtSettings {
|
public static class CiyamAtSettings {
|
||||||
/** Fee per step/op-code executed. */
|
/** Fee per step/op-code executed. */
|
||||||
@ -310,6 +314,11 @@ public class BlockChain {
|
|||||||
return this.maxBlockSize;
|
return this.maxBlockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Online accounts
|
||||||
|
public long getOnlineAccountsModulusV2Timestamp() {
|
||||||
|
return this.onlineAccountsModulusV2Timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
/** 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;
|
||||||
|
@ -50,8 +50,8 @@ public class OnlineAccountsManager extends Thread {
|
|||||||
// To do with online accounts list
|
// To do with online accounts list
|
||||||
private static final long ONLINE_ACCOUNTS_TASKS_INTERVAL = 10 * 1000L; // ms
|
private static final long ONLINE_ACCOUNTS_TASKS_INTERVAL = 10 * 1000L; // ms
|
||||||
private static final long ONLINE_ACCOUNTS_BROADCAST_INTERVAL = 1 * 60 * 1000L; // ms
|
private static final long ONLINE_ACCOUNTS_BROADCAST_INTERVAL = 1 * 60 * 1000L; // ms
|
||||||
public static final long ONLINE_TIMESTAMP_MODULUS = 5 * 60 * 1000L;
|
public static final long ONLINE_TIMESTAMP_MODULUS_V1 = 5 * 60 * 1000L;
|
||||||
private static final long LAST_SEEN_EXPIRY_PERIOD = (ONLINE_TIMESTAMP_MODULUS * 2) + (1 * 60 * 1000L);
|
public static final long ONLINE_TIMESTAMP_MODULUS_V2 = 30 * 60 * 1000L;
|
||||||
/** How many (latest) blocks' worth of online accounts we cache */
|
/** How many (latest) blocks' worth of online accounts we cache */
|
||||||
private static final int MAX_BLOCKS_CACHED_ONLINE_ACCOUNTS = 2;
|
private static final int MAX_BLOCKS_CACHED_ONLINE_ACCOUNTS = 2;
|
||||||
private static final long ONLINE_ACCOUNTS_V2_PEER_VERSION = 0x0300020000L;
|
private static final long ONLINE_ACCOUNTS_V2_PEER_VERSION = 0x0300020000L;
|
||||||
@ -116,6 +116,13 @@ public class OnlineAccountsManager extends Thread {
|
|||||||
this.interrupt();
|
this.interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long getOnlineTimestampModulus() {
|
||||||
|
if (NTP.getTime() >= BlockChain.getInstance().getOnlineAccountsModulusV2Timestamp()) {
|
||||||
|
return ONLINE_TIMESTAMP_MODULUS_V2;
|
||||||
|
}
|
||||||
|
return ONLINE_TIMESTAMP_MODULUS_V1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Online accounts import queue
|
// Online accounts import queue
|
||||||
|
|
||||||
@ -159,7 +166,7 @@ public class OnlineAccountsManager extends Thread {
|
|||||||
PublicKeyAccount otherAccount = new PublicKeyAccount(repository, onlineAccountData.getPublicKey());
|
PublicKeyAccount otherAccount = new PublicKeyAccount(repository, onlineAccountData.getPublicKey());
|
||||||
|
|
||||||
// Check timestamp is 'recent' here
|
// Check timestamp is 'recent' here
|
||||||
if (Math.abs(onlineAccountData.getTimestamp() - now) > ONLINE_TIMESTAMP_MODULUS * 2) {
|
if (Math.abs(onlineAccountData.getTimestamp() - now) > getOnlineTimestampModulus() * 2) {
|
||||||
LOGGER.trace(() -> String.format("Rejecting online account %s with out of range timestamp %d", otherAccount.getAddress(), onlineAccountData.getTimestamp()));
|
LOGGER.trace(() -> String.format("Rejecting online account %s with out of range timestamp %d", otherAccount.getAddress(), onlineAccountData.getTimestamp()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -241,7 +248,8 @@ public class OnlineAccountsManager extends Thread {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Expire old entries
|
// Expire old entries
|
||||||
final long cutoffThreshold = now - LAST_SEEN_EXPIRY_PERIOD;
|
final long lastSeenExpiryPeriod = (getOnlineTimestampModulus() * 2) + (1 * 60 * 1000L);
|
||||||
|
final long cutoffThreshold = now - lastSeenExpiryPeriod;
|
||||||
synchronized (this.onlineAccounts) {
|
synchronized (this.onlineAccounts) {
|
||||||
Iterator<OnlineAccountData> iterator = this.onlineAccounts.iterator();
|
Iterator<OnlineAccountData> iterator = this.onlineAccounts.iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
@ -372,7 +380,7 @@ public class OnlineAccountsManager extends Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static long toOnlineAccountTimestamp(long timestamp) {
|
public static long toOnlineAccountTimestamp(long timestamp) {
|
||||||
return (timestamp / ONLINE_TIMESTAMP_MODULUS) * ONLINE_TIMESTAMP_MODULUS;
|
return (timestamp / getOnlineTimestampModulus()) * getOnlineTimestampModulus();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns list of online accounts with timestamp recent enough to be considered currently online. */
|
/** Returns list of online accounts with timestamp recent enough to be considered currently online. */
|
||||||
|
@ -12,7 +12,6 @@ import java.util.function.Supplier;
|
|||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.qortal.account.Account;
|
import org.qortal.account.Account;
|
||||||
import org.qortal.controller.Controller;
|
|
||||||
import org.qortal.controller.OnlineAccountsManager;
|
import org.qortal.controller.OnlineAccountsManager;
|
||||||
import org.qortal.controller.tradebot.TradeBot;
|
import org.qortal.controller.tradebot.TradeBot;
|
||||||
import org.qortal.crosschain.ACCT;
|
import org.qortal.crosschain.ACCT;
|
||||||
@ -49,7 +48,7 @@ public class PresenceTransaction extends Transaction {
|
|||||||
REWARD_SHARE(0) {
|
REWARD_SHARE(0) {
|
||||||
@Override
|
@Override
|
||||||
public long getLifetime() {
|
public long getLifetime() {
|
||||||
return OnlineAccountsManager.ONLINE_TIMESTAMP_MODULUS;
|
return OnlineAccountsManager.getOnlineTimestampModulus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TRADE_BOT(1) {
|
TRADE_BOT(1) {
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
"founderEffectiveMintingLevel": 10,
|
"founderEffectiveMintingLevel": 10,
|
||||||
"onlineAccountSignaturesMinLifetime": 43200000,
|
"onlineAccountSignaturesMinLifetime": 43200000,
|
||||||
"onlineAccountSignaturesMaxLifetime": 86400000,
|
"onlineAccountSignaturesMaxLifetime": 86400000,
|
||||||
|
"onlineAccountsModulusV2Timestamp": 9999999999999,
|
||||||
"rewardsByHeight": [
|
"rewardsByHeight": [
|
||||||
{ "height": 1, "reward": 5.00 },
|
{ "height": 1, "reward": 5.00 },
|
||||||
{ "height": 259201, "reward": 4.75 },
|
{ "height": 259201, "reward": 4.75 },
|
||||||
|
@ -1,22 +1,36 @@
|
|||||||
package org.qortal.test.network;
|
package org.qortal.test.network;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;
|
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.qortal.account.PrivateKeyAccount;
|
||||||
|
import org.qortal.block.Block;
|
||||||
|
import org.qortal.block.BlockChain;
|
||||||
|
import org.qortal.controller.BlockMinter;
|
||||||
|
import org.qortal.controller.OnlineAccountsManager;
|
||||||
import org.qortal.data.network.OnlineAccountData;
|
import org.qortal.data.network.OnlineAccountData;
|
||||||
import org.qortal.network.message.*;
|
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.test.common.Common;
|
||||||
import org.qortal.transform.Transformer;
|
import org.qortal.transform.Transformer;
|
||||||
|
import org.qortal.utils.Base58;
|
||||||
|
import org.qortal.utils.NTP;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class OnlineAccountsTests {
|
public class OnlineAccountsTests extends Common {
|
||||||
|
|
||||||
private static final Random RANDOM = new Random();
|
private static final Random RANDOM = new Random();
|
||||||
static {
|
static {
|
||||||
@ -27,6 +41,12 @@ public class OnlineAccountsTests {
|
|||||||
Security.insertProviderAt(new BouncyCastleJsseProvider(), 1);
|
Security.insertProviderAt(new BouncyCastleJsseProvider(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void beforeTest() throws DataException, IOException {
|
||||||
|
Common.useSettingsAndDb(Common.testSettingsFilename, false);
|
||||||
|
NTP.setFixedOffset(Settings.getInstance().getTestNtpOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetOnlineAccountsV2() throws MessageException {
|
public void testGetOnlineAccountsV2() throws MessageException {
|
||||||
@ -111,4 +131,75 @@ public class OnlineAccountsTests {
|
|||||||
return onlineAccounts;
|
return onlineAccounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnlineAccountsModulusV1() throws IllegalAccessException, DataException {
|
||||||
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
|
|
||||||
|
// Set feature trigger timestamp to MAX long so that it is inactive
|
||||||
|
FieldUtils.writeField(BlockChain.getInstance(), "onlineAccountsModulusV2Timestamp", Long.MAX_VALUE, true);
|
||||||
|
|
||||||
|
List<String> onlineAccountSignatures = new ArrayList<>();
|
||||||
|
long fakeNTPOffset = 0L;
|
||||||
|
|
||||||
|
// Mint a block and store its timestamp
|
||||||
|
Block block = BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
|
||||||
|
long lastBlockTimestamp = block.getBlockData().getTimestamp();
|
||||||
|
|
||||||
|
// Mint some blocks and keep track of the different online account signatures
|
||||||
|
for (int i = 0; i < 30; i++) {
|
||||||
|
block = BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
|
||||||
|
|
||||||
|
// Increase NTP fixed offset by the block time, to simulate time passing
|
||||||
|
long blockTimeDelta = block.getBlockData().getTimestamp() - lastBlockTimestamp;
|
||||||
|
lastBlockTimestamp = block.getBlockData().getTimestamp();
|
||||||
|
fakeNTPOffset += blockTimeDelta;
|
||||||
|
NTP.setFixedOffset(fakeNTPOffset);
|
||||||
|
|
||||||
|
String lastOnlineAccountSignatures58 = Base58.encode(block.getBlockData().getOnlineAccountsSignatures());
|
||||||
|
if (!onlineAccountSignatures.contains(lastOnlineAccountSignatures58)) {
|
||||||
|
onlineAccountSignatures.add(lastOnlineAccountSignatures58);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We expect at least 6 unique signatures over 30 blocks (generally 6-8, but could be higher due to block time differences)
|
||||||
|
System.out.println(String.format("onlineAccountSignatures count: %d", onlineAccountSignatures.size()));
|
||||||
|
assertTrue(onlineAccountSignatures.size() >= 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnlineAccountsModulusV2() throws IllegalAccessException, DataException {
|
||||||
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
|
|
||||||
|
// Set feature trigger timestamp to 0 so that it is active
|
||||||
|
FieldUtils.writeField(BlockChain.getInstance(), "onlineAccountsModulusV2Timestamp", 0L, true);
|
||||||
|
|
||||||
|
List<String> onlineAccountSignatures = new ArrayList<>();
|
||||||
|
long fakeNTPOffset = 0L;
|
||||||
|
|
||||||
|
// Mint a block and store its timestamp
|
||||||
|
Block block = BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
|
||||||
|
long lastBlockTimestamp = block.getBlockData().getTimestamp();
|
||||||
|
|
||||||
|
// Mint some blocks and keep track of the different online account signatures
|
||||||
|
for (int i = 0; i < 30; i++) {
|
||||||
|
block = BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
|
||||||
|
|
||||||
|
// Increase NTP fixed offset by the block time, to simulate time passing
|
||||||
|
long blockTimeDelta = block.getBlockData().getTimestamp() - lastBlockTimestamp;
|
||||||
|
lastBlockTimestamp = block.getBlockData().getTimestamp();
|
||||||
|
fakeNTPOffset += blockTimeDelta;
|
||||||
|
NTP.setFixedOffset(fakeNTPOffset);
|
||||||
|
|
||||||
|
String lastOnlineAccountSignatures58 = Base58.encode(block.getBlockData().getOnlineAccountsSignatures());
|
||||||
|
if (!onlineAccountSignatures.contains(lastOnlineAccountSignatures58)) {
|
||||||
|
onlineAccountSignatures.add(lastOnlineAccountSignatures58);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We expect 1-3 unique signatures over 30 blocks
|
||||||
|
System.out.println(String.format("onlineAccountSignatures count: %d", onlineAccountSignatures.size()));
|
||||||
|
assertTrue(onlineAccountSignatures.size() >= 1 && onlineAccountSignatures.size() <= 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"founderEffectiveMintingLevel": 10,
|
"founderEffectiveMintingLevel": 10,
|
||||||
"onlineAccountSignaturesMinLifetime": 3600000,
|
"onlineAccountSignaturesMinLifetime": 3600000,
|
||||||
"onlineAccountSignaturesMaxLifetime": 86400000,
|
"onlineAccountSignaturesMaxLifetime": 86400000,
|
||||||
|
"onlineAccountsModulusV2Timestamp": 9999999999999,
|
||||||
"rewardsByHeight": [
|
"rewardsByHeight": [
|
||||||
{ "height": 1, "reward": 100 },
|
{ "height": 1, "reward": 100 },
|
||||||
{ "height": 11, "reward": 10 },
|
{ "height": 11, "reward": 10 },
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"founderEffectiveMintingLevel": 10,
|
"founderEffectiveMintingLevel": 10,
|
||||||
"onlineAccountSignaturesMinLifetime": 3600000,
|
"onlineAccountSignaturesMinLifetime": 3600000,
|
||||||
"onlineAccountSignaturesMaxLifetime": 86400000,
|
"onlineAccountSignaturesMaxLifetime": 86400000,
|
||||||
|
"onlineAccountsModulusV2Timestamp": 9999999999999,
|
||||||
"rewardsByHeight": [
|
"rewardsByHeight": [
|
||||||
{ "height": 1, "reward": 100 },
|
{ "height": 1, "reward": 100 },
|
||||||
{ "height": 11, "reward": 10 },
|
{ "height": 11, "reward": 10 },
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"founderEffectiveMintingLevel": 10,
|
"founderEffectiveMintingLevel": 10,
|
||||||
"onlineAccountSignaturesMinLifetime": 3600000,
|
"onlineAccountSignaturesMinLifetime": 3600000,
|
||||||
"onlineAccountSignaturesMaxLifetime": 86400000,
|
"onlineAccountSignaturesMaxLifetime": 86400000,
|
||||||
|
"onlineAccountsModulusV2Timestamp": 9999999999999,
|
||||||
"rewardsByHeight": [
|
"rewardsByHeight": [
|
||||||
{ "height": 1, "reward": 100 },
|
{ "height": 1, "reward": 100 },
|
||||||
{ "height": 11, "reward": 10 },
|
{ "height": 11, "reward": 10 },
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"founderEffectiveMintingLevel": 10,
|
"founderEffectiveMintingLevel": 10,
|
||||||
"onlineAccountSignaturesMinLifetime": 3600000,
|
"onlineAccountSignaturesMinLifetime": 3600000,
|
||||||
"onlineAccountSignaturesMaxLifetime": 86400000,
|
"onlineAccountSignaturesMaxLifetime": 86400000,
|
||||||
|
"onlineAccountsModulusV2Timestamp": 9999999999999,
|
||||||
"rewardsByHeight": [
|
"rewardsByHeight": [
|
||||||
{ "height": 1, "reward": 100 },
|
{ "height": 1, "reward": 100 },
|
||||||
{ "height": 11, "reward": 10 },
|
{ "height": 11, "reward": 10 },
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"founderEffectiveMintingLevel": 10,
|
"founderEffectiveMintingLevel": 10,
|
||||||
"onlineAccountSignaturesMinLifetime": 3600000,
|
"onlineAccountSignaturesMinLifetime": 3600000,
|
||||||
"onlineAccountSignaturesMaxLifetime": 86400000,
|
"onlineAccountSignaturesMaxLifetime": 86400000,
|
||||||
|
"onlineAccountsModulusV2Timestamp": 9999999999999,
|
||||||
"rewardsByHeight": [
|
"rewardsByHeight": [
|
||||||
{ "height": 1, "reward": 100 },
|
{ "height": 1, "reward": 100 },
|
||||||
{ "height": 11, "reward": 10 },
|
{ "height": 11, "reward": 10 },
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"founderEffectiveMintingLevel": 10,
|
"founderEffectiveMintingLevel": 10,
|
||||||
"onlineAccountSignaturesMinLifetime": 3600000,
|
"onlineAccountSignaturesMinLifetime": 3600000,
|
||||||
"onlineAccountSignaturesMaxLifetime": 86400000,
|
"onlineAccountSignaturesMaxLifetime": 86400000,
|
||||||
|
"onlineAccountsModulusV2Timestamp": 9999999999999,
|
||||||
"rewardsByHeight": [
|
"rewardsByHeight": [
|
||||||
{ "height": 1, "reward": 100 },
|
{ "height": 1, "reward": 100 },
|
||||||
{ "height": 11, "reward": 10 },
|
{ "height": 11, "reward": 10 },
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"founderEffectiveMintingLevel": 10,
|
"founderEffectiveMintingLevel": 10,
|
||||||
"onlineAccountSignaturesMinLifetime": 3600000,
|
"onlineAccountSignaturesMinLifetime": 3600000,
|
||||||
"onlineAccountSignaturesMaxLifetime": 86400000,
|
"onlineAccountSignaturesMaxLifetime": 86400000,
|
||||||
|
"onlineAccountsModulusV2Timestamp": 9999999999999,
|
||||||
"rewardsByHeight": [
|
"rewardsByHeight": [
|
||||||
{ "height": 1, "reward": 100 },
|
{ "height": 1, "reward": 100 },
|
||||||
{ "height": 11, "reward": 10 },
|
{ "height": 11, "reward": 10 },
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"founderEffectiveMintingLevel": 10,
|
"founderEffectiveMintingLevel": 10,
|
||||||
"onlineAccountSignaturesMinLifetime": 3600000,
|
"onlineAccountSignaturesMinLifetime": 3600000,
|
||||||
"onlineAccountSignaturesMaxLifetime": 86400000,
|
"onlineAccountSignaturesMaxLifetime": 86400000,
|
||||||
|
"onlineAccountsModulusV2Timestamp": 9999999999999,
|
||||||
"rewardsByHeight": [
|
"rewardsByHeight": [
|
||||||
{ "height": 1, "reward": 100 },
|
{ "height": 1, "reward": 100 },
|
||||||
{ "height": 11, "reward": 10 },
|
{ "height": 11, "reward": 10 },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user