Search in sources :

Example 21 with AionTxExecSummary

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

the class ContractIntegTest method testFvmConstructorIsCalledOnCodeDeployment.

@Test
public void testFvmConstructorIsCalledOnCodeDeployment() throws Exception {
    String contractName = "MultiFeatureContract";
    byte[] deployCode = ContractUtils.getContractDeployer("MultiFeatureContract.sol", "MultiFeatureContract");
    long nrg = 1_000_000;
    long nrgPrice = energyPrice;
    BigInteger value = BigInteger.ONE;
    BigInteger nonce = BigInteger.ZERO;
    AionTransaction tx = AionTransaction.create(deployerKey, nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, nrgPrice, txType, null);
    RepositoryCache repo = blockchain.getRepository().startTracking();
    nonce = nonce.add(BigInteger.ONE);
    AionAddress contract = deployContract(repo, tx, contractName, null, value, nrg, nrgPrice, nonce);
    if (txType == TransactionTypes.DEFAULT) {
        // Now call the contract and check that the constructor message was set.
        String getMsgFunctionHash = "ce6d41de";
        tx = AionTransaction.create(deployerKey, nonce.toByteArray(), contract, BigInteger.ZERO.toByteArray(), Hex.decode(getMsgFunctionHash), nrg, nrgPrice, txType, null);
        assertFalse(tx.isContractCreationTransaction());
        MiningBlock block = makeBlock(tx);
        AionTxExecSummary summary = executeTransaction(tx, block, repo);
        assertEquals("", summary.getReceipt().getError());
        assertNotEquals(nrg, summary.getNrgUsed().longValue());
        String expectedMsg = "Im alive!";
        assertEquals(expectedMsg, new String(extractOutput(summary.getResult())));
    } else if (txType == TransactionTypes.AVM_CREATE_CODE) {
        assertNull(contract);
    }
}
Also used : AionAddress(org.aion.types.AionAddress) AionTxExecSummary(org.aion.base.AionTxExecSummary) BigInteger(java.math.BigInteger) AionRepositoryCache(org.aion.zero.impl.db.AionRepositoryCache) RepositoryCache(org.aion.base.db.RepositoryCache) AionTransaction(org.aion.base.AionTransaction) MiningBlock(org.aion.zero.impl.types.MiningBlock) Test(org.junit.Test)

Example 22 with AionTxExecSummary

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

the class ContractIntegTest method tellFvmContractCallAvmContract.

@Test
public void tellFvmContractCallAvmContract() throws Exception {
    if (txType == TransactionTypes.AVM_CREATE_CODE) {
        return;
    }
    String contractName = "InternalCallContract";
    byte[] deployCode = getDeployCode(contractName);
    long nrg = Constants.NRG_TRANSACTION_MAX;
    long nrgPrice = energyPrice;
    BigInteger value = BigInteger.ZERO;
    BigInteger nonce = BigInteger.ZERO;
    AionTransaction tx = AionTransaction.create(deployerKey, nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, nrgPrice, txType, null);
    RepositoryCache repo = blockchain.getRepository().startTracking();
    nonce = nonce.add(BigInteger.ONE);
    AionAddress contract = deployContract(repo, tx, contractName, null, value, nrg, nrgPrice, nonce, true);
    assertNotNull(contract);
    repo = blockchain.getRepository().startTracking();
    AionAddress avmAddress = deployAvmContract(AvmVersion.VERSION_1, nonce);
    assertNotNull(avmAddress);
    nonce = nonce.add(BigInteger.ONE);
    byte[] input = Arrays.copyOfRange(HashUtil.keccak256("callAVM(address)".getBytes()), 0, 4);
    input = ByteUtil.merge(input, avmAddress.toByteArray());
    tx = AionTransaction.create(deployerKey, nonce.toByteArray(), contract, BigInteger.ZERO.toByteArray(), input, nrg, nrgPrice, txType, null);
    assertFalse(tx.isContractCreationTransaction());
    MiningBlock block = makeBlock(tx);
    AionTxExecSummary summary = executeTransaction(tx, block, repo);
    // The evmjit only return the the transaction success or failed when performing the function
    // call.
    assertEquals("reverted", summary.getReceipt().getError());
    assertNotEquals(nrg, summary.getNrgUsed().longValue());
    Pair<ImportResult, AionBlockSummary> result = blockchain.tryToConnectAndFetchSummary(block);
    assertTrue(result.getLeft().isSuccessful());
    assertTrue(result.getRight().getSummaries().get(0).isFailed());
}
Also used : AionAddress(org.aion.types.AionAddress) ImportResult(org.aion.zero.impl.core.ImportResult) AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) AionTxExecSummary(org.aion.base.AionTxExecSummary) BigInteger(java.math.BigInteger) AionRepositoryCache(org.aion.zero.impl.db.AionRepositoryCache) RepositoryCache(org.aion.base.db.RepositoryCache) AionTransaction(org.aion.base.AionTransaction) MiningBlock(org.aion.zero.impl.types.MiningBlock) Test(org.junit.Test)

