3
0
mirror of https://github.com/Qortal/qortal.git synced 2025-02-11 17:55:50 +00:00

A merge of just alpha's validation changes, phil and quick's commits, and kenny's changes to test.

This commit is contained in:
crowetic 2024-12-03 08:29:53 -08:00
parent 2347118e59
commit 2e989aaa57
24 changed files with 568 additions and 59 deletions

View File

@ -349,10 +349,28 @@ public class Account {
} }
/** /**
* Returns 'effective' minting level, or zero if reward-share does not exist. * Returns reward-share minting address, or unknown if reward-share does not exist.
* *
* @param repository * @param repository
* @param rewardSharePublicKey * @param rewardSharePublicKey
* @return address or unknown
* @throws DataException
*/
public static String getRewardShareMintingAddress(Repository repository, byte[] rewardSharePublicKey) throws DataException {
// Find actual minter address
RewardShareData rewardShareData = repository.getAccountRepository().getRewardShare(rewardSharePublicKey);
if (rewardShareData == null)
return "Unknown";
return rewardShareData.getMinter();
}
/**
* Returns 'effective' minting level, or zero if reward-share does not exist.
*
* @param repository
* @param rewardSharePublicKey
* @return 0+ * @return 0+
* @throws DataException * @throws DataException
*/ */

View File

@ -1,7 +1,13 @@
package org.qortal.api.model; package org.qortal.api.model;
import org.qortal.account.Account;
import org.qortal.repository.DataException;
import org.qortal.repository.RepositoryManager;
import org.qortal.repository.Repository;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
// All properties to be converted to JSON via JAXB // All properties to be converted to JSON via JAXB
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
@ -47,4 +53,31 @@ public class ApiOnlineAccount {
return this.recipientAddress; return this.recipientAddress;
} }
public int getMinterLevelFromPublicKey() {
try (final Repository repository = RepositoryManager.getRepository()) {
return Account.getRewardShareEffectiveMintingLevel(repository, this.rewardSharePublicKey);
} catch (DataException e) {
return 0;
}
}
public boolean getIsMember() {
try (final Repository repository = RepositoryManager.getRepository()) {
return repository.getGroupRepository().memberExists(694, getMinterAddress());
} catch (DataException e) {
return false;
}
}
// JAXB special
@XmlElement(name = "minterLevel")
protected int getMinterLevel() {
return getMinterLevelFromPublicKey();
}
@XmlElement(name = "isMinterMember")
protected boolean getMinterMember() {
return getIsMember();
}
} }

View File

@ -9,6 +9,7 @@ import java.math.BigInteger;
public class BlockMintingInfo { public class BlockMintingInfo {
public byte[] minterPublicKey; public byte[] minterPublicKey;
public String minterAddress;
public int minterLevel; public int minterLevel;
public int onlineAccountsCount; public int onlineAccountsCount;
public BigDecimal maxDistance; public BigDecimal maxDistance;
@ -19,5 +20,4 @@ public class BlockMintingInfo {
public BlockMintingInfo() { public BlockMintingInfo() {
} }
} }

View File

@ -542,6 +542,7 @@ public class BlocksResource {
} }
} }
String minterAddress = Account.getRewardShareMintingAddress(repository, blockData.getMinterPublicKey());
int minterLevel = Account.getRewardShareEffectiveMintingLevel(repository, blockData.getMinterPublicKey()); int minterLevel = Account.getRewardShareEffectiveMintingLevel(repository, blockData.getMinterPublicKey());
if (minterLevel == 0) if (minterLevel == 0)
// This may be unavailable when requesting a trimmed block // This may be unavailable when requesting a trimmed block
@ -554,6 +555,7 @@ public class BlocksResource {
BlockMintingInfo blockMintingInfo = new BlockMintingInfo(); BlockMintingInfo blockMintingInfo = new BlockMintingInfo();
blockMintingInfo.minterPublicKey = blockData.getMinterPublicKey(); blockMintingInfo.minterPublicKey = blockData.getMinterPublicKey();
blockMintingInfo.minterAddress = minterAddress;
blockMintingInfo.minterLevel = minterLevel; blockMintingInfo.minterLevel = minterLevel;
blockMintingInfo.onlineAccountsCount = blockData.getOnlineAccountsCount(); blockMintingInfo.onlineAccountsCount = blockData.getOnlineAccountsCount();
blockMintingInfo.maxDistance = new BigDecimal(block.MAX_DISTANCE); blockMintingInfo.maxDistance = new BigDecimal(block.MAX_DISTANCE);
@ -887,5 +889,4 @@ public class BlocksResource {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
} }
} }
} }

View File

