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);
}
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);
}
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);
}
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);
}
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);
}
Aggregations