Example 23 with AionTxExecSummary

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

the class ContractIntegTest method testDeployWithOutCode.

@Test
public void testDeployWithOutCode() throws Exception {
    long nrg = 1_000_000;
    long nrgPrice = energyPrice;
    // attempt to transfer value to new contract.
    BigInteger value = BigInteger.ZERO;
    BigInteger nonce = BigInteger.ZERO;
    // to == null  signals that this is contract creation.
    AionTransaction tx = AionTransaction.create(deployerKey, nonce.toByteArray(), null, value.toByteArray(), new byte[0], nrg, nrgPrice, txType, null);
    assertTrue(tx.isContractCreationTransaction());
    assertEquals(Builder.DEFAULT_BALANCE, blockchain.getRepository().getBalance(deployer));
    assertEquals(BigInteger.ZERO, blockchain.getRepository().getNonce(deployer));
    if (txType == TransactionTypes.DEFAULT) {
        MiningBlock block = makeBlock(tx);
        RepositoryCache repo = blockchain.getRepository().startTracking();
        AionTxExecSummary summary = executeTransaction(tx, block, repo);
        assertEquals("", summary.getReceipt().getError());
        // all energy is not used up.
        assertNotEquals(nrg, summary.getNrgUsed().longValue());
        AionAddress contract = TxUtil.calculateContractAddress(tx);
        checkStateOfDeployer(repo, summary, nrgPrice, BigInteger.ZERO, nonce.add(BigInteger.ONE));
        byte[] code = repo.getCode(contract);
        assertNotNull(code);
    } else {
        blockchain.forkUtility.enable040Fork(0);
        MiningBlock block = makeBlock(tx);
        RepositoryCache repo = blockchain.getRepository().startTracking();
        AionTxExecSummary summary = executeTransaction(tx, block, repo);
        assertEquals("Failed: invalid data", summary.getReceipt().getError());
    }
}
Also used : AionAddress(org.aion.types.AionAddress) AionTxExecSummary(org.aion.base.AionTxExecSummary) BigInteger(java.math.BigInteger) AionRepositoryCache(org.aion.zero.impl.db.AionRepositoryCache) RepositoryCache(org.aion.base.db.RepositoryCache) AionTransaction(org.aion.base.AionTransaction) MiningBlock(org.aion.zero.impl.types.MiningBlock) Test(org.junit.Test)

Example 24 with AionTxExecSummary

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

the class ContractIntegTest method testRecursiveStackoverflow.

