use of org.aion.zero.impl.core.ImportResult in project aion by aionnetwork.
the class DetailsDataStoreIntegTest method largeStorageTransitionBenchmark.
/**
* Creates a contract with large storage. Imports 20 blocks expanding the storage and prints
* times and database size with and without storage transition.
*/
@Ignore
@Test
public void largeStorageTransitionBenchmark() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {
// setup account used to deploy and call the large storage contract
List<ECKey> accounts = generateAccounts(1);
ECKey account = accounts.get(0);
// setup AVM
// clear setting from @Before
AvmTestConfig.clearConfigurations();
TransactionTypeRule.allowAVMContractTransaction();
resourceProvider = TestResourceProvider.initializeAndCreateNewProvider(AvmPathManager.getPathOfProjectRootDirectory());
// enable both AVMs without overlap
AvmTestConfig.supportBothAvmVersions(0, 1, 0);
// setup 3 identical blockchains
StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
StandaloneBlockchain chain = builder.withValidatorConfiguration("simple").withDefaultAccounts(accounts).withAvmEnabled().build().bc;
StandaloneBlockchain chainWithTransition = builder.withValidatorConfiguration("simple").withDefaultAccounts(accounts).withAvmEnabled().build().bc;
StandaloneBlockchain chainWithoutTransition = builder.withValidatorConfiguration("simple").withDefaultAccounts(accounts).withAvmEnabled().build().bc;
// disabling Unity for this test
chain.forkUtility.disableUnityFork();
chainWithTransition.forkUtility.disableUnityFork();
chainWithoutTransition.forkUtility.disableUnityFork();
assertThat(chain).isNotEqualTo(chainWithTransition);
assertThat(chain.genesis).isEqualTo(chainWithTransition.genesis);
assertThat(chain).isNotEqualTo(chainWithoutTransition);
assertThat(chain.genesis).isEqualTo(chainWithoutTransition.genesis);
assertThat(chainWithoutTransition).isNotEqualTo(chainWithTransition);
assertThat(chainWithoutTransition.genesis).isEqualTo(chainWithTransition.genesis);
// deploy the storage contract
BigInteger nonce = BigInteger.ZERO;
AionTransaction tx = deployAvmContractTransaction(AvmContract.LARGE_STORAGE, resourceProvider.factoryForVersion2, account, nonce);
nonce = nonce.add(BigInteger.ONE);
addMiningBlock(chain, chain.getBestBlock(), List.of(tx));
// save the contract address
AionAddress contract = TxUtil.calculateContractAddress(tx);
System.out.println("Contract: " + contract);
List<AionTransaction> txs = new ArrayList<>();
int insertTxPerBlock = 9, updateTxPerBlock = 5, deleteTxPerBlock = 4;
// results in 3*6 blocks with storage in details, 3*6 after transition
int numberOfStorageBlocks = 2 * 6;
LinkedList<byte[]> keys = new LinkedList<>();
// populate chain
for (int i = 0; i < numberOfStorageBlocks; i++) {
// call contract to increase storage
for (int j = 0; j < insertTxPerBlock; j++) {
byte[] key = RandomUtils.nextBytes(32 - i);
txs.add(putToLargeStorageTransaction(resourceProvider.factoryForVersion2, account, key, RandomUtils.nextBytes(32 - i), nonce, contract));
nonce = nonce.add(BigInteger.ONE);
keys.addLast(key);
}
addMiningBlock(chain, chain.getBestBlock(), txs);
// call contract to update storage
for (int j = 0; j < updateTxPerBlock; j++) {
byte[] key = keys.removeFirst();
txs.add(putToLargeStorageTransaction(resourceProvider.factoryForVersion2, account, key, RandomUtils.nextBytes(32 - i - 1), nonce, contract));
nonce = nonce.add(BigInteger.ONE);
keys.addLast(key);
}
addMiningBlock(chain, chain.getBestBlock(), txs);
// call contract to delete storage
for (int j = 0; j < deleteTxPerBlock; j++) {
txs.add(putToLargeStorageTransaction(resourceProvider.factoryForVersion2, account, keys.removeFirst(), null, nonce, contract));
nonce = nonce.add(BigInteger.ONE);
}
addMiningBlock(chain, chain.getBestBlock(), txs);
}
// import the contract block (not part of the benchmark)
Block block = chain.getBlockByNumber(1);
ImportResult importResult = chainWithoutTransition.tryToConnect(block);
assertThat(importResult).isEqualTo(ImportResult.IMPORTED_BEST);
importResult = chainWithTransition.tryToConnect(block);
assertThat(importResult).isEqualTo(ImportResult.IMPORTED_BEST);
long start, duration, storage, details, size;
long totalTimeWithTransition = 0, totalDetailsSizeWithTransition = 0, totalStorageSizeWithTransition = 0, totalSizeWithTransition = 0, totalTimeWithoutTransition = 0, totalDetailsSizeWithoutTransition = 0, totalStorageSizeWithoutTransition = 0, totalSizeWithoutTransition = 0;
int blocks = (int) chain.getBestBlock().getNumber();
long[][] results = new long[blocks + 1][8];
boolean isEmptyStorage = true, isSaved = false;
// generate data by importing each block to the chain with/without transition
for (int i = 2; i <= blocks; i++) {
block = chain.getBlockByNumber(i);
// importing without transition first
// In case there is any bias due to caching, it will disfavour this option.
// Even with any potential nevative bias, the option seems to have better performance.
// AionContractDetailsImpl.detailsInMemoryStorageLimit = 0;
start = System.nanoTime();
importResult = chainWithoutTransition.tryToConnect(block);
duration = System.nanoTime() - start;
assertThat(importResult).isEqualTo(ImportResult.IMPORTED_BEST);
details = chainWithoutTransition.getRepository().detailsDatabase.approximateSize();
storage = chainWithoutTransition.getRepository().storageDatabase.approximateSize();
size = details + storage;
results[i][4] = duration;
results[i][5] = details;
results[i][6] = storage;
results[i][7] = size;
totalTimeWithoutTransition += duration;
totalDetailsSizeWithoutTransition += details;
totalStorageSizeWithoutTransition += storage;
totalSizeWithoutTransition += size;
if (storage != 0 && isEmptyStorage) {
isEmptyStorage = false;
}
if (!isEmptyStorage && !isSaved) {
results[1][0] = totalTimeWithTransition;
results[1][1] = totalDetailsSizeWithTransition;
results[1][2] = totalStorageSizeWithTransition;
results[1][3] = totalSizeWithTransition;
results[1][4] = totalTimeWithoutTransition;
results[1][5] = totalDetailsSizeWithoutTransition;
results[1][6] = totalStorageSizeWithoutTransition;
results[1][7] = totalSizeWithoutTransition;
isSaved = true;
}
}
// Save totals
results[0][0] = totalTimeWithTransition;
results[0][1] = totalDetailsSizeWithTransition;
results[0][2] = totalStorageSizeWithTransition;
results[0][3] = totalSizeWithTransition;
results[0][4] = totalTimeWithoutTransition;
results[0][5] = totalDetailsSizeWithoutTransition;
results[0][6] = totalStorageSizeWithoutTransition;
results[0][7] = totalSizeWithoutTransition;
print(results);
}
use of org.aion.zero.impl.core.ImportResult in project aion by aionnetwork.
the class PendingStateTest method replayTransactionWithDoubleEnergyPriceAfterSealing.
@Test
public void replayTransactionWithDoubleEnergyPriceAfterSealing() {
AionTransaction tx1 = AionTransaction.create(deployerKey, BigInteger.ZERO.toByteArray(), new AionAddress(new byte[32]), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), 1000_000L, energyPrice, TransactionTypes.DEFAULT, null);
AionTransaction tx2 = AionTransaction.create(deployerKey, BigInteger.ZERO.toByteArray(), new AionAddress(new byte[32]), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), 1000_000L, energyPrice * 2, TransactionTypes.DEFAULT, null);
assertEquals(TxResponse.SUCCESS, pendingState.addTransactionFromApiServer(tx1));
assertEquals(TxResponse.REPAID, pendingState.addTransactionFromApiServer(tx2));
assertEquals(1, pendingState.getPendingTxSize());
// tx2 will get cached and will replace tx1 if tx1 is not included in the next block.
assertEquals(pendingState.getPendingTransactions().get(0), tx1);
MiningBlock block = blockchain.createNewMiningBlock(blockchain.getBestBlock(), pendingState.getPendingTransactions(), false);
Pair<ImportResult, AionBlockSummary> connectResult = blockchain.tryToConnectAndFetchSummary(block);
assertEquals(connectResult.getLeft(), ImportResult.IMPORTED_BEST);
pendingState.applyBlockUpdate(block, connectResult.getRight().getReceipts());
assertEquals(0, pendingState.getPendingTxSize());
}
use of org.aion.zero.impl.core.ImportResult in project aion by aionnetwork.
the class PendingStateTest method replayTransactionWithDoubleEnergyPrice.
@Test
public void replayTransactionWithDoubleEnergyPrice() {
AionTransaction tx1 = AionTransaction.create(deployerKey, BigInteger.ZERO.toByteArray(), new AionAddress(new byte[32]), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), 1000_000L, energyPrice, TransactionTypes.DEFAULT, null);
AionTransaction tx2 = AionTransaction.create(deployerKey, BigInteger.ZERO.toByteArray(), new AionAddress(new byte[32]), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), 1000_000L, energyPrice * 2, TransactionTypes.DEFAULT, null);
assertEquals(TxResponse.SUCCESS, pendingState.addTransactionFromApiServer(tx1));
assertEquals(TxResponse.REPAID, pendingState.addTransactionFromApiServer(tx2));
assertEquals(1, pendingState.getPendingTxSize());
// tx2 will get cached and will replace tx1 if tx1 is not included in the next block.
assertEquals(pendingState.getPendingTransactions().get(0), tx1);
MiningBlock block = blockchain.createNewMiningBlock(blockchain.getBestBlock(), Collections.emptyList(), false);
Pair<ImportResult, AionBlockSummary> connectResult = blockchain.tryToConnectAndFetchSummary(block);
assertEquals(connectResult.getLeft(), ImportResult.IMPORTED_BEST);
(pendingState).applyBlockUpdate(block, connectResult.getRight().getReceipts());
assertEquals(pendingState.getPendingTransactions().get(0), tx2);
}
use of org.aion.zero.impl.core.ImportResult in project aion by aionnetwork.
the class PendingStateTest method replayTransactionThatUsesEntireBalance.
@Test
public void replayTransactionThatUsesEntireBalance() {
BigInteger balance = blockchain.getRepository().getBalance(new AionAddress(deployerKey.getAddress()));
BigInteger value = balance.subtract(BigInteger.valueOf(21000 * 3).multiply(BigInteger.valueOf(energyPrice)));
AionTransaction tx1 = AionTransaction.create(deployerKey, BigInteger.ZERO.toByteArray(), new AionAddress(new byte[32]), value.toByteArray(), new byte[0], 21000, energyPrice, TransactionTypes.DEFAULT, null);
AionTransaction tx2 = AionTransaction.create(deployerKey, BigInteger.ONE.toByteArray(), new AionAddress(new byte[32]), BigInteger.ZERO.toByteArray(), new byte[0], 21000, energyPrice, TransactionTypes.DEFAULT, null);
/* tx1 and tx3 should use the entire balance. If tx2 is removed properly, tx3 should be
* able to replace it in the pending state */
AionTransaction tx3 = AionTransaction.create(deployerKey, BigInteger.ONE.toByteArray(), new AionAddress(new byte[32]), BigInteger.ZERO.toByteArray(), new byte[0], 21000, energyPrice * 2, TransactionTypes.DEFAULT, null);
// This would execute fine on top of tx2, but should have insufficient balance on top of tx3
AionTransaction tx4 = AionTransaction.create(deployerKey, BigInteger.TWO.toByteArray(), new AionAddress(new byte[32]), BigInteger.ZERO.toByteArray(), new byte[0], 21000, energyPrice, TransactionTypes.DEFAULT, null);
assertEquals(TxResponse.SUCCESS, pendingState.addTransactionFromApiServer(tx1));
assertEquals(TxResponse.SUCCESS, pendingState.addTransactionFromApiServer(tx2));
assertEquals(TxResponse.REPAID, pendingState.addTransactionFromApiServer(tx3));
assertEquals(TxResponse.SUCCESS, pendingState.addTransactionFromApiServer(tx4));
assertEquals(3, pendingState.getPendingTxSize());
MiningBlock block = blockchain.createNewMiningBlock(blockchain.getBestBlock(), Collections.emptyList(), false);
Pair<ImportResult, AionBlockSummary> connectResult = blockchain.tryToConnectAndFetchSummary(block);
assertEquals(connectResult.getLeft(), ImportResult.IMPORTED_BEST);
pendingState.applyBlockUpdate(block, connectResult.getRight().getReceipts());
// tx3 should replace tx2, and tx4 will now have insufficient funds so it will get dropped
assertEquals(2, pendingState.getPendingTxSize());
assertEquals(pendingState.getPendingTransactions().get(1), tx3);
}
use of org.aion.zero.impl.core.ImportResult in project aion by aionnetwork.
the class PendingStateTest method replayInvalidTransactionInMiddle.
@Test
public void replayInvalidTransactionInMiddle() {
BigInteger balance = blockchain.getRepository().getBalance(new AionAddress(deployerKey.getAddress()));
BigInteger value = balance.subtract(BigInteger.valueOf(21000 * 3).multiply(BigInteger.valueOf(energyPrice)));
AionTransaction tx1 = AionTransaction.create(deployerKey, BigInteger.ZERO.toByteArray(), new AionAddress(new byte[32]), value.toByteArray(), new byte[0], 21000, energyPrice, TransactionTypes.DEFAULT, null);
AionTransaction tx2 = AionTransaction.create(deployerKey, BigInteger.ONE.toByteArray(), new AionAddress(new byte[32]), BigInteger.ZERO.toByteArray(), new byte[0], 21000, energyPrice, TransactionTypes.DEFAULT, null);
AionTransaction tx3 = AionTransaction.create(deployerKey, BigInteger.ONE.toByteArray(), new AionAddress(new byte[32]), BigInteger.ZERO.toByteArray(), new byte[0], 21000, energyPrice * 4, TransactionTypes.DEFAULT, null);
// This tx will get dropped after tx3 is rejected
AionTransaction tx4 = AionTransaction.create(deployerKey, BigInteger.TWO.toByteArray(), new AionAddress(new byte[32]), BigInteger.ZERO.toByteArray(), new byte[0], 21000, energyPrice, TransactionTypes.DEFAULT, null);
assertEquals(TxResponse.SUCCESS, pendingState.addTransactionFromApiServer(tx1));
assertEquals(TxResponse.SUCCESS, pendingState.addTransactionFromApiServer(tx2));
assertEquals(TxResponse.REPAID, pendingState.addTransactionFromApiServer(tx3));
assertEquals(TxResponse.SUCCESS, pendingState.addTransactionFromApiServer(tx4));
assertEquals(3, pendingState.getPendingTxSize());
MiningBlock block = blockchain.createNewMiningBlock(blockchain.getBestBlock(), Collections.emptyList(), false);
Pair<ImportResult, AionBlockSummary> connectResult = blockchain.tryToConnectAndFetchSummary(block);
assertEquals(connectResult.getLeft(), ImportResult.IMPORTED_BEST);
pendingState.applyBlockUpdate(block, connectResult.getRight().getReceipts());
assertEquals(1, pendingState.getPendingTxSize());
}
Aggregations