Search in sources :

Example 36 with AionTxExecSummary

use of org.aion.base.AionTxExecSummary in project aion by aionnetwork.

the class AvmBulkTransactionTest method sendValueTransferTransactionsInBulkTest.

@Test
public void sendValueTransferTransactionsInBulkTest() {
    int numTransactions = 50;
    // Create the accounts.
    List<ECKey> accounts = getRandomAccounts(numTransactions);
    // Grab the initial data we need to track.
    BigInteger expectedDeployerNonce = getNonce(this.deployerKey);
    BigInteger initialBalanceDeployer = getBalance(this.deployerKey);
    // Declare the various transfer amounts.
    List<BigInteger> transferAmounts = getRandomValues(numTransactions, 500, 5_000_000);
    printValuesUsed(transferAmounts);
    // Make the transactions, then bundle them up together.
    List<AionTransaction> transactions = new ArrayList<>();
    for (int i = 0; i < numTransactions; i++) {
        transactions.add(makeValueTransferTransaction(this.deployerKey, accounts.get(i), transferAmounts.get(i), expectedDeployerNonce));
        expectedDeployerNonce = expectedDeployerNonce.add(BigInteger.ONE);
    }
    // Process the transactions in bulk.
    AionBlockSummary blockSummary = sendTransactionsInBulkInSingleBlock(transactions);
    // Verify all transactions were successful.
    assertEquals(numTransactions, blockSummary.getSummaries().size());
    for (AionTxExecSummary transactionSummary : blockSummary.getSummaries()) {
        assertTrue(transactionSummary.getReceipt().isSuccessful());
    }
    BigInteger expectedDeployerBalance = initialBalanceDeployer;
    for (int i = 0; i < numTransactions; i++) {
        BigInteger energyUsed = BigInteger.valueOf(blockSummary.getSummaries().get(i).getReceipt().getEnergyUsed());
        expectedDeployerBalance = expectedDeployerBalance.subtract(energyUsed.multiply(BigInteger.valueOf(energyPrice))).subtract(transferAmounts.get(i));
    }
    // Verify account states after the transactions have been processed.
    for (int i = 0; i < numTransactions; i++) {
        assertEquals(transferAmounts.get(i), getBalance(accounts.get(i)));
        assertEquals(BigInteger.ZERO, getNonce(accounts.get(i)));
    }
    assertEquals(expectedDeployerBalance, getBalance(this.deployerKey));
    assertEquals(expectedDeployerNonce, getNonce(this.deployerKey));
}
Also used : AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) AionTxExecSummary(org.aion.base.AionTxExecSummary) ArrayList(java.util.ArrayList) BigInteger(java.math.BigInteger) ECKey(org.aion.crypto.ECKey) AionTransaction(org.aion.base.AionTransaction) Test(org.junit.Test)

Example 37 with AionTxExecSummary

use of org.aion.base.AionTxExecSummary in project aion by aionnetwork.

the class AvmBulkTransactionTest method importBlockWithContractDeploysAndSubsequentCalls.

/**
 * Ensures that AVM contracts can be deployed and called within the same block.
 */
