Search in sources :

Example 66 with AionTransaction

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

the class AvmBulkTransactionTest method sendContractCreationAndCallTransactionsInBulkTest.

@Test
public void sendContractCreationAndCallTransactionsInBulkTest() {
    BigInteger expectedDeployerNonce = getNonce(this.deployerKey);
    // First, deploy a contract that we can call into.
    AionBlockSummary initialSummary = sendTransactionsInBulkInSingleBlock(Collections.singletonList(makeAvmContractCreateTransaction(this.deployerKey, expectedDeployerNonce)));
    expectedDeployerNonce = expectedDeployerNonce.add(BigInteger.ONE);
    // Grab the address of the newly deployed contract.
    AionAddress deployedContract = new AionAddress(initialSummary.getReceipts().get(0).getTransactionOutput());
    int numAvmCreateTransactions = 2;
    int numAvmCallTransactions = 10;
    int numTransactions = numAvmCreateTransactions + numAvmCallTransactions;
    // Grab the initial data we need to track.
    BigInteger initialBalanceDeployer = getBalance(this.deployerKey);
    // Make the create transactions.
    List<AionTransaction> transactions = new ArrayList<>();
    for (int i = 0; i < numAvmCreateTransactions; i++) {
        transactions.add(makeAvmContractCreateTransaction(this.deployerKey, expectedDeployerNonce));
        expectedDeployerNonce = expectedDeployerNonce.add(BigInteger.ONE);
    }
    // Make the call transactions.
    for (int i = 0; i < numAvmCallTransactions; i++) {
        transactions.add(makeAvmContractCallTransaction(this.deployerKey, expectedDeployerNonce, deployedContract));
        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());
    }
    List<AionAddress> contracts = new ArrayList<>();
    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)));
        // The first batch are creates, so grab the new contract addresses.
        if (i < numAvmCreateTransactions) {
            contracts.add(new AionAddress(blockSummary.getSummaries().get(i).getReceipt().getTransactionOutput()));
        }
    }
    // Verify account states after the transactions have been processed.
    for (int i = 0; i < numAvmCreateTransactions; i++) {
        // Check that these contracts have code.
        assertTrue(this.blockchain.getRepository().getCode(contracts.get(i)).length > 0);
        assertEquals(BigInteger.ZERO, getBalance(contracts.get(i)));
        assertEquals(BigInteger.ZERO, getNonce(contracts.get(i)));
    }
    assertEquals(expectedDeployerBalance, getBalance(this.deployerKey));
    assertEquals(expectedDeployerNonce, getNonce(this.deployerKey));
    // Call into the contract to get its current 'count' to verify its state is correct.
    int count = getDeployedStatefulnessCountValue(AvmVersion.VERSION_1, this.deployerKey, expectedDeployerNonce, deployedContract);
    assertEquals(numAvmCallTransactions, count);
}
Also used : AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) AionAddress(org.aion.types.AionAddress) AionTxExecSummary(org.aion.base.AionTxExecSummary) ArrayList(java.util.ArrayList) BigInteger(java.math.BigInteger) AionTransaction(org.aion.base.AionTransaction) Test(org.junit.Test)

Example 67 with AionTransaction

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

the class AvmBulkTransactionTest method importBlockWithContractAndCallsForBothVMsWhereFVMContractIsEmpty.

/**
 * Ensures that a block containing the transactions described below is processed correctly:
 *
 * <ol>
 *   <li>an empty FVM contract deployment,
 *   <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 importBlockWithContractAndCallsForBothVMsWhereFVMContractIsEmpty() {
    BigInteger expectedNonce = getNonce(deployerKey);
    BigInteger initialBalance = getBalance(deployerKey);
    List<AionTransaction> transactions = new ArrayList<>();
    // Deploy empty FVM contract.
    AionTransaction deployTxFVM = AionTransaction.create(deployerKey, expectedNonce.toByteArray(), null, BigInteger.ZERO.toByteArray(), new byte[0], 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)));
    }
    // Verify that the code and storage of the FVM contract are unchanged.
    AccountState fvm = (AccountState) blockchain.getRepository().startTracking().getAccountState(fvmContract);
    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 68 with AionTransaction

use of org.aion.base.AionTransaction 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 69 with AionTransaction

use of org.aion.base.AionTransaction 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 70 with AionTransaction

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

Aggregations

AionTransaction (org.aion.base.AionTransaction)437 Test (org.junit.Test)308 AionAddress (org.aion.types.AionAddress)273 BigInteger (java.math.BigInteger)174 MiningBlock (org.aion.zero.impl.types.MiningBlock)149 ArrayList (java.util.ArrayList)127 ImportResult (org.aion.zero.impl.core.ImportResult)115 AionTxExecSummary (org.aion.base.AionTxExecSummary)103 Block (org.aion.zero.impl.types.Block)102 RepositoryCache (org.aion.base.db.RepositoryCache)89 AionBlockSummary (org.aion.zero.impl.types.AionBlockSummary)87 AionTxReceipt (org.aion.base.AionTxReceipt)75 ECKey (org.aion.crypto.ECKey)52 AionRepositoryImpl (org.aion.zero.impl.db.AionRepositoryImpl)46 BlockContext (org.aion.zero.impl.types.BlockContext)43 PooledTransaction (org.aion.base.PooledTransaction)40 AccountState (org.aion.base.AccountState)39 Properties (java.util.Properties)35 HashMap (java.util.HashMap)33 DataWord (org.aion.util.types.DataWord)29