@Test
public void testRecursiveStackoverflow() throws Exception {
    String contractName = "Recursive";
    byte[] deployCode = getDeployCode(contractName);
    long nrg = Constants.NRG_TRANSACTION_MAX;
    long nrgPrice = energyPrice;
    BigInteger value = BigInteger.ZERO;
    BigInteger nonce = BigInteger.ZERO;
    AionTransaction tx = AionTransaction.create(deployerKey, nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, nrgPrice, txType, null);
    RepositoryCache repo = blockchain.getRepository().startTracking();
    nonce = nonce.add(BigInteger.ONE);
    AionAddress contract = deployContract(repo, tx, contractName, null, value, nrg, nrgPrice, nonce);
    if (txType == TransactionTypes.AVM_CREATE_CODE) {
        assertNull(contract);
        return;
    }
    deployerBalance = repo.getBalance(deployer);
    deployerNonce = repo.getNonce(deployer);
    // First recurse 1 time less than the max and verify this is ok.
    // Note that 128 == FvmConstants.MAX_CALL_DEPTH
    int numRecurses = 127;
    byte[] input = ByteUtil.merge(Hex.decode("2d7df21a"), contract.toByteArray());
    input = ByteUtil.merge(input, new DataWord(numRecurses + 1).getData());
    tx = AionTransaction.create(deployerKey, nonce.toByteArray(), contract, BigInteger.ZERO.toByteArray(), input, nrg, nrgPrice, txType, null);
    assertFalse(tx.isContractCreationTransaction());
    MiningBlock block = makeBlock(tx);
    AionTxExecSummary summary = executeTransaction(tx, block, repo);
    assertEquals("", summary.getReceipt().getError());
    assertNotEquals(nrg, summary.getNrgUsed().longValue());
    BigInteger txCost = BigInteger.valueOf(summary.getNrgUsed().longValue()).multiply(BigInteger.valueOf(nrgPrice));
    assertEquals(deployerBalance.subtract(txCost), repo.getBalance(deployer));
    deployerBalance = repo.getBalance(deployer);
    deployerNonce = repo.getNonce(deployer);
    repo.flushTo(blockchain.getRepository(), true);
    repo = blockchain.getRepository().startTracking();
    // Now recurse the max amount of times and ensure we fail.
    // Note that 128 == FvmConstants.MAX_CALL_DEPTH
    numRecurses = 128;
    input = ByteUtil.merge(Hex.decode("2d7df21a"), contract.toByteArray());
    input = ByteUtil.merge(input, new DataWord(numRecurses + 1).getData());
    nonce = nonce.add(BigInteger.ONE);
    tx = AionTransaction.create(deployerKey, nonce.toByteArray(), contract, BigInteger.ZERO.toByteArray(), input, nrg, nrgPrice, txType, null);
    assertFalse(tx.isContractCreationTransaction());
    block = makeBlock(tx);
    summary = executeTransaction(tx, block, repo);
    assertEquals("reverted", summary.getReceipt().getError());
    assertNotEquals(nrg, summary.getNrgUsed().longValue());
    txCost = BigInteger.valueOf(summary.getNrgUsed().longValue()).multiply(BigInteger.valueOf(nrgPrice));
    assertEquals(deployerBalance.subtract(txCost), repo.getBalance(deployer));
}
Also used : AionAddress(org.aion.types.AionAddress) AionTxExecSummary(org.aion.base.AionTxExecSummary) BigInteger(java.math.BigInteger) AionRepositoryCache(org.aion.zero.impl.db.AionRepositoryCache) RepositoryCache(org.aion.base.db.RepositoryCache) AionTransaction(org.aion.base.AionTransaction) DataWord(org.aion.util.types.DataWord) MiningBlock(org.aion.zero.impl.types.MiningBlock) Test(org.junit.Test)

Example 25 with AionTxExecSummary

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

the class AvmTransactionExecutor method executeTransactions.

/**
 * Executes the specified transactions using the avm, and returns the execution summaries of
 * each of the transactions.
 *
 * This method does not perform any checks on its inputs! It operates under the assumption that
 * the caller has ensured the input parameters are correct!
 *
 * In particular, every object supplied must be non-null with the exception of
 * {@code postExecutionWork}, which may be null. Also, we must have
 * {@code initialBlockEnergyLimit <= blockEnergyLimit}.
 *
 * @param repository The current state of the world.
 * @param blockDifficulty The block difficulty.
 * @param blockNumber The current block number.
 * @param blockTimestamp The block timestamp.
 * @param blockEnergyLimit The energy limit of the block.
 * @param miner The miner address.
 * @param transactions The transactions to execute.
 * @param postExecutionWork The post-execution work to be applied after executing the transactions.
 * @param decrementBlockEnergyLimit Whether or not to check the block energy limit.
 * @param allowNonceIncrement Whether to increment the sender's nonce or not.
 * @param isLocalCall Whether this is a local call (ie. is to cause no state changes).
 * @param remainingBlockEnergy The amount of energy remaining in the block.
 * @param executionType The avm execution type.
 * @param cachedBlockNumber The cached block number.
 * @param unityForkEnabled the flag shows the unityfork feature enabled/disabled
 * @param signatureSchemeSwapEnabled the flag shows the signatureSchemeSwap feature enabled/disabled
 * @return the execution summaries of the transactions.
 * @throws VmFatalException If a fatal error occurred and the kernel must be shut down.
 */