@Test
public void importBlockWithContractDeploysAndSubsequentCalls() {
    BigInteger expectedNonce = getNonce(deployerKey);
    BigInteger initialBalance = getBalance(deployerKey);
    // note: 3 contract deployments would pass the block energy limit
    int nbCreateTransactions = 2;
    int nbCallTransactions = 2;
    int nbTransactions = nbCreateTransactions + nbCreateTransactions * nbCallTransactions;
    List<AionTransaction> transactions = new ArrayList<>();
    for (int j = 0; j < nbCreateTransactions; j++) {
        // create contract transaction
        AionTransaction deployTx = makeAvmContractCreateTransaction(deployerKey, expectedNonce);
        expectedNonce = expectedNonce.add(BigInteger.ONE);
        AionAddress deployedContract = TxUtil.calculateContractAddress(deployTx);
        transactions.add(deployTx);
        // subsequent call transactions
        for (int i = 0; i < nbCallTransactions; i++) {
            transactions.add(makeAvmContractCallTransaction(deployerKey, expectedNonce, deployedContract));
            expectedNonce = expectedNonce.add(BigInteger.ONE);
        }
    }
    // process the transactions in bulk
    AionBlockSummary blockSummary = sendTransactionsInBulkInSingleBlock(transactions);
    // verify all transactions were successful
    assertEquals(nbTransactions, blockSummary.getSummaries().size());
    for (AionTxExecSummary transactionSummary : blockSummary.getSummaries()) {
        System.out.println(transactionSummary.getReceipt());
        assertTrue(transactionSummary.getReceipt().isSuccessful());
    }
    BigInteger expectedBalance = initialBalance;
    for (int i = 0; i < nbTransactions; i++) {
        BigInteger energyUsed = BigInteger.valueOf(blockSummary.getSummaries().get(i).getReceipt().getEnergyUsed());
        expectedBalance = expectedBalance.subtract(energyUsed.multiply(BigInteger.valueOf(energyPrice)));
    }
    assertEquals(expectedBalance, getBalance(deployerKey));
    assertEquals(expectedNonce, getNonce(deployerKey));
}
Also used : AionAddress(org.aion.types.AionAddress) AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) AionTxExecSummary(org.aion.base.AionTxExecSummary) ArrayList(java.util.ArrayList) BigInteger(java.math.BigInteger) AionTransaction(org.aion.base.AionTransaction) Test(org.junit.Test)

Example 38 with AionTxExecSummary

use of org.aion.base.AionTxExecSummary in project aion by aionnetwork.

the class AionBlockchainImpl method add.

/**
 * @Param flushRepo true for the kernel runtime import and false for the DBUtil
 */
private Pair<AionBlockSummary, RepositoryCache> add(BlockWrapper blockWrapper) {
    // reset cached VMs before processing the block
    repository.clearCachedVMs();
    Block block = blockWrapper.block;
    if (!blockWrapper.validatedHeader && !isValid(block)) {
        LOG.error("Attempting to add {} block.", (block == null ? "NULL" : "INVALID"));
        return Pair.of(null, null);
    }
    track = repository.startTracking();
    byte[] origRoot = repository.getRoot();
    // (if not reconstructing old blocks) keep chain continuity
    if (!blockWrapper.reBuild && !Arrays.equals(bestBlock.getHash(), block.getParentHash())) {
        LOG.error("Attempting to add NON-SEQUENTIAL block.");
        return Pair.of(null, null);
    }
    if (blockWrapper.reBuild) {
        // when recovering blocks do not touch the cache
        executionTypeForAVM = BlockCachingContext.DEEP_SIDECHAIN;
        cachedBlockNumberForAVM = 0;
    }
    AionBlockSummary summary = processBlock(block);
    List<AionTxExecSummary> transactionSummaries = summary.getSummaries();
    List<AionTxReceipt> receipts = summary.getReceipts();
    if (!isValidBlock(block, transactionSummaries, receipts, isException(block.getNumber()), LOG)) {
        track.rollback();
        return Pair.of(null, null);
    }
    if (blockWrapper.skipRepoFlush) {
        return Pair.of(summary, track);
    }
    track.flushTo(repository, true);
    repository.commitCachedVMs(block.getHashWrapper());
    if (blockWrapper.reBuild) {
        List<AionTxExecSummary> execSummaries = summary.getSummaries();
        for (int i = 0; i < receipts.size(); i++) {
            AionTxInfo infoWithInternalTxs = AionTxInfo.newInstanceWithInternalTransactions(receipts.get(i), block.getHashWrapper(), i, execSummaries.get(i).getInternalTransactions());
            if (storeInternalTransactions) {
                transactionStore.putTxInfoToBatch(infoWithInternalTxs);
            } else {
                AionTxInfo info = AionTxInfo.newInstance(receipts.get(i), block.getHashWrapper(), i);
                transactionStore.putTxInfoToBatch(info);
            }
            if (execSummaries.get(i).getInternalTransactions().size() > 0) {
                transactionStore.putAliasesToBatch(infoWithInternalTxs);
            }
        }
        transactionStore.flushBatch();
        repository.commitBlock(block.getHashWrapper(), block.getNumber(), block.getStateRoot());
        LOG.debug("Block rebuilt: number: {}, hash: {}, TD: {}", block.getNumber(), block.getShortHash(), getTotalDifficulty());
    } else {
        if (!isValidStateRoot(block, repository.getRoot(), LOG)) {
            // block is bad so 'rollback' the state root to the original state
            repository.setRoot(origRoot);
            return Pair.of(null, null);
        }
    }
    return Pair.of(summary, null);
}
Also used : AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) AionTxInfo(org.aion.zero.impl.types.AionTxInfo) AionTxExecSummary(org.aion.base.AionTxExecSummary) Block(org.aion.zero.impl.types.Block) BlockDetailsValidator.isValidBlock(org.aion.zero.impl.valid.BlockDetailsValidator.isValidBlock) GenesisStakingBlock(org.aion.zero.impl.types.GenesisStakingBlock) RetValidPreBlock(org.aion.zero.impl.types.RetValidPreBlock) MiningBlock(org.aion.zero.impl.types.MiningBlock) EventBlock(org.aion.evtmgr.impl.evt.EventBlock) StakingBlock(org.aion.zero.impl.types.StakingBlock) AionTxReceipt(org.aion.base.AionTxReceipt)

