Search in sources :

Example 26 with AionTxExecSummary

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

the class AvmTransactionExecutor method buildTransactionSummary.

/**
 * Constructs a new execution summary for the given transaction & result pair.
 *
 * @param transaction The transaction.
 * @param result The transaction result.
 * @return the summary.
 */
private static AionTxExecSummary buildTransactionSummary(AionTransaction transaction, TransactionResult result) {
    List<Log> logs = result.transactionStatus.isSuccess() ? result.logs : new ArrayList<>();
    byte[] output = result.copyOfTransactionOutput().orElse(new byte[0]);
    AionTxExecSummary.Builder builder = AionTxExecSummary.builderFor(makeReceipt(transaction, logs, result, output)).logs(logs).deletedAccounts(new ArrayList<>()).internalTransactions(result.internalTransactions).result(output);
    TransactionStatus resultCode = result.transactionStatus;
    if (resultCode.isRejected()) {
        builder.markAsRejected();
    } else if (resultCode.isFailed()) {
        builder.markAsFailed();
    }
    return builder.build();
}
Also used : Log(org.aion.types.Log) AionTxExecSummary(org.aion.base.AionTxExecSummary) TransactionStatus(org.aion.types.TransactionStatus)

Example 27 with AionTxExecSummary

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

the class AvmTransactionExecutor method buildSummaryAndUpdateState.

/**
 * Builds a transaction summary and updates the current state of the world. If the transction
 * was rejected, or if this is a local call, then no state changes will be made. Otherwise,
 * the world state will be updated.
 *
 * Returns the built summary.
 *
 * @param future The future result.
 * @param transaction The transaction that was run.
 * @param result The result of running the transaction.
 * @param avmVersion The version of the avm that was used.
 * @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 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).
 * @return the execution summary.
 */
private static AionTxExecSummary buildSummaryAndUpdateState(IAvmFutureResult future, AionTransaction transaction, TransactionResult result, AvmVersion avmVersion, RepositoryCache repository, BigInteger blockDifficulty, long blockNumber, long blockTimestamp, long blockEnergyLimit, AionAddress miner, boolean allowNonceIncrement, boolean isLocalCall) {
    AionTxExecSummary summary = buildTransactionSummary(transaction, result);
    // Update the repository by committing any changes in the Avm so long as the transaction was not rejected.
    if (!result.transactionStatus.isRejected() && !isLocalCall) {
        // We have to build a new world state so things flush to repository.
        IAvmExternalState currentWorldState = AvmProvider.newExternalStateBuilder(avmVersion).withRepository(repository).withMiner(miner).withDifficulty(blockDifficulty).withBlockNumber(blockNumber).withBlockTimestamp(blockTimestamp).withBlockEnergyLimit(blockEnergyLimit).withEnergyRules(AvmConfigurations.getEnergyLimitRules()).allowNonceIncrement(allowNonceIncrement).isLocalCall(isLocalCall).build();
        future.commitStateChangesTo(currentWorldState);
    }
    return summary;
}
Also used : IAvmExternalState(org.aion.avm.stub.IAvmExternalState) AionTxExecSummary(org.aion.base.AionTxExecSummary)

Example 28 with AionTxExecSummary

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

the class BulkExecutor method executeInternal.

/**
 * This is the common execution point that all publicly-exposed execute methods call into.
 */
