Search in sources :

Example 21 with AionTxReceipt

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

the class AvmBulkTransactionTest method importBlockWithContractAndCallsForBothVMsOnTopOfAddressesWithBalance.

@Test
public void importBlockWithContractAndCallsForBothVMsOnTopOfAddressesWithBalance() {
    // Enable Fork040 to be able to deploy the contract on FVM.
    blockchain.forkUtility.enable040Fork(1L);
    BigInteger initialNonce = getNonce(deployerKey);
    // Two transactions will be made to add balance to the expected contract addresses.
    BigInteger expectedNonce = initialNonce.add(BigInteger.TWO);
    BigInteger initialBalance = getBalance(deployerKey);
    List<AionTransaction> transactions = new ArrayList<>();
    // Deploy FVM contract.
    String contractCode = "0x605060405234156100105760006000fd5b5b600a600060005081909090555060006000505460016000506000600060005054815260100190815260100160002090506000508190909055506064600260005060000160005081909090555060c8600260005060010160005081909090555060026000506001016000505460016000506000600260005060000160005054815260100190815260100160002090506000508190909055505b6100ae565b610184806100bd6000396000f30060506040526000356c01000000000000000000000000900463ffffffff1680631677b0ff14610049578063209652551461007657806362eb702a146100a057610043565b60006000fd5b34156100555760006000fd5b61007460048080359060100190919080359060100190919050506100c4565b005b34156100825760006000fd5b61008a610111565b6040518082815260100191505060405180910390f35b34156100ac5760006000fd5b6100c26004808035906010019091905050610123565b005b8160026000506000016000508190909055508060026000506001016000508190909055508082016001600050600084815260100190815260100160002090506000508190909055505b5050565b60006000600050549050610120565b90565b806000600050819090905550600181016001600050600083815260100190815260100160002090506000508190909055505b505600a165627a7a723058205b6e690d70d3703337452467437dc7c4e863ee4ad34b24cc516e2afa71e334700029";
    AionTransaction deployTxFVM = AionTransaction.create(deployerKey, expectedNonce.toByteArray(), null, BigInteger.ZERO.toByteArray(), ByteUtil.hexStringToBytes(contractCode), 5_000_000L, energyPrice, TransactionTypes.DEFAULT, null);
    AionAddress fvmContract = TxUtil.calculateContractAddress(deployTxFVM);
    transactions.add(deployTxFVM);
    expectedNonce = expectedNonce.add(BigInteger.ONE);
    // Deploy AVM contract.
    AionTransaction deployTxAVM = makeAvmContractCreateTransaction(deployerKey, expectedNonce);
    AionAddress avmContract = TxUtil.calculateContractAddress(deployTxAVM);
    transactions.add(deployTxAVM);
    expectedNonce = expectedNonce.add(BigInteger.ONE);
    // Call FVM contract.
    AionTransaction contractCallTx = AionTransaction.create(deployerKey, expectedNonce.toByteArray(), fvmContract, BigInteger.ZERO.toByteArray(), Hex.decode("62eb702a00000000000000000000000000000006"), 2_000_000L, energyPrice, TransactionTypes.DEFAULT, null);
    transactions.add(contractCallTx);
    expectedNonce = expectedNonce.add(BigInteger.ONE);
    // Call AVM contract.
    transactions.add(makeAvmContractCallTransaction(deployerKey, expectedNonce, avmContract));
    expectedNonce = expectedNonce.add(BigInteger.ONE);
    // First, send balance to the two future contracts.
    AionTransaction balanceTransferToFVM = AionTransaction.create(deployerKey, initialNonce.toByteArray(), fvmContract, BigInteger.TEN.toByteArray(), new byte[0], 2_000_000L, energyPrice, TransactionTypes.DEFAULT, null);
    AionTransaction balanceTransferToAVM = AionTransaction.create(deployerKey, initialNonce.add(BigInteger.ONE).toByteArray(), avmContract, BigInteger.TEN.toByteArray(), new byte[0], 2_000_000L, energyPrice, TransactionTypes.DEFAULT, null);
    BigInteger expectedBalance = initialBalance.subtract(BigInteger.TEN).subtract(BigInteger.TEN);
    AionBlockSummary blockSummary = sendTransactionsInBulkInSingleBlock(List.of(balanceTransferToFVM, balanceTransferToAVM));
    // Verify that all transactions were successful.
    assertThat(blockSummary.getSummaries().size()).isEqualTo(2);
    for (AionTxExecSummary transactionSummary : blockSummary.getSummaries()) {
        AionTxReceipt receipt = transactionSummary.getReceipt();
        assertThat(receipt.isSuccessful()).isTrue();
        // Compute the expected balance.
        expectedBalance = expectedBalance.subtract(BigInteger.valueOf(receipt.getEnergyUsed()).multiply(BigInteger.valueOf(energyPrice)));
    }
    // Next, process the 4 transactions in a single block.
    blockSummary = sendTransactionsInBulkInSingleBlock(transactions);
    // Verify that all transactions were successful.
    assertThat(blockSummary.getSummaries().size()).isEqualTo(4);
    for (AionTxExecSummary transactionSummary : blockSummary.getSummaries()) {
        AionTxReceipt receipt = transactionSummary.getReceipt();
        assertThat(receipt.isSuccessful()).isTrue();
        // Compute the expected balance.
        expectedBalance = expectedBalance.subtract(BigInteger.valueOf(receipt.getEnergyUsed()).multiply(BigInteger.valueOf(energyPrice)));
    }
    assertThat(getBalance(deployerKey)).isEqualTo(expectedBalance);
    assertThat(getNonce(deployerKey)).isEqualTo(expectedNonce);
}
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) AionTxReceipt(org.aion.base.AionTxReceipt) Test(org.junit.Test)