Example 39 with AionTxExecSummary

use of org.aion.base.AionTxExecSummary in project aion by aionnetwork.

the class AionBlockchainImpl method applyBlock.

private AionBlockSummary applyBlock(Block block) {
    long saveTime = System.nanoTime();
    List<AionTxReceipt> receipts = new ArrayList<>();
    List<AionTxExecSummary> summaries = new ArrayList<>();
    if (!block.getTransactionsList().isEmpty()) {
        // might apply the block before the 040 fork point.
        boolean fork040Enable = forkUtility.is040ForkActive(block.getNumber());
        if (fork040Enable) {
            TransactionTypeRule.allowAVMContractTransaction();
        }
        if (forkUtility.isSignatureSwapForkActive(block.getNumber())) {
            HashUtil.setAfterSignatureSwap();
        } else {
            HashUtil.setBeforeSignatureSwap();
        }
        try {
            // Booleans moved out here so their meaning is explicit.
            boolean isLocalCall = false;
            boolean incrementSenderNonce = true;
            boolean checkBlockEnergyLimit = false;
            List<AionTxExecSummary> executionSummaries = BulkExecutor.executeAllTransactionsInBlock(block.getDifficulty(), block.getNumber(), block.getTimestamp(), block.getNrgLimit(), block.getCoinbase(), block.getTransactionsList(), track, isLocalCall, incrementSenderNonce, fork040Enable, checkBlockEnergyLimit, LOGGER_VM, getPostExecutionWorkForApplyBlock(repository), executionTypeForAVM, cachedBlockNumberForAVM, forkUtility.isUnityForkActive(block.getNumber()), forkUtility.isSignatureSwapForkActive(block.getNumber()));
            // Check for rejected transaction already included in the chain.
            if (isException(block.getNumber())) {
                for (AionTxExecSummary summary : executionSummaries) {
                    if (summary.isRejected()) {
                        AionTxReceipt receipt = summary.getReceipt();
                        receipt.setNrgUsed(receipt.getTransaction().getEnergyLimit());
                    }
                }
            }
            for (AionTxExecSummary summary : executionSummaries) {
                receipts.add(summary.getReceipt());
                summaries.add(summary);
            }
        } catch (VmFatalException e) {
            LOG.error("Shutdown due to a VM fatal error.", e);
            System.exit(SystemExitCodes.FATAL_VM_ERROR);
        }
    }
    Map<AionAddress, BigInteger> rewards = addReward(block);
    return new AionBlockSummary(block, rewards, receipts, summaries);
}
Also used : AionAddress(org.aion.types.AionAddress) AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) AionTxExecSummary(org.aion.base.AionTxExecSummary) ArrayList(java.util.ArrayList) VmFatalException(org.aion.zero.impl.vm.common.VmFatalException) BigInteger(java.math.BigInteger) AionTxReceipt(org.aion.base.AionTxReceipt)

