Search in sources :

Example 86 with ImportResult

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);
}
Also used : AionAddress(org.aion.types.AionAddress) ImportResult(org.aion.zero.impl.core.ImportResult) ArrayList(java.util.ArrayList) ECKey(org.aion.crypto.ECKey) StandaloneBlockchain(org.aion.zero.impl.blockchain.StandaloneBlockchain) AionTransaction(org.aion.base.AionTransaction) LinkedList(java.util.LinkedList) BigInteger(java.math.BigInteger) Block(org.aion.zero.impl.types.Block) BlockchainTestUtils.addStakingBlock(org.aion.zero.impl.blockchain.BlockchainTestUtils.addStakingBlock) BlockchainTestUtils.addMiningBlock(org.aion.zero.impl.blockchain.BlockchainTestUtils.addMiningBlock) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 87 with ImportResult

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());
}
Also used : AionAddress(org.aion.types.AionAddress) ImportResult(org.aion.zero.impl.core.ImportResult) AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) AionTransaction(org.aion.base.AionTransaction) MiningBlock(org.aion.zero.impl.types.MiningBlock) Test(org.junit.Test)

Example 88 with ImportResult

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);
}
Also used : AionAddress(org.aion.types.AionAddress) ImportResult(org.aion.zero.impl.core.ImportResult) AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) AionTransaction(org.aion.base.AionTransaction) MiningBlock(org.aion.zero.impl.types.MiningBlock) Test(org.junit.Test)

Example 89 with ImportResult

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);
}
Also used : AionAddress(org.aion.types.AionAddress) ImportResult(org.aion.zero.impl.core.ImportResult) AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) BigInteger(java.math.BigInteger) AionTransaction(org.aion.base.AionTransaction) MiningBlock(org.aion.zero.impl.types.MiningBlock) Test(org.junit.Test)

Example 90 with ImportResult

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());
}
Also used : AionAddress(org.aion.types.AionAddress) ImportResult(org.aion.zero.impl.core.ImportResult) AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) BigInteger(java.math.BigInteger) AionTransaction(org.aion.base.AionTransaction) MiningBlock(org.aion.zero.impl.types.MiningBlock) Test(org.junit.Test)

Aggregations

ImportResult (org.aion.zero.impl.core.ImportResult)166 Test (org.junit.Test)127 AionTransaction (org.aion.base.AionTransaction)114 AionAddress (org.aion.types.AionAddress)106 AionBlockSummary (org.aion.zero.impl.types.AionBlockSummary)95 MiningBlock (org.aion.zero.impl.types.MiningBlock)90 Block (org.aion.zero.impl.types.Block)80 BigInteger (java.math.BigInteger)75 AionTxReceipt (org.aion.base.AionTxReceipt)50 AionTxExecSummary (org.aion.base.AionTxExecSummary)31 ECKey (org.aion.crypto.ECKey)28 RepositoryCache (org.aion.base.db.RepositoryCache)22 StandaloneBlockchain (org.aion.zero.impl.blockchain.StandaloneBlockchain)22 InternalTransaction (org.aion.types.InternalTransaction)20 AccountState (org.aion.base.AccountState)18 ArrayList (java.util.ArrayList)17 AionBlockchainImpl.getPostExecutionWorkForGeneratePreBlock (org.aion.zero.impl.blockchain.AionBlockchainImpl.getPostExecutionWorkForGeneratePreBlock)16 Builder (org.aion.zero.impl.blockchain.StandaloneBlockchain.Builder)14 AionRepositoryImpl (org.aion.zero.impl.db.AionRepositoryImpl)10 BlockContext (org.aion.zero.impl.types.BlockContext)9