Example 22 with AionTxReceipt

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

the class AvmBulkTransactionTest method importBlockWithContractAndCallsForBothVMsWhereFVMContractHashStorageOnly.

/**
 * Ensures that a block containing the transactions described below is processed correctly:
 *
 * <ol>
 *   <li>an FVM contract deployment with storage (interpreted as empty),
 *   <li>an AVM contract deployment,
 *   <li>an FVM call to the first contract,
 *   <li>an AVM call to the second contract.
 * </ol>
 */
@Test
public void importBlockWithContractAndCallsForBothVMsWhereFVMContractHashStorageOnly() {
    BigInteger expectedNonce = getNonce(deployerKey);
    BigInteger initialBalance = getBalance(deployerKey);
    List<AionTransaction> transactions = new ArrayList<>();
    // Deploy storage-only FVM contract with data [PUSH1 0x80 PUSH1 0x80 SSTORE] (the storage change will not be registered by the kernel).
    AionTransaction deployTxFVM = AionTransaction.create(deployerKey, expectedNonce.toByteArray(), null, BigInteger.ZERO.toByteArray(), Hex.decode("6080608055"), 5_000_000L, energyPrice, TransactionTypes.DEFAULT, null);
    AionAddress fvmContract = TxUtil.calculateContractAddress(deployTxFVM);
    transactions.add(deployTxFVM);
    expectedNonce = expectedNonce.add(BigInteger.ONE);
    // Deploy AVM contract.
    AionTransaction deployTxAVM = makeAvmContractCreateTransaction(deployerKey, expectedNonce);
    AionAddress avmContract = TxUtil.calculateContractAddress(deployTxAVM);
    transactions.add(deployTxAVM);
    expectedNonce = expectedNonce.add(BigInteger.ONE);
    // Call FVM contract with code data that will be ignored by the VM because the contract has no code.
    AionTransaction contractCallTx = AionTransaction.create(deployerKey, expectedNonce.toByteArray(), fvmContract, BigInteger.ZERO.toByteArray(), Hex.decode("6080608055"), 2_000_000L, energyPrice, TransactionTypes.DEFAULT, null);
    transactions.add(contractCallTx);
    expectedNonce = expectedNonce.add(BigInteger.ONE);
    // Call AVM contract.
    transactions.add(makeAvmContractCallTransaction(deployerKey, expectedNonce, avmContract));
    expectedNonce = expectedNonce.add(BigInteger.ONE);
    // Process the 4 transactions in a single block.
    AionBlockSummary blockSummary = sendTransactionsInBulkInSingleBlock(transactions);
    // Verify that all transactions were successful.
    assertThat(blockSummary.getSummaries().size()).isEqualTo(4);
    BigInteger expectedBalance = initialBalance;
    for (AionTxExecSummary transactionSummary : blockSummary.getSummaries()) {
        AionTxReceipt receipt = transactionSummary.getReceipt();
        assertThat(receipt.isSuccessful()).isTrue();
        // Compute the expected balance.
        expectedBalance = expectedBalance.subtract(BigInteger.valueOf(receipt.getEnergyUsed()).multiply(BigInteger.valueOf(energyPrice)));
    }
    AccountState fvm = (AccountState) blockchain.getRepository().startTracking().getAccountState(fvmContract);
    // The current implementation does not allow storage-only contracts. They result in empty storage and code.
    assertThat(fvm.getStateRoot()).isEqualTo(EMPTY_TRIE_HASH);
    assertThat(fvm.getCodeHash()).isEqualTo(EMPTY_DATA_HASH);
    assertThat(getBalance(deployerKey)).isEqualTo(expectedBalance);
    assertThat(getNonce(deployerKey)).isEqualTo(expectedNonce);
}
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) AionTxReceipt(org.aion.base.AionTxReceipt) AccountState(org.aion.base.AccountState) Test(org.junit.Test)