Example 40 with AionTxExecSummary

use of org.aion.base.AionTxExecSummary in project aion by aionnetwork.

the class AionBlockchainImpl method generatePreBlock.

/**
 * For generating the necessary transactions for a block
 *
 * @param block
 * @return
 */
private RetValidPreBlock generatePreBlock(Block block) {
    long saveTime = System.nanoTime();
    List<AionTxReceipt> receipts = new ArrayList<>();
    List<AionTxExecSummary> summaries = new ArrayList<>();
    List<AionTransaction> transactions = new ArrayList<>();
    if (!block.getTransactionsList().isEmpty()) {
        boolean fork040Enable = forkUtility.is040ForkActive(block.getNumber());
        if (fork040Enable) {
            TransactionTypeRule.allowAVMContractTransaction();
        }
        try {
            // Booleans moved out here so their meaning is explicit.
            boolean isLocalCall = false;
            boolean incrementSenderNonce = true;
            boolean checkBlockEnergyLimit = true;
            List<AionTxExecSummary> executionSummaries = BulkExecutor.executeAllTransactionsInBlock(block.getDifficulty(), block.getNumber(), block.getTimestamp(), block.getNrgLimit(), block.getCoinbase(), block.getTransactionsList(), track, isLocalCall, incrementSenderNonce, fork040Enable, checkBlockEnergyLimit, LOGGER_VM, getPostExecutionWorkForGeneratePreBlock(repository), BlockCachingContext.PENDING, bestBlock.getNumber(), forkUtility.isUnityForkActive(block.getNumber()), forkUtility.isSignatureSwapForkActive(block.getNumber()));
            for (AionTxExecSummary summary : executionSummaries) {
                if (!summary.isRejected()) {
                    transactions.add(summary.getTransaction());
                    receipts.add(summary.getReceipt());
                    summaries.add(summary);
                }
            }
        } catch (VmFatalException e) {
            LOG.error("Shutdown due to a VM fatal error.", e);
            System.exit(SystemExitCodes.FATAL_VM_ERROR);
        }
    }
    Map<AionAddress, BigInteger> rewards = addReward(block);
    return new RetValidPreBlock(transactions, rewards, receipts, summaries);
}
Also used : AionAddress(org.aion.types.AionAddress) RetValidPreBlock(org.aion.zero.impl.types.RetValidPreBlock) AionTxExecSummary(org.aion.base.AionTxExecSummary) ArrayList(java.util.ArrayList) AionTransaction(org.aion.base.AionTransaction) VmFatalException(org.aion.zero.impl.vm.common.VmFatalException) BigInteger(java.math.BigInteger) AionTxReceipt(org.aion.base.AionTxReceipt)

Aggregations

AionTxExecSummary (org.aion.base.AionTxExecSummary)121 AionTransaction (org.aion.base.AionTransaction)103 AionAddress (org.aion.types.AionAddress)98 Test (org.junit.Test)97 RepositoryCache (org.aion.base.db.RepositoryCache)72 BigInteger (java.math.BigInteger)66 AccountState (org.aion.base.AccountState)37 ImportResult (org.aion.zero.impl.core.ImportResult)31 MiningBlock (org.aion.zero.impl.types.MiningBlock)26 ArrayList (java.util.ArrayList)22 AionRepositoryCache (org.aion.zero.impl.db.AionRepositoryCache)22 InternalTransaction (org.aion.types.InternalTransaction)20 Block (org.aion.zero.impl.types.Block)20 BlockContext (org.aion.zero.impl.types.BlockContext)19 DataWord (org.aion.util.types.DataWord)18 AionBlockchainImpl.getPostExecutionWorkForGeneratePreBlock (org.aion.zero.impl.blockchain.AionBlockchainImpl.getPostExecutionWorkForGeneratePreBlock)18 AionBlockSummary (org.aion.zero.impl.types.AionBlockSummary)18 AionTxReceipt (org.aion.base.AionTxReceipt)17 Bloom (org.aion.base.Bloom)5 ECKey (org.aion.crypto.ECKey)5