public static List<AionTxExecSummary> executeTransactions(RepositoryCache repository, BigInteger blockDifficulty, long blockNumber, long blockTimestamp, long blockEnergyLimit, AionAddress miner, AionTransaction[] transactions, PostExecutionWork postExecutionWork, boolean decrementBlockEnergyLimit, boolean allowNonceIncrement, boolean isLocalCall, long remainingBlockEnergy, AvmExecutionType executionType, long cachedBlockNumber, boolean unityForkEnabled, boolean signatureSchemeSwapEnabled) throws VmFatalException {
    List<AionTxExecSummary> transactionSummaries = new ArrayList<>();
    long blockEnergy = remainingBlockEnergy;
    try {
        // We need to acquire the provider's lock before we can do anything meaningful.
        if (!AvmProvider.tryAcquireLock(10, TimeUnit.MINUTES)) {
            throw new TimeoutException("Timed out waiting to acquire the avm provider lock!");
        }
        // Ensure that the vm is in the correct state and grab the version of the avm we need to use for this block.
        AvmVersion versionToUse = updateAvmsAndGetVersionToUse(AvmConfigurations.getProjectRootDirectory(), blockNumber, signatureSchemeSwapEnabled);
        IAvmFutureResult[] futures = invokeAvm(versionToUse, repository, blockDifficulty, blockNumber, blockTimestamp, blockEnergyLimit, miner, transactions, allowNonceIncrement, isLocalCall, executionType, cachedBlockNumber, unityForkEnabled);
        // Process the transaction results.
        int index = 0;
        for (IAvmFutureResult future : futures) {
            TransactionResult result = future.getResult();
            if (result.transactionStatus.isFatal()) {
                throw new VmFatalException(result.transactionStatus.causeOfError);
            }
            // Check the block energy limit and reject if necessary.
            AionTransaction transaction = transactions[index];
            if (result.energyUsed > blockEnergy) {
                result = markAsBlockEnergyLimitExceeded(result, transaction.getEnergyLimit());
            }
            AionTxExecSummary summary = buildSummaryAndUpdateState(future, transaction, result, versionToUse, repository, blockDifficulty, blockNumber, blockTimestamp, blockEnergyLimit, miner, allowNonceIncrement, isLocalCall);
            // Do any post execution work if any is specified.
            if (postExecutionWork != null) {
                postExecutionWork.doWork(repository, summary, transaction);
            }
            // Update the remaining block energy.
            if (!result.transactionStatus.isRejected() && decrementBlockEnergyLimit) {
                blockEnergy -= summary.getReceipt().getEnergyUsed();
            }
            transactionSummaries.add(summary);
            index++;
        }
    } catch (Throwable e) {
        // If we get here then something unexpected went wrong, we treat this as a fatal situation since shutting down is our only recovery.
        System.err.println("Encountered an unexpected error while processing the transactions in the avm: " + e.toString());
        throw new VmFatalException(e);
    } finally {
        AvmProvider.releaseLock();
    }
    return transactionSummaries;
}
Also used : TransactionResult(org.aion.types.TransactionResult) AionTxExecSummary(org.aion.base.AionTxExecSummary) ArrayList(java.util.ArrayList) IAvmFutureResult(org.aion.avm.stub.IAvmFutureResult) AionTransaction(org.aion.base.AionTransaction) VmFatalException(org.aion.zero.impl.vm.common.VmFatalException) AvmVersion(org.aion.avm.stub.AvmVersion) TimeoutException(java.util.concurrent.TimeoutException)

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