@ -145,7 +145,7 @@ public class Block {
private final Account recipientAccount; private final Account recipientAccount;
private final AccountData recipientAccountData; private final AccountData recipientAccountData;
final BlockChain blockChain = BlockChain.getInstance(); final BlockChain blockChain = BlockChain.getInstance();
ExpandedAccount(Repository repository, RewardShareData rewardShareData) throws DataException { ExpandedAccount(Repository repository, RewardShareData rewardShareData) throws DataException {
@ -414,6 +414,21 @@ public class Block {
}); });
} }
// After feature trigger, remove any online accounts that are not minter group member
if (height >= BlockChain.getInstance().getGroupMemberCheckHeight()) {
onlineAccounts.removeIf(a -> {
try {
int groupId = BlockChain.getInstance().getMintingGroupId();
String address = Account.getRewardShareMintingAddress(repository, a.getPublicKey());
boolean isMinterGroupMember = repository.getGroupRepository().memberExists(groupId, address);
return !isMinterGroupMember;
} catch (DataException e) {
// Something went wrong, so remove the account
return true;
}
});
}
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;
@ -721,19 +736,19 @@ public class Block {
List<ExpandedAccount> expandedAccounts = new ArrayList<>(); List<ExpandedAccount> expandedAccounts = new ArrayList<>();
for (RewardShareData rewardShare : this.cachedOnlineRewardShares) { for (RewardShareData rewardShare : this.cachedOnlineRewardShares) {
if (this.getBlockData().getHeight() < BlockChain.getInstance().getFixBatchRewardHeight()) { int groupId = BlockChain.getInstance().getMintingGroupId();
String address = rewardShare.getMinter();
boolean isMinterGroupMember = repository.getGroupRepository().memberExists(groupId, address);
if (this.getBlockData().getHeight() < BlockChain.getInstance().getFixBatchRewardHeight())
expandedAccounts.add(new ExpandedAccount(repository, rewardShare));
if (this.getBlockData().getHeight() >= BlockChain.getInstance().getFixBatchRewardHeight() && isMinterGroupMember)
expandedAccounts.add(new ExpandedAccount(repository, rewardShare)); expandedAccounts.add(new ExpandedAccount(repository, rewardShare));
}
if (this.getBlockData().getHeight() >= BlockChain.getInstance().getFixBatchRewardHeight()) {
boolean isMinterGroupMember = repository.getGroupRepository().memberExists(BlockChain.getInstance().getMintingGroupId(), rewardShare.getMinter());
if (isMinterGroupMember) {
expandedAccounts.add(new ExpandedAccount(repository, rewardShare));
}
}
} }
this.cachedExpandedAccounts = expandedAccounts; this.cachedExpandedAccounts = expandedAccounts;
LOGGER.trace(() -> String.format("Online reward-shares after expanded accounts %s", this.cachedOnlineRewardShares));
return this.cachedExpandedAccounts; return this.cachedExpandedAccounts;
} }
@ -1143,8 +1158,17 @@ public class Block {
if (this.getBlockData().getHeight() >= BlockChain.getInstance().getOnlineAccountMinterLevelValidationHeight()) { if (this.getBlockData().getHeight() >= BlockChain.getInstance().getOnlineAccountMinterLevelValidationHeight()) {
List<ExpandedAccount> expandedAccounts = this.getExpandedAccounts(); List<ExpandedAccount> expandedAccounts = this.getExpandedAccounts();
for (ExpandedAccount account : expandedAccounts) { for (ExpandedAccount account : expandedAccounts) {
int groupId = BlockChain.getInstance().getMintingGroupId();
String address = account.getMintingAccount().getAddress();
boolean isMinterGroupMember = repository.getGroupRepository().memberExists(groupId, address);
if (account.getMintingAccount().getEffectiveMintingLevel() == 0) if (account.getMintingAccount().getEffectiveMintingLevel() == 0)
return ValidationResult.ONLINE_ACCOUNTS_INVALID; return ValidationResult.ONLINE_ACCOUNTS_INVALID;
if (this.getBlockData().getHeight() >= BlockChain.getInstance().getFixBatchRewardHeight()) {
if (!isMinterGroupMember)
return ValidationResult.ONLINE_ACCOUNTS_INVALID;
}
} }
} }
@ -1273,6 +1297,7 @@ public class Block {
// Online Accounts // Online Accounts
ValidationResult onlineAccountsResult = this.areOnlineAccountsValid(); ValidationResult onlineAccountsResult = this.areOnlineAccountsValid();
LOGGER.trace("Accounts valid = {}", onlineAccountsResult);
if (onlineAccountsResult != ValidationResult.OK) if (onlineAccountsResult != ValidationResult.OK)
return onlineAccountsResult; return onlineAccountsResult;
@ -1361,7 +1386,7 @@ public class Block {
// Check transaction can even be processed // Check transaction can even be processed
validationResult = transaction.isProcessable(); validationResult = transaction.isProcessable();
if (validationResult != Transaction.ValidationResult.OK) { if (validationResult != Transaction.ValidationResult.OK) {
LOGGER.info(String.format("Error during transaction validation, tx %s: %s", Base58.encode(transactionData.getSignature()), validationResult.name())); LOGGER.debug(String.format("Error during transaction validation, tx %s: %s", Base58.encode(transactionData.getSignature()), validationResult.name()));
return ValidationResult.TRANSACTION_INVALID; return ValidationResult.TRANSACTION_INVALID;
} }
@ -1562,6 +1587,7 @@ public class Block {
this.blockData.setHeight(blockchainHeight + 1); this.blockData.setHeight(blockchainHeight + 1);
LOGGER.trace(() -> String.format("Processing block %d", this.blockData.getHeight())); LOGGER.trace(() -> String.format("Processing block %d", this.blockData.getHeight()));
LOGGER.trace(() -> String.format("Online Reward Shares in process %s", this.cachedOnlineRewardShares));
if (this.blockData.getHeight() > 1) { if (this.blockData.getHeight() > 1) {
@ -2280,7 +2306,6 @@ public class Block {
// Select the correct set of share bins based on block height // Select the correct set of share bins based on block height
List<AccountLevelShareBin> accountLevelShareBinsForBlock = (this.blockData.getHeight() >= BlockChain.getInstance().getSharesByLevelV2Height()) ? List<AccountLevelShareBin> accountLevelShareBinsForBlock = (this.blockData.getHeight() >= BlockChain.getInstance().getSharesByLevelV2Height()) ?
BlockChain.getInstance().getAccountLevelShareBinsV2() : BlockChain.getInstance().getAccountLevelShareBinsV1(); BlockChain.getInstance().getAccountLevelShareBinsV2() : BlockChain.getInstance().getAccountLevelShareBinsV1();
// Determine reward candidates based on account level // Determine reward candidates based on account level
// This needs a deep copy, so the shares can be modified when tiers aren't activated yet // This needs a deep copy, so the shares can be modified when tiers aren't activated yet
List<AccountLevelShareBin> accountLevelShareBins = new ArrayList<>(); List<AccountLevelShareBin> accountLevelShareBins = new ArrayList<>();
@ -2570,9 +2595,11 @@ public class Block {
return; return;
int minterLevel = Account.getRewardShareEffectiveMintingLevel(this.repository, this.getMinter().getPublicKey()); int minterLevel = Account.getRewardShareEffectiveMintingLevel(this.repository, this.getMinter().getPublicKey());
String minterAddress = Account.getRewardShareMintingAddress(this.repository, this.getMinter().getPublicKey());
LOGGER.debug(String.format("======= BLOCK %d (%.8s) =======", this.getBlockData().getHeight(), Base58.encode(this.getSignature()))); LOGGER.debug(String.format("======= BLOCK %d (%.8s) =======", this.getBlockData().getHeight(), Base58.encode(this.getSignature())));
LOGGER.debug(String.format("Timestamp: %d", this.getBlockData().getTimestamp())); LOGGER.debug(String.format("Timestamp: %d", this.getBlockData().getTimestamp()));
LOGGER.debug(String.format("Minter address: %s", minterAddress));
LOGGER.debug(String.format("Minter level: %d", minterLevel)); LOGGER.debug(String.format("Minter level: %d", minterLevel));
LOGGER.debug(String.format("Online accounts: %d", this.getBlockData().getOnlineAccountsCount())); LOGGER.debug(String.format("Online accounts: %d", this.getBlockData().getOnlineAccountsCount()));
LOGGER.debug(String.format("AT count: %d", this.getBlockData().getATCount())); LOGGER.debug(String.format("AT count: %d", this.getBlockData().getATCount()));

View File

@ -1,8 +1,11 @@
package org.qortal.data.block; package org.qortal.data.block;
import com.google.common.primitives.Bytes; import com.google.common.primitives.Bytes;
import org.qortal.account.Account;
import org.qortal.block.BlockChain; import org.qortal.block.BlockChain;
import org.qortal.crypto.Crypto; import org.qortal.repository.DataException;
import org.qortal.repository.Repository;
import org.qortal.repository.RepositoryManager;
import org.qortal.settings.Settings; import org.qortal.settings.Settings;
import org.qortal.utils.NTP; import org.qortal.utils.NTP;
@ -224,7 +227,7 @@ public class BlockData implements Serializable {
} }
return 0; return 0;
} }
public boolean isTrimmed() { public boolean isTrimmed() {
long onlineAccountSignaturesTrimmedTimestamp = NTP.getTime() - BlockChain.getInstance().getOnlineAccountSignaturesMaxLifetime(); long onlineAccountSignaturesTrimmedTimestamp = NTP.getTime() - BlockChain.getInstance().getOnlineAccountSignaturesMaxLifetime();
long currentTrimmableTimestamp = NTP.getTime() - Settings.getInstance().getAtStatesMaxLifetime(); long currentTrimmableTimestamp = NTP.getTime() - Settings.getInstance().getAtStatesMaxLifetime();
@ -232,11 +235,31 @@ public class BlockData implements Serializable {
return blockTimestamp < onlineAccountSignaturesTrimmedTimestamp && blockTimestamp < currentTrimmableTimestamp; return blockTimestamp < onlineAccountSignaturesTrimmedTimestamp && blockTimestamp < currentTrimmableTimestamp;
} }
public String getMinterAddressFromPublicKey() {
try (final Repository repository = RepositoryManager.getRepository()) {
return Account.getRewardShareMintingAddress(repository, this.minterPublicKey);
} catch (DataException e) {
return "Unknown";
}
}
public int getMinterLevelFromPublicKey() {
try (final Repository repository = RepositoryManager.getRepository()) {
return Account.getRewardShareEffectiveMintingLevel(repository, this.minterPublicKey);
} catch (DataException e) {
return 0;
}
}
// JAXB special // JAXB special
@XmlElement(name = "minterAddress") @XmlElement(name = "minterAddress")
protected String getMinterAddress() { protected String getMinterAddress() {
return Crypto.toAddress(this.minterPublicKey); return getMinterAddressFromPublicKey();
} }
@XmlElement(name = "minterLevel")
protected int getMinterLevel() {
return getMinterLevelFromPublicKey();
}
} }

View File

@ -54,26 +54,39 @@ public class BlockArchiveV1Tests extends Common {
public void testWriter() throws DataException, InterruptedException, TransformationException, IOException { public void testWriter() throws DataException, InterruptedException, TransformationException, IOException {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
System.out.println("Starting testWriter");
// Mint some blocks so that we are able to archive them later // Mint some blocks so that we are able to archive them later
System.out.println("Minting 1000 blocks...");
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share")); BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
// Log every 100 blocks
if ((i + 1) % 100 == 0) {
System.out.println("Minted block " + (i + 1));
}
} }
System.out.println("Finished minting blocks.");
// 900 blocks are trimmed (this specifies the first untrimmed height) // 900 blocks are trimmed (this specifies the first untrimmed height)
repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(901); repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(901);
repository.getATRepository().setAtTrimHeight(901); repository.getATRepository().setAtTrimHeight(901);
System.out.println("Set trim heights to 901.");
// Check the max archive height - this should be one less than the first untrimmed height // Check the max archive height - this should be one less than the first untrimmed height
final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository); final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository);
System.out.println("Maximum archive height (Expected 900): " + maximumArchiveHeight);
assertEquals(900, maximumArchiveHeight); assertEquals(900, maximumArchiveHeight);
// Write blocks 2-900 to the archive // Write blocks 2-900 to the archive
System.out.println("Writing blocks 2 to " + maximumArchiveHeight + " to the archive...");
BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository); BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository);
writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes
BlockArchiveWriter.BlockArchiveWriteResult result = writer.write(); BlockArchiveWriter.BlockArchiveWriteResult result = writer.write();
System.out.println("Finished writing blocks to archive. Result: " + result);
assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result); assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result);
// Make sure that the archive contains the correct number of blocks // Make sure that the archive contains the correct number of blocks
System.out.println("Archive contains " + writer.getWrittenCount() + " blocks. (Expected 899)");
assertEquals(900 - 1, writer.getWrittenCount()); assertEquals(900 - 1, writer.getWrittenCount());
// Increment block archive height // Increment block archive height
@ -84,6 +97,9 @@ public class BlockArchiveV1Tests extends Common {
// Ensure the file exists // Ensure the file exists
File outputFile = writer.getOutputPath().toFile(); File outputFile = writer.getOutputPath().toFile();
assertTrue(outputFile.exists()); assertTrue(outputFile.exists());
System.out.println("Archive file exists at: " + outputFile.getAbsolutePath());
System.out.println("testWriter completed successfully.");
} }
} }
@ -91,26 +107,39 @@ public class BlockArchiveV1Tests extends Common {
public void testWriterAndReader() throws DataException, InterruptedException, TransformationException, IOException { public void testWriterAndReader() throws DataException, InterruptedException, TransformationException, IOException {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
System.out.println("Starting testWriterAndReader");
// Mint some blocks so that we are able to archive them later // Mint some blocks so that we are able to archive them later
System.out.println("Minting 1000 blocks...");
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share")); BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
// Log every 100 blocks
if ((i + 1) % 100 == 0) {
System.out.println("Minted block " + (i + 1));
}
} }
System.out.println("Finished minting blocks.");
// 900 blocks are trimmed (this specifies the first untrimmed height) // 900 blocks are trimmed (this specifies the first untrimmed height)
repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(901); repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(901);
repository.getATRepository().setAtTrimHeight(901); repository.getATRepository().setAtTrimHeight(901);
System.out.println("Set trim heights to 901.");
// Check the max archive height - this should be one less than the first untrimmed height // Check the max archive height - this should be one less than the first untrimmed height
final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository); final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository);
System.out.println("Maximum archive height (Expected 900): " + maximumArchiveHeight);
assertEquals(900, maximumArchiveHeight); assertEquals(900, maximumArchiveHeight);
// Write blocks 2-900 to the archive // Write blocks 2-900 to the archive
System.out.println("Writing blocks 2 to " + maximumArchiveHeight + " to the archive...");
BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository); BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository);
writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes
BlockArchiveWriter.BlockArchiveWriteResult result = writer.write(); BlockArchiveWriter.BlockArchiveWriteResult result = writer.write();
System.out.println("Finished writing blocks to archive. Result: " + result);
assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result); assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result);
// Make sure that the archive contains the correct number of blocks // Make sure that the archive contains the correct number of blocks
System.out.println("Archive contains " + writer.getWrittenCount() + " blocks. (Expected 899)");
assertEquals(900 - 1, writer.getWrittenCount()); assertEquals(900 - 1, writer.getWrittenCount());
// Increment block archive height // Increment block archive height
@ -121,8 +150,10 @@ public class BlockArchiveV1Tests extends Common {
// Ensure the file exists // Ensure the file exists
File outputFile = writer.getOutputPath().toFile(); File outputFile = writer.getOutputPath().toFile();
assertTrue(outputFile.exists()); assertTrue(outputFile.exists());
System.out.println("Archive file exists at: " + outputFile.getAbsolutePath());
// Read block 2 from the archive // Read block 2 from the archive
System.out.println("Reading block 2 from the archive...");
BlockArchiveReader reader = BlockArchiveReader.getInstance(); BlockArchiveReader reader = BlockArchiveReader.getInstance();
BlockTransformation block2Info = reader.fetchBlockAtHeight(2); BlockTransformation block2Info = reader.fetchBlockAtHeight(2);
BlockData block2ArchiveData = block2Info.getBlockData(); BlockData block2ArchiveData = block2Info.getBlockData();
@ -131,6 +162,7 @@ public class BlockArchiveV1Tests extends Common {
BlockData block2RepositoryData = repository.getBlockRepository().fromHeight(2); BlockData block2RepositoryData = repository.getBlockRepository().fromHeight(2);
// Ensure the values match // Ensure the values match
System.out.println("Comparing block 2 data...");
assertEquals(block2ArchiveData.getHeight(), block2RepositoryData.getHeight()); assertEquals(block2ArchiveData.getHeight(), block2RepositoryData.getHeight());
assertArrayEquals(block2ArchiveData.getSignature(), block2RepositoryData.getSignature()); assertArrayEquals(block2ArchiveData.getSignature(), block2RepositoryData.getSignature());
@ -138,6 +170,7 @@ public class BlockArchiveV1Tests extends Common {
assertEquals(1, block2ArchiveData.getOnlineAccountsCount()); assertEquals(1, block2ArchiveData.getOnlineAccountsCount());
// Read block 900 from the archive // Read block 900 from the archive
System.out.println("Reading block 900 from the archive...");
BlockTransformation block900Info = reader.fetchBlockAtHeight(900); BlockTransformation block900Info = reader.fetchBlockAtHeight(900);
BlockData block900ArchiveData = block900Info.getBlockData(); BlockData block900ArchiveData = block900Info.getBlockData();
@ -145,12 +178,14 @@ public class BlockArchiveV1Tests extends Common {
BlockData block900RepositoryData = repository.getBlockRepository().fromHeight(900); BlockData block900RepositoryData = repository.getBlockRepository().fromHeight(900);
// Ensure the values match // Ensure the values match
System.out.println("Comparing block 900 data...");
assertEquals(block900ArchiveData.getHeight(), block900RepositoryData.getHeight()); assertEquals(block900ArchiveData.getHeight(), block900RepositoryData.getHeight());
assertArrayEquals(block900ArchiveData.getSignature(), block900RepositoryData.getSignature()); assertArrayEquals(block900ArchiveData.getSignature(), block900RepositoryData.getSignature());
// Test some values in the archive // Test some values in the archive
assertEquals(1, block900ArchiveData.getOnlineAccountsCount()); assertEquals(1, block900ArchiveData.getOnlineAccountsCount());
System.out.println("testWriterAndReader completed successfully.");
} }
} }
@ -158,33 +193,48 @@ public class BlockArchiveV1Tests extends Common {
public void testArchivedAtStates() throws DataException, InterruptedException, TransformationException, IOException { public void testArchivedAtStates() throws DataException, InterruptedException, TransformationException, IOException {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
System.out.println("Starting testArchivedAtStates");
// Deploy an AT so that we have AT state data // Deploy an AT so that we have AT state data
System.out.println("Deploying AT...");
PrivateKeyAccount deployer = Common.getTestAccount(repository, "alice"); PrivateKeyAccount deployer = Common.getTestAccount(repository, "alice");
byte[] creationBytes = AtUtils.buildSimpleAT(); byte[] creationBytes = AtUtils.buildSimpleAT();
long fundingAmount = 1_00000000L; long fundingAmount = 1_00000000L;
DeployAtTransaction deployAtTransaction = AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount); DeployAtTransaction deployAtTransaction = AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount);
String atAddress = deployAtTransaction.getATAccount().getAddress(); String atAddress = deployAtTransaction.getATAccount().getAddress();
System.out.println("AT deployed at address: " + atAddress);
// Mint some blocks so that we are able to archive them later // Mint some blocks so that we are able to archive them later
System.out.println("Minting 1000 blocks...");
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share")); BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
// Log every 100 blocks
if ((i + 1) % 100 == 0) {
System.out.println("Minted block " + (i + 1));
}
} }
System.out.println("Finished minting blocks.");
// 9 blocks are trimmed (this specifies the first untrimmed height) // 9 blocks are trimmed (this specifies the first untrimmed height)
repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(10); repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(10);
repository.getATRepository().setAtTrimHeight(10); repository.getATRepository().setAtTrimHeight(10);
System.out.println("Set trim heights to 10.");
// Check the max archive height // Check the max archive height
final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository); final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository);
System.out.println("Maximum archive height (Expected 9): " + maximumArchiveHeight);
assertEquals(9, maximumArchiveHeight); assertEquals(9, maximumArchiveHeight);
// Write blocks 2-9 to the archive // Write blocks 2-9 to the archive
System.out.println("Writing blocks 2 to " + maximumArchiveHeight + " to the archive...");
BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository); BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository);
writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes
BlockArchiveWriter.BlockArchiveWriteResult result = writer.write(); BlockArchiveWriter.BlockArchiveWriteResult result = writer.write();
System.out.println("Finished writing blocks to archive. Result: " + result);
assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result); assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result);
// Make sure that the archive contains the correct number of blocks // Make sure that the archive contains the correct number of blocks
System.out.println("Archive contains " + writer.getWrittenCount() + " blocks. (Expected 8)");
assertEquals(9 - 1, writer.getWrittenCount()); assertEquals(9 - 1, writer.getWrittenCount());
// Increment block archive height // Increment block archive height
@ -195,10 +245,13 @@ public class BlockArchiveV1Tests extends Common {
// Ensure the file exists // Ensure the file exists
File outputFile = writer.getOutputPath().toFile(); File outputFile = writer.getOutputPath().toFile();
assertTrue(outputFile.exists()); assertTrue(outputFile.exists());
System.out.println("Archive file exists at: " + outputFile.getAbsolutePath());
// Check blocks 3-9 // Check blocks 3-9
System.out.println("Checking blocks 3 to 9...");
for (Integer testHeight = 2; testHeight <= 9; testHeight++) { for (Integer testHeight = 2; testHeight <= 9; testHeight++) {
System.out.println("Reading block " + testHeight + " from the archive...");
// Read a block from the archive // Read a block from the archive
BlockArchiveReader reader = BlockArchiveReader.getInstance(); BlockArchiveReader reader = BlockArchiveReader.getInstance();
BlockTransformation blockInfo = reader.fetchBlockAtHeight(testHeight); BlockTransformation blockInfo = reader.fetchBlockAtHeight(testHeight);
@ -216,6 +269,7 @@ public class BlockArchiveV1Tests extends Common {
// Check the archived AT state // Check the archived AT state
if (testHeight == 2) { if (testHeight == 2) {
System.out.println("Checking block " + testHeight + " AT state data (expected null)...");
// Block 2 won't have an AT state hash because it's initial (and has the DEPLOY_AT in the same block) // Block 2 won't have an AT state hash because it's initial (and has the DEPLOY_AT in the same block)
assertNull(archivedAtStateData); assertNull(archivedAtStateData);
@ -223,6 +277,7 @@ public class BlockArchiveV1Tests extends Common {
assertEquals(Transaction.TransactionType.DEPLOY_AT, archivedTransactions.get(0).getType()); assertEquals(Transaction.TransactionType.DEPLOY_AT, archivedTransactions.get(0).getType());
} }
else { else {
System.out.println("Checking block " + testHeight + " AT state data...");
// For blocks 3+, ensure the archive has the AT state data, but not the hashes // For blocks 3+, ensure the archive has the AT state data, but not the hashes
assertNotNull(archivedAtStateData.getStateHash()); assertNotNull(archivedAtStateData.getStateHash());
assertNull(archivedAtStateData.getStateData()); assertNull(archivedAtStateData.getStateData());
@ -255,10 +310,12 @@ public class BlockArchiveV1Tests extends Common {
} }
// Check block 10 (unarchived) // Check block 10 (unarchived)
System.out.println("Checking block 10 (should not be in archive)...");
BlockArchiveReader reader = BlockArchiveReader.getInstance(); BlockArchiveReader reader = BlockArchiveReader.getInstance();
BlockTransformation blockInfo = reader.fetchBlockAtHeight(10); BlockTransformation blockInfo = reader.fetchBlockAtHeight(10);
assertNull(blockInfo); assertNull(blockInfo);
System.out.println("testArchivedAtStates completed successfully.");
} }
} }
@ -267,32 +324,46 @@ public class BlockArchiveV1Tests extends Common {
public void testArchiveAndPrune() throws DataException, InterruptedException, TransformationException, IOException { public void testArchiveAndPrune() throws DataException, InterruptedException, TransformationException, IOException {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
System.out.println("Starting testArchiveAndPrune");
// Deploy an AT so that we have AT state data // Deploy an AT so that we have AT state data
System.out.println("Deploying AT...");
PrivateKeyAccount deployer = Common.getTestAccount(repository, "alice"); PrivateKeyAccount deployer = Common.getTestAccount(repository, "alice");
byte[] creationBytes = AtUtils.buildSimpleAT(); byte[] creationBytes = AtUtils.buildSimpleAT();
long fundingAmount = 1_00000000L; long fundingAmount = 1_00000000L;
AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount); AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount);
// Mint some blocks so that we are able to archive them later // Mint some blocks so that we are able to archive them later
System.out.println("Minting 1000 blocks...");
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share")); BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
// Log every 100 blocks
if ((i + 1) % 100 == 0) {
System.out.println("Minted block " + (i + 1));
}
} }
System.out.println("Finished minting blocks.");
// Assume 900 blocks are trimmed (this specifies the first untrimmed height) // Assume 900 blocks are trimmed (this specifies the first untrimmed height)
repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(901); repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(901);
repository.getATRepository().setAtTrimHeight(901); repository.getATRepository().setAtTrimHeight(901);
System.out.println("Set trim heights to 901.");
// Check the max archive height - this should be one less than the first untrimmed height // Check the max archive height - this should be one less than the first untrimmed height
final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository); final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository);
System.out.println("Maximum archive height (Expected 900): " + maximumArchiveHeight);
assertEquals(900, maximumArchiveHeight); assertEquals(900, maximumArchiveHeight);
// Write blocks 2-900 to the archive // Write blocks 2-900 to the archive
System.out.println("Writing blocks 2 to " + maximumArchiveHeight + " to the archive...");
BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository); BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository);
writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes
BlockArchiveWriter.BlockArchiveWriteResult result = writer.write(); BlockArchiveWriter.BlockArchiveWriteResult result = writer.write();
System.out.println("Finished writing blocks to archive. Result: " + result);
assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result); assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result);
// Make sure that the archive contains the correct number of blocks // Make sure that the archive contains the correct number of blocks
System.out.println("Archive contains " + writer.getWrittenCount() + " blocks. (Expected 899)");
assertEquals(900 - 1, writer.getWrittenCount()); assertEquals(900 - 1, writer.getWrittenCount());
// Increment block archive height // Increment block archive height
@ -303,17 +374,21 @@ public class BlockArchiveV1Tests extends Common {
// Ensure the file exists // Ensure the file exists
File outputFile = writer.getOutputPath().toFile(); File outputFile = writer.getOutputPath().toFile();
assertTrue(outputFile.exists()); assertTrue(outputFile.exists());
System.out.println("Archive file exists at: " + outputFile.getAbsolutePath());
// Ensure the SQL repository contains blocks 2 and 900... // Ensure the SQL repository contains blocks 2 and 900...
assertNotNull(repository.getBlockRepository().fromHeight(2)); assertNotNull(repository.getBlockRepository().fromHeight(2));
assertNotNull(repository.getBlockRepository().fromHeight(900)); assertNotNull(repository.getBlockRepository().fromHeight(900));
System.out.println("Blocks 2 and 900 exist in the repository.");
// Prune all the archived blocks // Prune all the archived blocks
System.out.println("Pruning blocks 2 to 900...");
int numBlocksPruned = repository.getBlockRepository().pruneBlocks(0, 900); int numBlocksPruned = repository.getBlockRepository().pruneBlocks(0, 900);
assertEquals(900-1, numBlocksPruned); assertEquals(900-1, numBlocksPruned);
repository.getBlockRepository().setBlockPruneHeight(901); repository.getBlockRepository().setBlockPruneHeight(901);
// Prune the AT states for the archived blocks // Prune the AT states for the archived blocks
System.out.println("Pruning AT states up to height 900...");
repository.getATRepository().rebuildLatestAtStates(900); repository.getATRepository().rebuildLatestAtStates(900);
repository.saveChanges(); repository.saveChanges();
int numATStatesPruned = repository.getATRepository().pruneAtStates(0, 900); int numATStatesPruned = repository.getATRepository().pruneAtStates(0, 900);
@ -323,14 +398,19 @@ public class BlockArchiveV1Tests extends Common {
// Now ensure the SQL repository is missing blocks 2 and 900... // Now ensure the SQL repository is missing blocks 2 and 900...
assertNull(repository.getBlockRepository().fromHeight(2)); assertNull(repository.getBlockRepository().fromHeight(2));
assertNull(repository.getBlockRepository().fromHeight(900)); assertNull(repository.getBlockRepository().fromHeight(900));
System.out.println("Blocks 2 and 900 have been pruned from the repository.");
// ... but it's not missing blocks 1 and 901 (we don't prune the genesis block) // ... but it's not missing blocks 1 and 901 (we don't prune the genesis block)
assertNotNull(repository.getBlockRepository().fromHeight(1)); assertNotNull(repository.getBlockRepository().fromHeight(1));
assertNotNull(repository.getBlockRepository().fromHeight(901)); assertNotNull(repository.getBlockRepository().fromHeight(901));
System.out.println("Blocks 1 and 901 still exist in the repository.");
// Validate the latest block height in the repository // Validate the latest block height in the repository
assertEquals(1002, (int) repository.getBlockRepository().getLastBlock().getHeight()); int lastBlockHeight = repository.getBlockRepository().getLastBlock().getHeight();
System.out.println("Latest block height in repository (Expected 1002): " + lastBlockHeight);
assertEquals(1002, lastBlockHeight);
System.out.println("testArchiveAndPrune completed successfully.");
} }
} }
@ -338,137 +418,190 @@ public class BlockArchiveV1Tests extends Common {
public void testTrimArchivePruneAndOrphan() throws DataException, InterruptedException, TransformationException, IOException { public void testTrimArchivePruneAndOrphan() throws DataException, InterruptedException, TransformationException, IOException {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
System.out.println("Starting testTrimArchivePruneAndOrphan");
// Deploy an AT so that we have AT state data // Deploy an AT so that we have AT state data
System.out.println("Deploying AT...");
PrivateKeyAccount deployer = Common.getTestAccount(repository, "alice"); PrivateKeyAccount deployer = Common.getTestAccount(repository, "alice");
byte[] creationBytes = AtUtils.buildSimpleAT(); byte[] creationBytes = AtUtils.buildSimpleAT();
long fundingAmount = 1_00000000L; long fundingAmount = 1_00000000L;
AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount); AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount);
System.out.println("AT deployed successfully.");
// Mint some blocks so that we are able to archive them later // Mint some blocks so that we are able to archive them later
System.out.println("Minting 1000 blocks...");
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share")); BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
// Log every 100 blocks
if ((i + 1) % 100 == 0) {
System.out.println("Minted block " + (i + 1));
}
} }
System.out.println("Finished minting blocks.");
// Make sure that block 500 has full AT state data and data hash // Make sure that block 500 has full AT state data and data hash
System.out.println("Verifying block 500 AT state data...");
List<ATStateData> block500AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(500); List<ATStateData> block500AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(500);
ATStateData atStatesData = repository.getATRepository().getATStateAtHeight(block500AtStatesData.get(0).getATAddress(), 500); ATStateData atStatesData = repository.getATRepository().getATStateAtHeight(block500AtStatesData.get(0).getATAddress(), 500);
assertNotNull(atStatesData.getStateHash()); assertNotNull(atStatesData.getStateHash());
assertNotNull(atStatesData.getStateData()); assertNotNull(atStatesData.getStateData());
System.out.println("Block 500 AT state data verified.");
// Trim the first 500 blocks // Trim the first 500 blocks
System.out.println("Trimming first 500 blocks...");
repository.getBlockRepository().trimOldOnlineAccountsSignatures(0, 500); repository.getBlockRepository().trimOldOnlineAccountsSignatures(0, 500);
repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(501); repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(501);
repository.getATRepository().rebuildLatestAtStates(500); repository.getATRepository().rebuildLatestAtStates(500);
repository.getATRepository().trimAtStates(0, 500, 1000); repository.getATRepository().trimAtStates(0, 500, 1000);
repository.getATRepository().setAtTrimHeight(501); repository.getATRepository().setAtTrimHeight(501);
System.out.println("Trimming completed.");
// Now block 499 should only have the AT state data hash // Now block 499 should only have the AT state data hash
System.out.println("Checking block 499 AT state data...");
List<ATStateData> block499AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(499); List<ATStateData> block499AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(499);
atStatesData = repository.getATRepository().getATStateAtHeight(block499AtStatesData.get(0).getATAddress(), 499); atStatesData = repository.getATRepository().getATStateAtHeight(block499AtStatesData.get(0).getATAddress(), 499);
assertNotNull(atStatesData.getStateHash()); assertNotNull(atStatesData.getStateHash());
assertNull(atStatesData.getStateData()); assertNull(atStatesData.getStateData());
System.out.println("Block 499 AT state data contains only state hash as expected.");
// ... but block 500 should have the full data (due to being retained as the "latest" AT state in the trimmed range // ... but block 500 should have the full data (due to being retained as the "latest" AT state in the trimmed range
System.out.println("Verifying block 500 AT state data again...");
block500AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(500); block500AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(500);
atStatesData = repository.getATRepository().getATStateAtHeight(block500AtStatesData.get(0).getATAddress(), 500); atStatesData = repository.getATRepository().getATStateAtHeight(block500AtStatesData.get(0).getATAddress(), 500);
assertNotNull(atStatesData.getStateHash()); assertNotNull(atStatesData.getStateHash());
assertNotNull(atStatesData.getStateData()); assertNotNull(atStatesData.getStateData());
System.out.println("Block 500 AT state data contains full data.");
// ... and block 501 should also have the full data // ... and block 501 should also have the full data
System.out.println("Verifying block 501 AT state data...");
List<ATStateData> block501AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(501); List<ATStateData> block501AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(501);
atStatesData = repository.getATRepository().getATStateAtHeight(block501AtStatesData.get(0).getATAddress(), 501); atStatesData = repository.getATRepository().getATStateAtHeight(block501AtStatesData.get(0).getATAddress(), 501);
assertNotNull(atStatesData.getStateHash()); assertNotNull(atStatesData.getStateHash());
assertNotNull(atStatesData.getStateData()); assertNotNull(atStatesData.getStateData());
System.out.println("Block 501 AT state data contains full data.");
// Check the max archive height - this should be one less than the first untrimmed height // Check the max archive height - this should be one less than the first untrimmed height
final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository); final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository);
System.out.println("Maximum archive height determined (Expected 500): " + maximumArchiveHeight);
assertEquals(500, maximumArchiveHeight); assertEquals(500, maximumArchiveHeight);
BlockData block3DataPreArchive = repository.getBlockRepository().fromHeight(3); BlockData block3DataPreArchive = repository.getBlockRepository().fromHeight(3);
// Write blocks 2-500 to the archive // Write blocks 2-500 to the archive
System.out.println("Writing blocks 2 to " + maximumArchiveHeight + " to the archive...");
BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository); BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository);
writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes
BlockArchiveWriter.BlockArchiveWriteResult result = writer.write(); BlockArchiveWriter.BlockArchiveWriteResult result = writer.write();
System.out.println("Finished writing blocks to archive. Result: " + result);
assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result); assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result);
// Make sure that the archive contains the correct number of blocks // Make sure that the archive contains the correct number of blocks
System.out.println("Number of blocks written to archive (Expected 499): " + writer.getWrittenCount());
assertEquals(500 - 1, writer.getWrittenCount()); // -1 for the genesis block assertEquals(500 - 1, writer.getWrittenCount()); // -1 for the genesis block
// Increment block archive height // Increment block archive height
repository.getBlockArchiveRepository().setBlockArchiveHeight(writer.getWrittenCount()); repository.getBlockArchiveRepository().setBlockArchiveHeight(writer.getWrittenCount());
repository.saveChanges(); repository.saveChanges();
assertEquals(500 - 1, repository.getBlockArchiveRepository().getBlockArchiveHeight()); assertEquals(500 - 1, repository.getBlockArchiveRepository().getBlockArchiveHeight());
System.out.println("Block archive height updated to: " + (500 - 1));
// Ensure the file exists // Ensure the file exists
File outputFile = writer.getOutputPath().toFile(); File outputFile = writer.getOutputPath().toFile();
assertTrue(outputFile.exists()); assertTrue(outputFile.exists());
System.out.println("Archive file exists at: " + outputFile.getAbsolutePath());
// Ensure the SQL repository contains blocks 2 and 500... // Ensure the SQL repository contains blocks 2 and 500...
System.out.println("Verifying that blocks 2 and 500 exist in the repository...");
assertNotNull(repository.getBlockRepository().fromHeight(2)); assertNotNull(repository.getBlockRepository().fromHeight(2));
assertNotNull(repository.getBlockRepository().fromHeight(500)); assertNotNull(repository.getBlockRepository().fromHeight(500));
System.out.println("Blocks 2 and 500 are present in the repository.");
// Prune all the archived blocks // Prune all the archived blocks
System.out.println("Pruning blocks 2 to 500...");
int numBlocksPruned = repository.getBlockRepository().pruneBlocks(0, 500); int numBlocksPruned = repository.getBlockRepository().pruneBlocks(0, 500);
System.out.println("Number of blocks pruned (Expected 499): " + numBlocksPruned);
assertEquals(500-1, numBlocksPruned); assertEquals(500-1, numBlocksPruned);
repository.getBlockRepository().setBlockPruneHeight(501); repository.getBlockRepository().setBlockPruneHeight(501);
// Prune the AT states for the archived blocks // Prune the AT states for the archived blocks
System.out.println("Pruning AT states up to height 500...");
repository.getATRepository().rebuildLatestAtStates(500); repository.getATRepository().rebuildLatestAtStates(500);
repository.saveChanges(); repository.saveChanges();
int numATStatesPruned = repository.getATRepository().pruneAtStates(2, 500); int numATStatesPruned = repository.getATRepository().pruneAtStates(2, 500);
System.out.println("Number of AT states pruned (Expected 498): " + numATStatesPruned);
assertEquals(498, numATStatesPruned); // Minus 1 for genesis block, and another for the latest AT state assertEquals(498, numATStatesPruned); // Minus 1 for genesis block, and another for the latest AT state
repository.getATRepository().setAtPruneHeight(501); repository.getATRepository().setAtPruneHeight(501);
// Now ensure the SQL repository is missing blocks 2 and 500... // Now ensure the SQL repository is missing blocks 2 and 500...
System.out.println("Verifying that blocks 2 and 500 have been pruned...");
assertNull(repository.getBlockRepository().fromHeight(2)); assertNull(repository.getBlockRepository().fromHeight(2));
assertNull(repository.getBlockRepository().fromHeight(500)); assertNull(repository.getBlockRepository().fromHeight(500));
System.out.println("Blocks 2 and 500 have been successfully pruned.");
// ... but it's not missing blocks 1 and 501 (we don't prune the genesis block) // ... but it's not missing blocks 1 and 501 (we don't prune the genesis block)
System.out.println("Verifying that blocks 1 and 501 still exist...");
assertNotNull(repository.getBlockRepository().fromHeight(1)); assertNotNull(repository.getBlockRepository().fromHeight(1));
assertNotNull(repository.getBlockRepository().fromHeight(501)); assertNotNull(repository.getBlockRepository().fromHeight(501));
System.out.println("Blocks 1 and 501 are present in the repository.");
// Validate the latest block height in the repository // Validate the latest block height in the repository
assertEquals(1002, (int) repository.getBlockRepository().getLastBlock().getHeight()); int lastBlockHeight = repository.getBlockRepository().getLastBlock().getHeight();
System.out.println("Latest block height in repository (Expected 1002): " + lastBlockHeight);
assertEquals(1002, lastBlockHeight);
// Now orphan some unarchived blocks. // Now orphan some unarchived blocks.
System.out.println("Orphaning 500 blocks...");
BlockUtils.orphanBlocks(repository, 500); BlockUtils.orphanBlocks(repository, 500);
assertEquals(502, (int) repository.getBlockRepository().getLastBlock().getHeight()); int currentLastBlockHeight = repository.getBlockRepository().getLastBlock().getHeight();
System.out.println("New last block height after orphaning (Expected 502): " + currentLastBlockHeight);
assertEquals(502, currentLastBlockHeight);
// We're close to the lower limit of the SQL database now, so // We're close to the lower limit of the SQL database now, so
// we need to import some blocks from the archive // we need to import some blocks from the archive
System.out.println("Importing blocks 401 to 500 from the archive...");
BlockArchiveUtils.importFromArchive(401, 500, repository); BlockArchiveUtils.importFromArchive(401, 500, repository);
// Ensure the SQL repository now contains block 401 but not 400... // Ensure the SQL repository now contains block 401 but not 400...
System.out.println("Verifying that block 401 exists and block 400 does not...");
assertNotNull(repository.getBlockRepository().fromHeight(401)); assertNotNull(repository.getBlockRepository().fromHeight(401));
assertNull(repository.getBlockRepository().fromHeight(400)); assertNull(repository.getBlockRepository().fromHeight(400));
System.out.println("Block 401 exists, block 400 does not.");
// Import the remaining 399 blocks // Import the remaining 399 blocks
System.out.println("Importing blocks 2 to 400 from the archive...");
BlockArchiveUtils.importFromArchive(2, 400, repository); BlockArchiveUtils.importFromArchive(2, 400, repository);
// Verify that block 3 matches the original // Verify that block 3 matches the original
System.out.println("Verifying that block 3 matches the original data...");
BlockData block3DataPostArchive = repository.getBlockRepository().fromHeight(3); BlockData block3DataPostArchive = repository.getBlockRepository().fromHeight(3);
assertArrayEquals(block3DataPreArchive.getSignature(), block3DataPostArchive.getSignature()); assertArrayEquals(block3DataPreArchive.getSignature(), block3DataPostArchive.getSignature());
assertEquals(block3DataPreArchive.getHeight(), block3DataPostArchive.getHeight()); assertEquals(block3DataPreArchive.getHeight(), block3DataPostArchive.getHeight());
System.out.println("Block 3 data matches the original.");
// Orphan 1 more block, which should be the last one that is possible to be orphaned // Orphan 1 more block, which should be the last one that is possible to be orphaned
System.out.println("Orphaning 1 more block...");
BlockUtils.orphanBlocks(repository, 1); BlockUtils.orphanBlocks(repository, 1);
System.out.println("Orphaned 1 block successfully.");
// Orphan another block, which should fail // Orphan another block, which should fail
System.out.println("Attempting to orphan another block, which should fail...");
Exception exception = null; Exception exception = null;
try { try {
BlockUtils.orphanBlocks(repository, 1); BlockUtils.orphanBlocks(repository, 1);
} catch (DataException e) { } catch (DataException e) {
exception = e; exception = e;
System.out.println("Caught expected DataException: " + e.getMessage());
} }
// Ensure that a DataException is thrown because there is no more AT states data available // Ensure that a DataException is thrown because there is no more AT states data available
assertNotNull(exception); assertNotNull(exception);
assertEquals(DataException.class, exception.getClass()); assertEquals(DataException.class, exception.getClass());
System.out.println("DataException confirmed due to lack of AT states data.");
// FUTURE: we may be able to retain unique AT states when trimming, to avoid this exception // FUTURE: we may be able to retain unique AT states when trimming, to avoid this exception
// and allow orphaning back through blocks with trimmed AT states. // and allow orphaning back through blocks with trimmed AT states.
System.out.println("testTrimArchivePruneAndOrphan completed successfully.");
} }
} }
@ -482,16 +615,26 @@ public class BlockArchiveV1Tests extends Common {
public void testMissingAtStatesHeightIndex() throws DataException, SQLException { public void testMissingAtStatesHeightIndex() throws DataException, SQLException {
try (final HSQLDBRepository repository = (HSQLDBRepository) RepositoryManager.getRepository()) { try (final HSQLDBRepository repository = (HSQLDBRepository) RepositoryManager.getRepository()) {
System.out.println("Starting testMissingAtStatesHeightIndex");
// Firstly check that we're able to prune or archive when the index exists // Firstly check that we're able to prune or archive when the index exists
System.out.println("Checking existence of ATStatesHeightIndex...");
assertTrue(repository.getATRepository().hasAtStatesHeightIndex()); assertTrue(repository.getATRepository().hasAtStatesHeightIndex());
assertTrue(RepositoryManager.canArchiveOrPrune()); assertTrue(RepositoryManager.canArchiveOrPrune());
System.out.println("ATStatesHeightIndex exists. Archiving and pruning are possible.");
// Delete the index // Delete the index
System.out.println("Dropping ATStatesHeightIndex...");
repository.prepareStatement("DROP INDEX ATSTATESHEIGHTINDEX").execute(); repository.prepareStatement("DROP INDEX ATSTATESHEIGHTINDEX").execute();
System.out.println("ATStatesHeightIndex dropped.");
// Ensure check that we're unable to prune or archive when the index doesn't exist // Ensure check that we're unable to prune or archive when the index doesn't exist
System.out.println("Verifying that ATStatesHeightIndex no longer exists...");
assertFalse(repository.getATRepository().hasAtStatesHeightIndex()); assertFalse(repository.getATRepository().hasAtStatesHeightIndex());
assertFalse(RepositoryManager.canArchiveOrPrune()); assertFalse(RepositoryManager.canArchiveOrPrune());
System.out.println("ATStatesHeightIndex does not exist. Archiving and pruning are disabled.");
System.out.println("testMissingAtStatesHeightIndex completed successfully.");
} }
} }
@ -501,8 +644,10 @@ public class BlockArchiveV1Tests extends Common {
Path archivePath = Paths.get(Settings.getInstance().getRepositoryPath(), "archive").toAbsolutePath(); Path archivePath = Paths.get(Settings.getInstance().getRepositoryPath(), "archive").toAbsolutePath();
try { try {
FileUtils.deleteDirectory(archivePath.toFile()); FileUtils.deleteDirectory(archivePath.toFile());
System.out.println("Deleted archive directory at: " + archivePath);
} catch (IOException e) { } catch (IOException e) {
System.out.println("Failed to delete archive directory: " + e.getMessage());
} }
} }