Example 23 with AionTxReceipt

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

the class AvmBulkTransactionTest method importBlockWithContractAndCallsForAvmOnTopOfAddressWithBalance.

@Test
public void importBlockWithContractAndCallsForAvmOnTopOfAddressWithBalance() {
    BigInteger initialNonce = getNonce(deployerKey);
    // One transaction will be made to add balance to the expected contract address before the contract deployment.
    BigInteger expectedNonce = initialNonce.add(BigInteger.ONE);
    BigInteger initialBalance = getBalance(deployerKey);
    List<AionTransaction> transactions = new ArrayList<>();
    // Deploy AVM contract.
    AionTransaction deployTxAVM = makeAvmContractCreateTransaction(deployerKey, expectedNonce);
    AionAddress avmContract = TxUtil.calculateContractAddress(deployTxAVM);
    transactions.add(deployTxAVM);
    expectedNonce = expectedNonce.add(BigInteger.ONE);
    // Call AVM contract.
    transactions.add(makeAvmContractCallTransaction(deployerKey, expectedNonce, avmContract));
    expectedNonce = expectedNonce.add(BigInteger.ONE);
    // First send balance to the future contract.
    AionTransaction balanceTransferToAVM = AionTransaction.create(deployerKey, initialNonce.toByteArray(), avmContract, BigInteger.TEN.toByteArray(), new byte[0], 2_000_000L, energyPrice, TransactionTypes.DEFAULT, null);
    AionBlockSummary blockSummary = sendTransactionsInBulkInSingleBlock(List.of(balanceTransferToAVM));
    // Verify that the transaction was successful.
    assertThat(blockSummary.getSummaries().size()).isEqualTo(1);
    AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt();
    assertThat(receipt.isSuccessful()).isTrue();
    BigInteger expectedBalance = initialBalance.subtract(BigInteger.TEN).subtract(BigInteger.valueOf(receipt.getEnergyUsed()).multiply(BigInteger.valueOf(energyPrice)));
    AccountState contractState = (AccountState) blockchain.getRepository().startTracking().getAccountState(avmContract);
    assertThat(contractState.getBalance()).isEqualTo(BigInteger.TEN);
    assertThat(contractState.getStateRoot()).isEqualTo(EMPTY_TRIE_HASH);
    assertThat(contractState.getCodeHash()).isEqualTo(EMPTY_DATA_HASH);
    // Next, process the 2 transactions in a single block.
    blockSummary = sendTransactionsInBulkInSingleBlock(transactions);
    // Verify that all transactions were successful.
    assertThat(blockSummary.getSummaries().size()).isEqualTo(2);
    for (AionTxExecSummary transactionSummary : blockSummary.getSummaries()) {
        receipt = transactionSummary.getReceipt();
        assertThat(receipt.isSuccessful()).isTrue();
        // Compute the expected balance.
        expectedBalance = expectedBalance.subtract(BigInteger.valueOf(receipt.getEnergyUsed()).multiply(BigInteger.valueOf(energyPrice)));
    }
    contractState = (AccountState) blockchain.getRepository().startTracking().getAccountState(avmContract);
    assertThat(contractState.getBalance()).isEqualTo(BigInteger.TEN);
    assertThat(contractState.getStateRoot()).isNotEqualTo(EMPTY_TRIE_HASH);
    assertThat(contractState.getCodeHash()).isNotEqualTo(EMPTY_DATA_HASH);
    assertThat(getBalance(deployerKey)).isEqualTo(expectedBalance);
    assertThat(getNonce(deployerKey)).isEqualTo(expectedNonce);
}
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) AionTxReceipt(org.aion.base.AionTxReceipt) AccountState(org.aion.base.AccountState) Test(org.junit.Test)