private static List<AionTxExecSummary> executeInternal(byte[] blockDifficulty, long blockNumber, long blockTimestamp, long blockNrgLimit, AionAddress blockCoinbase, List<AionTransaction> transactions, RepositoryCache repository, PostExecutionWork postExecutionWork, Logger logger, boolean checkBlockEnergyLimit, boolean incrementSenderNonce, boolean isLocalCall, boolean fork040enabled, BlockCachingContext blockCachingContext, long cachedBlockNumber, boolean unityForkEnabled, boolean signatureSwapForkEnabled) throws VmFatalException {
    List<AionTxExecSummary> allSummaries = new ArrayList<>();
    long blockRemainingEnergy = blockNrgLimit;
    int currentIndex = 0;
    while (currentIndex < transactions.size()) {
        List<AionTxExecSummary> currentBatchOfSummaries;
        AionTransaction firstTransactionInNextBatch = transactions.get(currentIndex);
        if (transactionIsForAionVirtualMachine(repository, firstTransactionInNextBatch)) {
            currentBatchOfSummaries = executeNextBatchOfAvmTransactions(repository, transactions, currentIndex, new BigInteger(1, blockDifficulty), blockNumber, blockTimestamp, blockNrgLimit, blockCoinbase, postExecutionWork, logger, checkBlockEnergyLimit, incrementSenderNonce, isLocalCall, blockRemainingEnergy, blockCachingContext.avmType, cachedBlockNumber, unityForkEnabled, signatureSwapForkEnabled);
        } else if (transactionIsForFastVirtualMachine(repository, firstTransactionInNextBatch)) {
            currentBatchOfSummaries = executeNextBatchOfFvmTransactions(repository, transactions, currentIndex, blockDifficulty, blockNumber, blockTimestamp, blockNrgLimit, blockCoinbase, postExecutionWork, logger, checkBlockEnergyLimit, incrementSenderNonce, isLocalCall, blockRemainingEnergy, fork040enabled, unityForkEnabled, signatureSwapForkEnabled);
        } else if (transactionIsPrecompiledContractCall(firstTransactionInNextBatch)) {
            currentBatchOfSummaries = executeNextBatchOfPrecompiledTransactions(repository, transactions, currentIndex, blockNumber, blockCoinbase, postExecutionWork, logger, checkBlockEnergyLimit, incrementSenderNonce, isLocalCall, blockRemainingEnergy);
        } else {
            throw new IllegalStateException("Transaction is not destined for any known VM: " + firstTransactionInNextBatch);
        }
        // Update the remaining energy left in the block.
        for (AionTxExecSummary currentSummary : currentBatchOfSummaries) {
            if (!currentSummary.isRejected()) {
                blockRemainingEnergy -= ((checkBlockEnergyLimit) ? currentSummary.getReceipt().getEnergyUsed() : 0);
            }
        }
        // Add the current batch of summaries to the complete list and increment current index.
        allSummaries.addAll(currentBatchOfSummaries);
        currentIndex += currentBatchOfSummaries.size();
    }
    return allSummaries;
}
Also used : AionTxExecSummary(org.aion.base.AionTxExecSummary) ArrayList(java.util.ArrayList) BigInteger(java.math.BigInteger) AionTransaction(org.aion.base.AionTransaction)

Example 29 with AionTxExecSummary

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

the class FvmTransactionExecutor method executeTransactions.

/**
 * Executes the specified array of transactions using the FVM and returns a list of transaction
 * summaries, such that the i'th summary pertains to the i'th transaction in the input.
 *
 * <p>If no post-execution work is specified then none will be run. Otherwise, the
 * post-execution work will be applied in such a way that it appears, from the caller's
 * perspective, as if it was run immediately after each transaction sequentially.
 *
 * @param repository The current snapshot of the kernel's repository layer.
 * @param blockDifficulty The current best block's difficulty.
 * @param blockNumber The current best block number.
 * @param blockTimestamp The current best block timestamp.
 * @param blockNrgLimit The current best block energy limit.
 * @param blockCoinbase The address of the miner.
 * @param transactions The transactions to execute.
 * @param postExecutionWork The post-execute work, if any, to be run immediately after each
 *     transaction completes.
 * @param logger A logger.
 * @param decrementBlockEnergyLimit Whether to decrement the block energy limit (ie. if no
 *     decrement implication is block overflow won't be checked)
 * @param allowNonceIncrement Whether to increment the sender nonce.
 * @param isLocalCall Whether this is a local call or not.
 * @param fork040enabled Whether or not the 0.4.0 fork is enabled.
 * @param initialBlockEnergyLimit The initial block energy limit at the time of running these
 *     transactions.
 * @return a list of transaction summaries pertaining to the transactions.
 */
