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