Example 24 with AionTxReceipt

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

the class AvmInternalTxTest method makeCall.

private void makeCall(BigInteger nonce, AionAddress contract, byte[] call) {
    AionTransaction transaction = AionTransaction.create(deployerKey, nonce.toByteArray(), contract, new byte[0], call, 2_000_000, minEnergyPrice, TransactionTypes.DEFAULT, null);
    MiningBlock block = this.blockchain.createNewMiningBlock(this.blockchain.getBestBlock(), Collections.singletonList(transaction), false);
    Pair<ImportResult, AionBlockSummary> connectResult = this.blockchain.tryToConnectAndFetchSummary(block);
    AionTxReceipt receipt = connectResult.getRight().getReceipts().get(0);
    // Check the block was imported and the transaction was successful.
    assertThat(connectResult.getLeft()).isEqualTo(ImportResult.IMPORTED_BEST);
    assertThat(receipt.isSuccessful()).isTrue();
    System.out.println(block);
}
Also used : ImportResult(org.aion.zero.impl.core.ImportResult) AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) AionTransaction(org.aion.base.AionTransaction) AionTxReceipt(org.aion.base.AionTxReceipt) MiningBlock(org.aion.zero.impl.types.MiningBlock)

Example 25 with AionTxReceipt

use of org.aion.base.AionTxReceipt 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)

Aggregations

AionTxReceipt (org.aion.base.AionTxReceipt)111 Test (org.junit.Test)76 AionTransaction (org.aion.base.AionTransaction)74 AionBlockSummary (org.aion.zero.impl.types.AionBlockSummary)61 AionAddress (org.aion.types.AionAddress)56 BigInteger (java.math.BigInteger)53 ImportResult (org.aion.zero.impl.core.ImportResult)50 MiningBlock (org.aion.zero.impl.types.MiningBlock)43 ArrayList (java.util.ArrayList)24 Block (org.aion.zero.impl.types.Block)24 AionTxExecSummary (org.aion.base.AionTxExecSummary)17 RepositoryCache (org.aion.base.db.RepositoryCache)17 StandaloneBlockchain (org.aion.zero.impl.blockchain.StandaloneBlockchain)15 Builder (org.aion.zero.impl.blockchain.StandaloneBlockchain.Builder)14 ECKey (org.aion.crypto.ECKey)12 SolidityType (org.aion.solidity.SolidityType)10 AccountState (org.aion.base.AccountState)9 Log (org.aion.types.Log)9 AionTxInfo (org.aion.zero.impl.types.AionTxInfo)7 StakingBlock (org.aion.zero.impl.types.StakingBlock)7