View File

@ -54,26 +54,39 @@ public class BlockArchiveV2Tests extends Common {
public void testWriter() throws DataException, InterruptedException, TransformationException, IOException { public void testWriter() throws DataException, InterruptedException, TransformationException, IOException {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
System.out.println("Starting testWriter");
// Mint some blocks so that we are able to archive them later // Mint some blocks so that we are able to archive them later
System.out.println("Minting 1000 blocks...");
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share")); BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
// Log every 100 blocks
if ((i + 1) % 100 == 0) {
System.out.println("Minted block " + (i + 1));
}
} }
System.out.println("Finished minting blocks.");
// 900 blocks are trimmed (this specifies the first untrimmed height) // 900 blocks are trimmed (this specifies the first untrimmed height)
repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(901); repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(901);
repository.getATRepository().setAtTrimHeight(901); repository.getATRepository().setAtTrimHeight(901);
System.out.println("Set trim heights to 901.");
// Check the max archive height - this should be one less than the first untrimmed height // Check the max archive height - this should be one less than the first untrimmed height
final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository); final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository);
System.out.println("Maximum archive height (Expected 900): " + maximumArchiveHeight);
assertEquals(900, maximumArchiveHeight); assertEquals(900, maximumArchiveHeight);
// Write blocks 2-900 to the archive // Write blocks 2-900 to the archive
System.out.println("Writing blocks 2 to " + maximumArchiveHeight + " to the archive...");
BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository); BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository);
writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes
BlockArchiveWriter.BlockArchiveWriteResult result = writer.write(); BlockArchiveWriter.BlockArchiveWriteResult result = writer.write();
System.out.println("Finished writing blocks to archive. Result: " + result);
assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result); assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result);
// Make sure that the archive contains the correct number of blocks // Make sure that the archive contains the correct number of blocks
System.out.println("Archive contains " + writer.getWrittenCount() + " blocks. (Expected 899)");
assertEquals(900 - 1, writer.getWrittenCount()); assertEquals(900 - 1, writer.getWrittenCount());
// Increment block archive height // Increment block archive height
@ -84,6 +97,9 @@ public class BlockArchiveV2Tests extends Common {
// Ensure the file exists // Ensure the file exists
File outputFile = writer.getOutputPath().toFile(); File outputFile = writer.getOutputPath().toFile();
assertTrue(outputFile.exists()); assertTrue(outputFile.exists());
System.out.println("Archive file exists at: " + outputFile.getAbsolutePath());
System.out.println("testWriter completed successfully.");
} }
} }
@ -91,26 +107,39 @@ public class BlockArchiveV2Tests extends Common {
public void testWriterAndReader() throws DataException, InterruptedException, TransformationException, IOException { public void testWriterAndReader() throws DataException, InterruptedException, TransformationException, IOException {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
System.out.println("Starting testWriterAndReader");
// Mint some blocks so that we are able to archive them later // Mint some blocks so that we are able to archive them later
System.out.println("Minting 1000 blocks...");
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share")); BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
// Log every 100 blocks
if ((i + 1) % 100 == 0) {
System.out.println("Minted block " + (i + 1));
}
} }
System.out.println("Finished minting blocks.");
// 900 blocks are trimmed (this specifies the first untrimmed height) // 900 blocks are trimmed (this specifies the first untrimmed height)
repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(901); repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(901);
repository.getATRepository().setAtTrimHeight(901); repository.getATRepository().setAtTrimHeight(901);
System.out.println("Set trim heights to 901.");
// Check the max archive height - this should be one less than the first untrimmed height // Check the max archive height - this should be one less than the first untrimmed height
final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository); final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository);
System.out.println("Maximum archive height (Expected 900): " + maximumArchiveHeight);
assertEquals(900, maximumArchiveHeight); assertEquals(900, maximumArchiveHeight);
// Write blocks 2-900 to the archive // Write blocks 2-900 to the archive
System.out.println("Writing blocks 2 to " + maximumArchiveHeight + " to the archive...");
BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository); BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository);
writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes
BlockArchiveWriter.BlockArchiveWriteResult result = writer.write(); BlockArchiveWriter.BlockArchiveWriteResult result = writer.write();
System.out.println("Finished writing blocks to archive. Result: " + result);
assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result); assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result);
// Make sure that the archive contains the correct number of blocks // Make sure that the archive contains the correct number of blocks
System.out.println("Archive contains " + writer.getWrittenCount() + " blocks. (Expected 899)");
assertEquals(900 - 1, writer.getWrittenCount()); assertEquals(900 - 1, writer.getWrittenCount());
// Increment block archive height // Increment block archive height
@ -121,8 +150,10 @@ public class BlockArchiveV2Tests extends Common {
// Ensure the file exists // Ensure the file exists
File outputFile = writer.getOutputPath().toFile(); File outputFile = writer.getOutputPath().toFile();
assertTrue(outputFile.exists()); assertTrue(outputFile.exists());
System.out.println("Archive file exists at: " + outputFile.getAbsolutePath());
// Read block 2 from the archive // Read block 2 from the archive
System.out.println("Reading block 2 from the archive...");
BlockArchiveReader reader = BlockArchiveReader.getInstance(); BlockArchiveReader reader = BlockArchiveReader.getInstance();
BlockTransformation block2Info = reader.fetchBlockAtHeight(2); BlockTransformation block2Info = reader.fetchBlockAtHeight(2);
BlockData block2ArchiveData = block2Info.getBlockData(); BlockData block2ArchiveData = block2Info.getBlockData();
@ -131,6 +162,7 @@ public class BlockArchiveV2Tests extends Common {
BlockData block2RepositoryData = repository.getBlockRepository().fromHeight(2); BlockData block2RepositoryData = repository.getBlockRepository().fromHeight(2);
// Ensure the values match // Ensure the values match
System.out.println("Comparing block 2 data...");
assertEquals(block2ArchiveData.getHeight(), block2RepositoryData.getHeight()); assertEquals(block2ArchiveData.getHeight(), block2RepositoryData.getHeight());
assertArrayEquals(block2ArchiveData.getSignature(), block2RepositoryData.getSignature()); assertArrayEquals(block2ArchiveData.getSignature(), block2RepositoryData.getSignature());
@ -138,6 +170,7 @@ public class BlockArchiveV2Tests extends Common {
assertEquals(1, block2ArchiveData.getOnlineAccountsCount()); assertEquals(1, block2ArchiveData.getOnlineAccountsCount());
// Read block 900 from the archive // Read block 900 from the archive
System.out.println("Reading block 900 from the archive...");
BlockTransformation block900Info = reader.fetchBlockAtHeight(900); BlockTransformation block900Info = reader.fetchBlockAtHeight(900);
BlockData block900ArchiveData = block900Info.getBlockData(); BlockData block900ArchiveData = block900Info.getBlockData();
@ -145,12 +178,14 @@ public class BlockArchiveV2Tests extends Common {
BlockData block900RepositoryData = repository.getBlockRepository().fromHeight(900); BlockData block900RepositoryData = repository.getBlockRepository().fromHeight(900);
// Ensure the values match // Ensure the values match
System.out.println("Comparing block 900 data...");
assertEquals(block900ArchiveData.getHeight(), block900RepositoryData.getHeight()); assertEquals(block900ArchiveData.getHeight(), block900RepositoryData.getHeight());
assertArrayEquals(block900ArchiveData.getSignature(), block900RepositoryData.getSignature()); assertArrayEquals(block900ArchiveData.getSignature(), block900RepositoryData.getSignature());
// Test some values in the archive // Test some values in the archive
assertEquals(1, block900ArchiveData.getOnlineAccountsCount()); assertEquals(1, block900ArchiveData.getOnlineAccountsCount());
System.out.println("testWriterAndReader completed successfully.");
} }
} }
@ -158,47 +193,66 @@ public class BlockArchiveV2Tests extends Common {
public void testArchivedAtStates() throws DataException, InterruptedException, TransformationException, IOException { public void testArchivedAtStates() throws DataException, InterruptedException, TransformationException, IOException {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
System.out.println("Starting testArchivedAtStates");
// Deploy an AT so that we have AT state data // Deploy an AT so that we have AT state data
System.out.println("Deploying AT...");
PrivateKeyAccount deployer = Common.getTestAccount(repository, "alice"); PrivateKeyAccount deployer = Common.getTestAccount(repository, "alice");
byte[] creationBytes = AtUtils.buildSimpleAT(); byte[] creationBytes = AtUtils.buildSimpleAT();
long fundingAmount = 1_00000000L; long fundingAmount = 1_00000000L;
DeployAtTransaction deployAtTransaction = AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount); DeployAtTransaction deployAtTransaction = AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount);
String atAddress = deployAtTransaction.getATAccount().getAddress(); String atAddress = deployAtTransaction.getATAccount().getAddress();
System.out.println("AT deployed at address: " + atAddress);
// Mint some blocks so that we are able to archive them later // Mint some blocks so that we are able to archive them later
System.out.println("Minting 1000 blocks...");
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share")); BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
// Log every 100 blocks
if ((i + 1) % 100 == 0) {
System.out.println("Minted block " + (i + 1));
}
} }
System.out.println("Finished minting blocks.");
// 9 blocks are trimmed (this specifies the first untrimmed height) // 9 blocks are trimmed (this specifies the first untrimmed height)
repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(10); repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(10);
repository.getATRepository().setAtTrimHeight(10); repository.getATRepository().setAtTrimHeight(10);
System.out.println("Set trim heights to 10.");
// Check the max archive height // Check the max archive height
final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository); final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository);
System.out.println("Maximum archive height (Expected 9): " + maximumArchiveHeight);
assertEquals(9, maximumArchiveHeight); assertEquals(9, maximumArchiveHeight);
// Write blocks 2-9 to the archive // Write blocks 2-9 to the archive
System.out.println("Writing blocks 2 to " + maximumArchiveHeight + " to the archive...");
BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository); BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository);
writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes
BlockArchiveWriter.BlockArchiveWriteResult result = writer.write(); BlockArchiveWriter.BlockArchiveWriteResult result = writer.write();
System.out.println("Finished writing blocks to archive. Result: " + result);
assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result); assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result);
// Make sure that the archive contains the correct number of blocks // Make sure that the archive contains the correct number of blocks
System.out.println("Archive contains " + writer.getWrittenCount() + " blocks. (Expected 8)");
assertEquals(9 - 1, writer.getWrittenCount()); assertEquals(9 - 1, writer.getWrittenCount());
// Increment block archive height // Increment block archive height
repository.getBlockArchiveRepository().setBlockArchiveHeight(writer.getWrittenCount()); repository.getBlockArchiveRepository().setBlockArchiveHeight(writer.getWrittenCount());
repository.saveChanges(); repository.saveChanges();
assertEquals(9 - 1, repository.getBlockArchiveRepository().getBlockArchiveHeight()); assertEquals(9 - 1, repository.getBlockArchiveRepository().getBlockArchiveHeight());
System.out.println("Block archive height updated to: " + (9 - 1));
// Ensure the file exists // Ensure the file exists
File outputFile = writer.getOutputPath().toFile(); File outputFile = writer.getOutputPath().toFile();
assertTrue(outputFile.exists()); assertTrue(outputFile.exists());
System.out.println("Archive file exists at: " + outputFile.getAbsolutePath());
// Check blocks 3-9 // Check blocks 3-9
System.out.println("Checking blocks 2 to 9...");
for (Integer testHeight = 2; testHeight <= 9; testHeight++) { for (Integer testHeight = 2; testHeight <= 9; testHeight++) {
System.out.println("Reading block " + testHeight + " from the archive...");
// Read a block from the archive // Read a block from the archive
BlockArchiveReader reader = BlockArchiveReader.getInstance(); BlockArchiveReader reader = BlockArchiveReader.getInstance();
BlockTransformation blockInfo = reader.fetchBlockAtHeight(testHeight); BlockTransformation blockInfo = reader.fetchBlockAtHeight(testHeight);
@ -216,15 +270,18 @@ public class BlockArchiveV2Tests extends Common {
// Check the archived AT state // Check the archived AT state
if (testHeight == 2) { if (testHeight == 2) {
System.out.println("Checking block " + testHeight + " AT state data (expected transactions)...");
assertEquals(1, archivedTransactions.size()); assertEquals(1, archivedTransactions.size());
assertEquals(Transaction.TransactionType.DEPLOY_AT, archivedTransactions.get(0).getType()); assertEquals(Transaction.TransactionType.DEPLOY_AT, archivedTransactions.get(0).getType());
} }
else { else {
System.out.println("Checking block " + testHeight + " AT state data (no transactions expected)...");
// Blocks 3+ shouldn't have any transactions // Blocks 3+ shouldn't have any transactions
assertTrue(archivedTransactions.isEmpty()); assertTrue(archivedTransactions.isEmpty());
} }
// Ensure the archive has the AT states hash // Ensure the archive has the AT states hash
System.out.println("Checking block " + testHeight + " AT states hash...");
assertNotNull(archivedAtStateHash); assertNotNull(archivedAtStateHash);
// Also check the online accounts count and height // Also check the online accounts count and height
@ -232,6 +289,7 @@ public class BlockArchiveV2Tests extends Common {
assertEquals(testHeight, archivedBlockData.getHeight()); assertEquals(testHeight, archivedBlockData.getHeight());
// Ensure the values match // Ensure the values match
System.out.println("Comparing block " + testHeight + " data...");
assertEquals(archivedBlockData.getHeight(), repositoryBlockData.getHeight()); assertEquals(archivedBlockData.getHeight(), repositoryBlockData.getHeight());
assertArrayEquals(archivedBlockData.getSignature(), repositoryBlockData.getSignature()); assertArrayEquals(archivedBlockData.getSignature(), repositoryBlockData.getSignature());
assertEquals(archivedBlockData.getOnlineAccountsCount(), repositoryBlockData.getOnlineAccountsCount()); assertEquals(archivedBlockData.getOnlineAccountsCount(), repositoryBlockData.getOnlineAccountsCount());
@ -249,10 +307,12 @@ public class BlockArchiveV2Tests extends Common {
} }
// Check block 10 (unarchived) // Check block 10 (unarchived)
System.out.println("Checking block 10 (should not be in archive)...");
BlockArchiveReader reader = BlockArchiveReader.getInstance(); BlockArchiveReader reader = BlockArchiveReader.getInstance();
BlockTransformation blockInfo = reader.fetchBlockAtHeight(10); BlockTransformation blockInfo = reader.fetchBlockAtHeight(10);
assertNull(blockInfo); assertNull(blockInfo);
System.out.println("testArchivedAtStates completed successfully.");
} }
} }
@ -261,32 +321,47 @@ public class BlockArchiveV2Tests extends Common {
public void testArchiveAndPrune() throws DataException, InterruptedException, TransformationException, IOException { public void testArchiveAndPrune() throws DataException, InterruptedException, TransformationException, IOException {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
System.out.println("Starting testArchiveAndPrune");
// Deploy an AT so that we have AT state data // Deploy an AT so that we have AT state data
System.out.println("Deploying AT...");
PrivateKeyAccount deployer = Common.getTestAccount(repository, "alice"); PrivateKeyAccount deployer = Common.getTestAccount(repository, "alice");
byte[] creationBytes = AtUtils.buildSimpleAT(); byte[] creationBytes = AtUtils.buildSimpleAT();
long fundingAmount = 1_00000000L; long fundingAmount = 1_00000000L;
AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount); AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount);
System.out.println("AT deployed successfully.");
// Mint some blocks so that we are able to archive them later // Mint some blocks so that we are able to archive them later
System.out.println("Minting 1000 blocks...");
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share")); BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
// Log every 100 blocks
if ((i + 1) % 100 == 0) {
System.out.println("Minted block " + (i + 1));
}
} }
System.out.println("Finished minting blocks.");
// Assume 900 blocks are trimmed (this specifies the first untrimmed height) // Assume 900 blocks are trimmed (this specifies the first untrimmed height)
repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(901); repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(901);
repository.getATRepository().setAtTrimHeight(901); repository.getATRepository().setAtTrimHeight(901);
System.out.println("Set trim heights to 901.");
// Check the max archive height - this should be one less than the first untrimmed height // Check the max archive height - this should be one less than the first untrimmed height
final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository); final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository);
System.out.println("Maximum archive height (Expected 900): " + maximumArchiveHeight);
assertEquals(900, maximumArchiveHeight); assertEquals(900, maximumArchiveHeight);
// Write blocks 2-900 to the archive // Write blocks 2-900 to the archive
System.out.println("Writing blocks 2 to " + maximumArchiveHeight + " to the archive...");
BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository); BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository);
writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes
BlockArchiveWriter.BlockArchiveWriteResult result = writer.write(); BlockArchiveWriter.BlockArchiveWriteResult result = writer.write();
System.out.println("Finished writing blocks to archive. Result: " + result);
assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result); assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result);
// Make sure that the archive contains the correct number of blocks // Make sure that the archive contains the correct number of blocks
System.out.println("Archive contains " + writer.getWrittenCount() + " blocks. (Expected 899)");
assertEquals(900 - 1, writer.getWrittenCount()); assertEquals(900 - 1, writer.getWrittenCount());
// Increment block archive height // Increment block archive height
@ -297,34 +372,48 @@ public class BlockArchiveV2Tests extends Common {
// Ensure the file exists // Ensure the file exists
File outputFile = writer.getOutputPath().toFile(); File outputFile = writer.getOutputPath().toFile();
assertTrue(outputFile.exists()); assertTrue(outputFile.exists());
System.out.println("Archive file exists at: " + outputFile.getAbsolutePath());
// Ensure the SQL repository contains blocks 2 and 900... // Ensure the SQL repository contains blocks 2 and 900...
System.out.println("Verifying that blocks 2 and 900 exist in the repository...");
assertNotNull(repository.getBlockRepository().fromHeight(2)); assertNotNull(repository.getBlockRepository().fromHeight(2));
assertNotNull(repository.getBlockRepository().fromHeight(900)); assertNotNull(repository.getBlockRepository().fromHeight(900));
System.out.println("Blocks 2 and 900 are present in the repository.");
// Prune all the archived blocks // Prune all the archived blocks
System.out.println("Pruning blocks 2 to 900...");
int numBlocksPruned = repository.getBlockRepository().pruneBlocks(0, 900); int numBlocksPruned = repository.getBlockRepository().pruneBlocks(0, 900);
System.out.println("Number of blocks pruned (Expected 899): " + numBlocksPruned);
assertEquals(900-1, numBlocksPruned); assertEquals(900-1, numBlocksPruned);
repository.getBlockRepository().setBlockPruneHeight(901); repository.getBlockRepository().setBlockPruneHeight(901);
// Prune the AT states for the archived blocks // Prune the AT states for the archived blocks
System.out.println("Pruning AT states up to height 900...");
repository.getATRepository().rebuildLatestAtStates(900); repository.getATRepository().rebuildLatestAtStates(900);
repository.saveChanges(); repository.saveChanges();
int numATStatesPruned = repository.getATRepository().pruneAtStates(0, 900); int numATStatesPruned = repository.getATRepository().pruneAtStates(0, 900);
System.out.println("Number of AT states pruned (Expected 898): " + numATStatesPruned);
assertEquals(900-2, numATStatesPruned); // Minus 1 for genesis block, and another for the latest AT state assertEquals(900-2, numATStatesPruned); // Minus 1 for genesis block, and another for the latest AT state
repository.getATRepository().setAtPruneHeight(901); repository.getATRepository().setAtPruneHeight(901);
// Now ensure the SQL repository is missing blocks 2 and 900... // Now ensure the SQL repository is missing blocks 2 and 900...
System.out.println("Verifying that blocks 2 and 900 have been pruned...");
assertNull(repository.getBlockRepository().fromHeight(2)); assertNull(repository.getBlockRepository().fromHeight(2));
assertNull(repository.getBlockRepository().fromHeight(900)); assertNull(repository.getBlockRepository().fromHeight(900));
System.out.println("Blocks 2 and 900 have been successfully pruned.");
// ... but it's not missing blocks 1 and 901 (we don't prune the genesis block) // ... but it's not missing blocks 1 and 901 (we don't prune the genesis block)
System.out.println("Verifying that blocks 1 and 901 still exist...");
assertNotNull(repository.getBlockRepository().fromHeight(1)); assertNotNull(repository.getBlockRepository().fromHeight(1));
assertNotNull(repository.getBlockRepository().fromHeight(901)); assertNotNull(repository.getBlockRepository().fromHeight(901));
System.out.println("Blocks 1 and 901 are present in the repository.");
// Validate the latest block height in the repository // Validate the latest block height in the repository
assertEquals(1002, (int) repository.getBlockRepository().getLastBlock().getHeight()); int lastBlockHeight = repository.getBlockRepository().getLastBlock().getHeight();
System.out.println("Latest block height in repository (Expected 1002): " + lastBlockHeight);
assertEquals(1002, lastBlockHeight);
System.out.println("testArchiveAndPrune completed successfully.");
} }
} }
@ -332,138 +421,191 @@ public class BlockArchiveV2Tests extends Common {
public void testTrimArchivePruneAndOrphan() throws DataException, InterruptedException, TransformationException, IOException { public void testTrimArchivePruneAndOrphan() throws DataException, InterruptedException, TransformationException, IOException {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
System.out.println("Starting testTrimArchivePruneAndOrphan");
// Deploy an AT so that we have AT state data // Deploy an AT so that we have AT state data
System.out.println("Deploying AT...");
PrivateKeyAccount deployer = Common.getTestAccount(repository, "alice"); PrivateKeyAccount deployer = Common.getTestAccount(repository, "alice");
byte[] creationBytes = AtUtils.buildSimpleAT(); byte[] creationBytes = AtUtils.buildSimpleAT();
long fundingAmount = 1_00000000L; long fundingAmount = 1_00000000L;
AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount); AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount);
System.out.println("AT deployed successfully.");
// Mint some blocks so that we are able to archive them later // Mint some blocks so that we are able to archive them later
System.out.println("Minting 1000 blocks...");
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share")); BlockMinter.mintTestingBlock(repository, Common.getTestAccount(repository, "alice-reward-share"));
// Log every 100 blocks
if ((i + 1) % 100 == 0) {
System.out.println("Minted block " + (i + 1));
}
} }
System.out.println("Finished minting blocks.");
// Make sure that block 500 has full AT state data and data hash // Make sure that block 500 has full AT state data and data hash
System.out.println("Verifying block 500 AT state data...");
List<ATStateData> block500AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(500); List<ATStateData> block500AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(500);
ATStateData atStatesData = repository.getATRepository().getATStateAtHeight(block500AtStatesData.get(0).getATAddress(), 500); ATStateData atStatesData = repository.getATRepository().getATStateAtHeight(block500AtStatesData.get(0).getATAddress(), 500);
assertNotNull(atStatesData.getStateHash()); assertNotNull(atStatesData.getStateHash());
assertNotNull(atStatesData.getStateData()); assertNotNull(atStatesData.getStateData());
System.out.println("Block 500 AT state data verified.");
// Trim the first 500 blocks // Trim the first 500 blocks
System.out.println("Trimming first 500 blocks...");
repository.getBlockRepository().trimOldOnlineAccountsSignatures(0, 500); repository.getBlockRepository().trimOldOnlineAccountsSignatures(0, 500);
repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(501); repository.getBlockRepository().setOnlineAccountsSignaturesTrimHeight(501);
repository.getATRepository().rebuildLatestAtStates(500); repository.getATRepository().rebuildLatestAtStates(500);
repository.getATRepository().trimAtStates(0, 500, 1000); repository.getATRepository().trimAtStates(0, 500, 1000);
repository.getATRepository().setAtTrimHeight(501); repository.getATRepository().setAtTrimHeight(501);
System.out.println("Trimming completed.");
// Now block 499 should only have the AT state data hash // Now block 499 should only have the AT state data hash
System.out.println("Checking block 499 AT state data...");
List<ATStateData> block499AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(499); List<ATStateData> block499AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(499);
atStatesData = repository.getATRepository().getATStateAtHeight(block499AtStatesData.get(0).getATAddress(), 499); atStatesData = repository.getATRepository().getATStateAtHeight(block499AtStatesData.get(0).getATAddress(), 499);
assertNotNull(atStatesData.getStateHash()); assertNotNull(atStatesData.getStateHash());
assertNull(atStatesData.getStateData()); assertNull(atStatesData.getStateData());
System.out.println("Block 499 AT state data contains only state hash as expected.");
// ... but block 500 should have the full data (due to being retained as the "latest" AT state in the trimmed range // ... but block 500 should have the full data (due to being retained as the "latest" AT state in the trimmed range
System.out.println("Verifying block 500 AT state data again...");
block500AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(500); block500AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(500);
atStatesData = repository.getATRepository().getATStateAtHeight(block500AtStatesData.get(0).getATAddress(), 500); atStatesData = repository.getATRepository().getATStateAtHeight(block500AtStatesData.get(0).getATAddress(), 500);
assertNotNull(atStatesData.getStateHash()); assertNotNull(atStatesData.getStateHash());
assertNotNull(atStatesData.getStateData()); assertNotNull(atStatesData.getStateData());
System.out.println("Block 500 AT state data contains full data.");
// ... and block 501 should also have the full data // ... and block 501 should also have the full data
System.out.println("Verifying block 501 AT state data...");
List<ATStateData> block501AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(501); List<ATStateData> block501AtStatesData = repository.getATRepository().getBlockATStatesAtHeight(501);
atStatesData = repository.getATRepository().getATStateAtHeight(block501AtStatesData.get(0).getATAddress(), 501); atStatesData = repository.getATRepository().getATStateAtHeight(block501AtStatesData.get(0).getATAddress(), 501);
assertNotNull(atStatesData.getStateHash()); assertNotNull(atStatesData.getStateHash());
assertNotNull(atStatesData.getStateData()); assertNotNull(atStatesData.getStateData());
System.out.println("Block 501 AT state data contains full data.");
// Check the max archive height - this should be one less than the first untrimmed height // Check the max archive height - this should be one less than the first untrimmed height
final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository); final int maximumArchiveHeight = BlockArchiveWriter.getMaxArchiveHeight(repository);
System.out.println("Maximum archive height determined (Expected 500): " + maximumArchiveHeight);
assertEquals(500, maximumArchiveHeight); assertEquals(500, maximumArchiveHeight);
BlockData block3DataPreArchive = repository.getBlockRepository().fromHeight(3); BlockData block3DataPreArchive = repository.getBlockRepository().fromHeight(3);
// Write blocks 2-500 to the archive // Write blocks 2-500 to the archive
System.out.println("Writing blocks 2 to " + maximumArchiveHeight + " to the archive...");
BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository); BlockArchiveWriter writer = new BlockArchiveWriter(0, maximumArchiveHeight, repository);
writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes writer.setShouldEnforceFileSizeTarget(false); // To avoid the need to pre-calculate file sizes
BlockArchiveWriter.BlockArchiveWriteResult result = writer.write(); BlockArchiveWriter.BlockArchiveWriteResult result = writer.write();
System.out.println("Finished writing blocks to archive. Result: " + result);
assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result); assertEquals(BlockArchiveWriter.BlockArchiveWriteResult.OK, result);
// Make sure that the archive contains the correct number of blocks // Make sure that the archive contains the correct number of blocks
System.out.println("Number of blocks written to archive (Expected 499): " + writer.getWrittenCount());
assertEquals(500 - 1, writer.getWrittenCount()); // -1 for the genesis block assertEquals(500 - 1, writer.getWrittenCount()); // -1 for the genesis block
// Increment block archive height // Increment block archive height
repository.getBlockArchiveRepository().setBlockArchiveHeight(writer.getWrittenCount()); repository.getBlockArchiveRepository().setBlockArchiveHeight(writer.getWrittenCount());
repository.saveChanges(); repository.saveChanges();
assertEquals(500 - 1, repository.getBlockArchiveRepository().getBlockArchiveHeight()); assertEquals(500 - 1, repository.getBlockArchiveRepository().getBlockArchiveHeight());
System.out.println("Block archive height updated to: " + (500 - 1));
// Ensure the file exists // Ensure the file exists
File outputFile = writer.getOutputPath().toFile(); File outputFile = writer.getOutputPath().toFile();
assertTrue(outputFile.exists()); assertTrue(outputFile.exists());
System.out.println("Archive file exists at: " + outputFile.getAbsolutePath());
// Ensure the SQL repository contains blocks 2 and 500... // Ensure the SQL repository contains blocks 2 and 500...
System.out.println("Verifying that blocks 2 and 500 exist in the repository...");
assertNotNull(repository.getBlockRepository().fromHeight(2)); assertNotNull(repository.getBlockRepository().fromHeight(2));
assertNotNull(repository.getBlockRepository().fromHeight(500)); assertNotNull(repository.getBlockRepository().fromHeight(500));
System.out.println("Blocks 2 and 500 are present in the repository.");
// Prune all the archived blocks // Prune all the archived blocks
System.out.println("Pruning blocks 2 to 500...");
int numBlocksPruned = repository.getBlockRepository().pruneBlocks(0, 500); int numBlocksPruned = repository.getBlockRepository().pruneBlocks(0, 500);
System.out.println("Number of blocks pruned (Expected 499): " + numBlocksPruned);
assertEquals(500-1, numBlocksPruned); assertEquals(500-1, numBlocksPruned);
repository.getBlockRepository().setBlockPruneHeight(501); repository.getBlockRepository().setBlockPruneHeight(501);
// Prune the AT states for the archived blocks // Prune the AT states for the archived blocks
System.out.println("Pruning AT states up to height 500...");
repository.getATRepository().rebuildLatestAtStates(500); repository.getATRepository().rebuildLatestAtStates(500);
repository.saveChanges(); repository.saveChanges();
int numATStatesPruned = repository.getATRepository().pruneAtStates(2, 500); int numATStatesPruned = repository.getATRepository().pruneAtStates(2, 500);
System.out.println("Number of AT states pruned (Expected 498): " + numATStatesPruned);
assertEquals(498, numATStatesPruned); // Minus 1 for genesis block, and another for the latest AT state assertEquals(498, numATStatesPruned); // Minus 1 for genesis block, and another for the latest AT state
repository.getATRepository().setAtPruneHeight(501); repository.getATRepository().setAtPruneHeight(501);
// Now ensure the SQL repository is missing blocks 2 and 500... // Now ensure the SQL repository is missing blocks 2 and 500...
System.out.println("Verifying that blocks 2 and 500 have been pruned...");
assertNull(repository.getBlockRepository().fromHeight(2)); assertNull(repository.getBlockRepository().fromHeight(2));
assertNull(repository.getBlockRepository().fromHeight(500)); assertNull(repository.getBlockRepository().fromHeight(500));
System.out.println("Blocks 2 and 500 have been successfully pruned.");
// ... but it's not missing blocks 1 and 501 (we don't prune the genesis block) // ... but it's not missing blocks 1 and 501 (we don't prune the genesis block)
System.out.println("Verifying that blocks 1 and 501 still exist...");
assertNotNull(repository.getBlockRepository().fromHeight(1)); assertNotNull(repository.getBlockRepository().fromHeight(1));
assertNotNull(repository.getBlockRepository().fromHeight(501)); assertNotNull(repository.getBlockRepository().fromHeight(501));
System.out.println("Blocks 1 and 501 are present in the repository.");
// Validate the latest block height in the repository // Validate the latest block height in the repository
assertEquals(1002, (int) repository.getBlockRepository().getLastBlock().getHeight()); int lastBlockHeight = repository.getBlockRepository().getLastBlock().getHeight();
System.out.println("Latest block height in repository (Expected 1002): " + lastBlockHeight);
assertEquals(1002, lastBlockHeight);
// Now orphan some unarchived blocks. // Now orphan some unarchived blocks.
System.out.println("Orphaning 500 blocks...");
BlockUtils.orphanBlocks(repository, 500); BlockUtils.orphanBlocks(repository, 500);
assertEquals(502, (int) repository.getBlockRepository().getLastBlock().getHeight()); int currentLastBlockHeight = repository.getBlockRepository().getLastBlock().getHeight();
System.out.println("New last block height after orphaning (Expected 502): " + currentLastBlockHeight);
assertEquals(502, currentLastBlockHeight);
// We're close to the lower limit of the SQL database now, so // We're close to the lower limit of the SQL database now, so
// we need to import some blocks from the archive // we need to import some blocks from the archive
System.out.println("Importing blocks 401 to 500 from the archive...");
BlockArchiveUtils.importFromArchive(401, 500, repository); BlockArchiveUtils.importFromArchive(401, 500, repository);
// Ensure the SQL repository now contains block 401 but not 400... // Ensure the SQL repository now contains block 401 but not 400...
System.out.println("Verifying that block 401 exists and block 400 does not...");
assertNotNull(repository.getBlockRepository().fromHeight(401)); assertNotNull(repository.getBlockRepository().fromHeight(401));
assertNull(repository.getBlockRepository().fromHeight(400)); assertNull(repository.getBlockRepository().fromHeight(400));
System.out.println("Block 401 exists, block 400 does not.");
// Import the remaining 399 blocks // Import the remaining 399 blocks
System.out.println("Importing blocks 2 to 400 from the archive...");
BlockArchiveUtils.importFromArchive(2, 400, repository); BlockArchiveUtils.importFromArchive(2, 400, repository);
// Verify that block 3 matches the original // Verify that block 3 matches the original
System.out.println("Verifying that block 3 matches the original data...");
BlockData block3DataPostArchive = repository.getBlockRepository().fromHeight(3); BlockData block3DataPostArchive = repository.getBlockRepository().fromHeight(3);
assertArrayEquals(block3DataPreArchive.getSignature(), block3DataPostArchive.getSignature()); assertArrayEquals(block3DataPreArchive.getSignature(), block3DataPostArchive.getSignature());
assertEquals(block3DataPreArchive.getHeight(), block3DataPostArchive.getHeight()); assertEquals(block3DataPreArchive.getHeight(), block3DataPostArchive.getHeight());
System.out.println("Block 3 data matches the original.");
// Orphan 2 more block, which should be the last one that is possible to be orphaned // Orphan 2 more block, which should be the last one that is possible to be orphaned
// TODO: figure out why this is 1 block more than in the equivalent block archive V1 test // TODO: figure out why this is 1 block more than in the equivalent block archive V1 test
System.out.println("Orphaning 2 more blocks...");
BlockUtils.orphanBlocks(repository, 2); BlockUtils.orphanBlocks(repository, 2);
System.out.println("Orphaned 2 blocks successfully.");
// Orphan another block, which should fail // Orphan another block, which should fail
System.out.println("Attempting to orphan another block, which should fail...");
Exception exception = null; Exception exception = null;
try { try {
BlockUtils.orphanBlocks(repository, 1); BlockUtils.orphanBlocks(repository, 1);
} catch (DataException e) { } catch (DataException e) {
exception = e; exception = e;
System.out.println("Caught expected DataException: " + e.getMessage());
} }
// Ensure that a DataException is thrown because there is no more AT states data available // Ensure that a DataException is thrown because there is no more AT states data available
assertNotNull(exception); assertNotNull(exception);
assertEquals(DataException.class, exception.getClass()); assertEquals(DataException.class, exception.getClass());
System.out.println("DataException confirmed due to lack of AT states data.");
// FUTURE: we may be able to retain unique AT states when trimming, to avoid this exception // FUTURE: we may be able to retain unique AT states when trimming, to avoid this exception
// and allow orphaning back through blocks with trimmed AT states. // and allow orphaning back through blocks with trimmed AT states.
System.out.println("testTrimArchivePruneAndOrphan completed successfully.");
} }
} }
@ -477,16 +619,26 @@ public class BlockArchiveV2Tests extends Common {
public void testMissingAtStatesHeightIndex() throws DataException, SQLException { public void testMissingAtStatesHeightIndex() throws DataException, SQLException {
try (final HSQLDBRepository repository = (HSQLDBRepository) RepositoryManager.getRepository()) { try (final HSQLDBRepository repository = (HSQLDBRepository) RepositoryManager.getRepository()) {
System.out.println("Starting testMissingAtStatesHeightIndex");
// Firstly check that we're able to prune or archive when the index exists // Firstly check that we're able to prune or archive when the index exists
System.out.println("Checking existence of ATStatesHeightIndex...");
assertTrue(repository.getATRepository().hasAtStatesHeightIndex()); assertTrue(repository.getATRepository().hasAtStatesHeightIndex());
assertTrue(RepositoryManager.canArchiveOrPrune()); assertTrue(RepositoryManager.canArchiveOrPrune());
System.out.println("ATStatesHeightIndex exists. Archiving and pruning are possible.");
// Delete the index // Delete the index
System.out.println("Dropping ATStatesHeightIndex...");
repository.prepareStatement("DROP INDEX ATSTATESHEIGHTINDEX").execute(); repository.prepareStatement("DROP INDEX ATSTATESHEIGHTINDEX").execute();
System.out.println("ATStatesHeightIndex dropped.");
// Ensure check that we're unable to prune or archive when the index doesn't exist // Ensure check that we're unable to prune or archive when the index doesn't exist
System.out.println("Verifying that ATStatesHeightIndex no longer exists...");
assertFalse(repository.getATRepository().hasAtStatesHeightIndex()); assertFalse(repository.getATRepository().hasAtStatesHeightIndex());
assertFalse(RepositoryManager.canArchiveOrPrune()); assertFalse(RepositoryManager.canArchiveOrPrune());
System.out.println("ATStatesHeightIndex does not exist. Archiving and pruning are disabled.");
System.out.println("testMissingAtStatesHeightIndex completed successfully.");
} }
} }
@ -496,8 +648,10 @@ public class BlockArchiveV2Tests extends Common {
Path archivePath = Paths.get(Settings.getInstance().getRepositoryPath(), "archive").toAbsolutePath(); Path archivePath = Paths.get(Settings.getInstance().getRepositoryPath(), "archive").toAbsolutePath();
try { try {
FileUtils.deleteDirectory(archivePath.toFile()); FileUtils.deleteDirectory(archivePath.toFile());
System.out.println("Deleted archive directory at: " + archivePath);
} catch (IOException e) { } catch (IOException e) {
System.out.println("Failed to delete archive directory: " + e.getMessage());
} }
} }