public static List<AionTxExecSummary> executeTransactions(RepositoryCache repository, byte[] blockDifficulty, long blockNumber, long blockTimestamp, long blockNrgLimit, AionAddress blockCoinbase, AionTransaction[] transactions, PostExecutionWork postExecutionWork, Logger logger, boolean decrementBlockEnergyLimit, boolean allowNonceIncrement, boolean isLocalCall, boolean fork040enabled, long initialBlockEnergyLimit, boolean unityForkEnabled, boolean signatureSwapForkEnabled) throws VmFatalException {
    List<AionTxExecSummary> transactionSummaries = new ArrayList<>();
    long blockRemainingEnergy = initialBlockEnergyLimit;
    // Run the transactions.
    IExternalStateForFvm externalState = new ExternalStateForFvm(repository, blockCoinbase, getDifficultyAsDataWord(blockDifficulty), isLocalCall, allowNonceIncrement, fork040enabled, blockNumber, blockTimestamp, blockNrgLimit, unityForkEnabled, signatureSwapForkEnabled);
    // Process the results of the transactions.
    for (AionTransaction transaction : transactions) {
        FvmWrappedTransactionResult wrappedResult = FastVirtualMachine.run(externalState, new ExternalCapabilitiesForFvm(), toAionTypesTransaction(transaction), fork040enabled);
        TransactionResult result = wrappedResult.result;
        List<AionAddress> deletedAddresses = wrappedResult.deletedAddresses;
        if (result.transactionStatus.isFatal()) {
            throw new VmFatalException(result.toString());
        }
        // Check the block energy limit & reject if necessary.
        if (result.energyUsed > blockRemainingEnergy) {
            TransactionStatus status = TransactionStatus.rejection("Invalid Energy Limit");
            result = new TransactionResult(status, result.logs, result.internalTransactions, 0, ByteUtil.EMPTY_BYTE_ARRAY);
        }
        // Build the transaction summary.
        AionTxExecSummary summary = buildTransactionSummary(transaction, result, deletedAddresses);
        // If the transaction was not rejected, then commit the state changes.
        if (!result.transactionStatus.isRejected()) {
            externalState.commit();
        }
        // For non-rejected non-local transactions, make some final repository updates.
        if (!isLocalCall && !summary.isRejected()) {
            RepositoryCache repositoryTracker = repository.startTracking();
            refundSender(repositoryTracker, summary, transaction, result);
            payMiner(repositoryTracker, blockCoinbase, summary);
            deleteAccountsMarkedForDeletion(repositoryTracker, summary.getDeletedAccounts(), result);
            repositoryTracker.flushTo(repository, true);
        }
        // Do any post execution work.
        if (postExecutionWork != null) {
            postExecutionWork.doWork(repository, summary, transaction);
        }
        // Update the remaining block energy.
        if (!result.transactionStatus.isRejected() && decrementBlockEnergyLimit) {
            blockRemainingEnergy -= summary.getReceipt().getEnergyUsed();
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Transaction receipt: {}", summary.getReceipt());
            logger.debug("Transaction logs: {}", summary.getLogs());
        }
        transactionSummaries.add(summary);
    }
    return transactionSummaries;
}
Also used : IExternalStateForFvm(org.aion.fastvm.IExternalStateForFvm) FvmWrappedTransactionResult(org.aion.fastvm.FvmWrappedTransactionResult) TransactionResult(org.aion.types.TransactionResult) AionAddress(org.aion.types.AionAddress) AionTxExecSummary(org.aion.base.AionTxExecSummary) ArrayList(java.util.ArrayList) TransactionStatus(org.aion.types.TransactionStatus) AionTransaction(org.aion.base.AionTransaction) FvmWrappedTransactionResult(org.aion.fastvm.FvmWrappedTransactionResult) IExternalStateForFvm(org.aion.fastvm.IExternalStateForFvm) VmFatalException(org.aion.zero.impl.vm.common.VmFatalException) RepositoryCache(org.aion.base.db.RepositoryCache)

Example 30 with AionTxExecSummary

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

the class BlockDetailsValidator method hasRejectedTransaction.

private static boolean hasRejectedTransaction(long blockNumber, List<AionTxExecSummary> summaries, Logger log) {
    boolean hasRejectedTransaction = false;
    for (AionTxExecSummary summary : summaries) {
        if (summary.isRejected()) {
            log.warn("Invalid block#{}: contained reject transaction: Tx[{}] Receipt[{}]", blockNumber, summary.getTransaction(), summary.getReceipt());
            hasRejectedTransaction = true;
        }
    }
    return hasRejectedTransaction;
}
Also used : AionTxExecSummary(org.aion.base.AionTxExecSummary)

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