View File

@ -81,7 +81,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 9999999999999, "transactionV6Timestamp": 9999999999999,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -91,7 +91,14 @@
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -84,7 +84,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 0, "disableReferenceTimestamp": 0,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -94,7 +94,14 @@
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -85,7 +85,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -95,7 +95,14 @@
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -85,7 +85,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -95,7 +95,14 @@
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -85,7 +85,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 0, "disableReferenceTimestamp": 0,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -95,7 +95,14 @@
"arbitraryOptionalFeeTimestamp": 9999999999999, "arbitraryOptionalFeeTimestamp": 9999999999999,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -83,16 +83,24 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 99999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999,
"selfSponsorshipAlgoV3Height": 999999999,
"feeValidationFixTimestamp": 0, "feeValidationFixTimestamp": 0,
"chatReferenceTimestamp": 0, "chatReferenceTimestamp": 0,
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"selfSponsorshipAlgoV2Height": 9999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950, "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999,
"penaltyFixHeight": 5 "penaltyFixHeight": 5
}, },
"genesisInfo": { "genesisInfo": {

View File

@ -85,7 +85,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -95,7 +95,14 @@
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -86,7 +86,7 @@
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"aggregateSignatureTimestamp": 0, "aggregateSignatureTimestamp": 0,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -96,7 +96,14 @@
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -85,7 +85,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -95,7 +95,14 @@
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -85,7 +85,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -95,7 +95,14 @@
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -85,7 +85,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -95,7 +95,14 @@
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 500, "unconfirmableRewardSharesHeight": 500,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -85,7 +85,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -95,7 +95,14 @@
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -85,7 +85,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 20, "selfSponsorshipAlgoV1Height": 20,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -95,7 +95,14 @@
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -85,7 +85,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 30, "selfSponsorshipAlgoV2Height": 30,
@ -95,7 +95,14 @@
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -85,7 +85,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -95,7 +95,14 @@
"arbitraryOptionalFeeTimestamp": 0, "arbitraryOptionalFeeTimestamp": 0,
"unconfirmableRewardSharesHeight": 99999999, "unconfirmableRewardSharesHeight": 99999999,
"disableTransferPrivsTimestamp": 9999999999500, "disableTransferPrivsTimestamp": 9999999999500,
"enableTransferPrivsTimestamp": 9999999999950 "enableTransferPrivsTimestamp": 9999999999950,
"cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,

View File

@ -86,7 +86,7 @@
"transactionV5Timestamp": 0, "transactionV5Timestamp": 0,
"transactionV6Timestamp": 0, "transactionV6Timestamp": 0,
"disableReferenceTimestamp": 9999999999999, "disableReferenceTimestamp": 9999999999999,
"increaseOnlineAccountsDifficultyTimestamp": 9999999999999, "increaseOnlineAccountsDifficultyTimestamp": 9999999999990,
"onlineAccountMinterLevelValidationHeight": 0, "onlineAccountMinterLevelValidationHeight": 0,
"selfSponsorshipAlgoV1Height": 999999999, "selfSponsorshipAlgoV1Height": 999999999,
"selfSponsorshipAlgoV2Height": 999999999, "selfSponsorshipAlgoV2Height": 999999999,
@ -100,8 +100,10 @@
"cancelSellNameValidationTimestamp": 9999999999999, "cancelSellNameValidationTimestamp": 9999999999999,
"disableRewardshareHeight": 9999999999990, "disableRewardshareHeight": 9999999999990,
"enableRewardshareHeight": 9999999999999, "enableRewardshareHeight": 9999999999999,
"onlyMintWithNameHeight": 9999999999999, "onlyMintWithNameHeight": 9999999999990,
"groupMemberCheckHeight": 9999999999999 "groupMemberCheckHeight": 9999999999999,
"decreaseOnlineAccountsDifficultyTimestamp": 9999999999999,
"removeOnlyMintWithNameHeight": 9999999999999
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,