use of org.aion.base.AionTransaction in project aion by aionnetwork.
the class AbstractBlock method getTransactionsEncoded.
private byte[] getTransactionsEncoded() {
byte[][] transactionsEncoded = new byte[transactionsList.size()][];
int i = 0;
for (AionTransaction tx : transactionsList) {
transactionsEncoded[i] = tx.getEncoded();
++i;
}
return RLP.encodeList(transactionsEncoded);
}
use of org.aion.base.AionTransaction in project aion by aionnetwork.
the class BlockUtil method newBlockFromSharedRLPList.
public static Block newBlockFromSharedRLPList(SharedRLPList rlpList) {
// return null when given empty bytes
if (rlpList == null || rlpList.isEmpty()) {
return null;
}
try {
SharedRLPList header = (SharedRLPList) rlpList.get(0);
List<AionTransaction> txs = parseTransactions((SharedRLPList) rlpList.get(1));
byte[] sealType = header.get(0).getRLPData();
if (sealType[0] == Seal.PROOF_OF_WORK.getSealId()) {
MiningBlockHeader miningHeader = MiningBlockHeader.Builder.newInstance().withRlpList(header).build();
return new MiningBlock(miningHeader, txs);
} else if (sealType[0] == Seal.PROOF_OF_STAKE.getSealId()) {
StakingBlockHeader stakingHeader = StakingBlockHeader.Builder.newInstance().withRlpList(header).build();
return new StakingBlock(stakingHeader, txs);
} else {
return null;
}
} catch (Exception e) {
genLog.warn("Unable to decode block bytes " + Arrays.toString(SharedRLPList.getRLPDataCopy(rlpList)), e);
return null;
}
}
use of org.aion.base.AionTransaction 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.AionTransaction in project aion by aionnetwork.
the class BulkExecutor method executeNextBatchOfPrecompiledTransactions.
/**
* Returns the execution summaries of the next batch of precompiled contract call transactions
* to be run. This batch of transactions begins with the transaction at index {@code
* currentIndex} in the provided list of transactions and includes all subsequent transactions
* that are precompiled-bound.
*/
private static List<AionTxExecSummary> executeNextBatchOfPrecompiledTransactions(RepositoryCache repository, List<AionTransaction> transactions, int currentIndex, long blockNumber, AionAddress blockCoinbase, PostExecutionWork postExecutionWork, Logger logger, boolean checkBlockEnergyLimit, boolean incrementSenderNonce, boolean isLocalCall, long blockRemainingEnergy) {
// Grab the next batch of precompiled contract call transactions to execute.
List<AionTransaction> precompiledTransactionsToExecute = fetchNextBatchOfPrecompiledContractCallTransactions(transactions, currentIndex);
AionTransaction[] precompiledTransactions = new AionTransaction[precompiledTransactionsToExecute.size()];
precompiledTransactionsToExecute.toArray(precompiledTransactions);
CfgFork cfg = new CfgFork();
String forkProperty = cfg.getProperties().getProperty("fork0.3.2");
boolean fork032Enabled = (forkProperty != null) && (blockNumber >= Long.valueOf(forkProperty));
// Execute the precompiled contract call transactions.
return PrecompiledTransactionExecutor.executeTransactions(repository, blockNumber, blockCoinbase, precompiledTransactions, postExecutionWork, logger, checkBlockEnergyLimit, incrementSenderNonce, isLocalCall, fork032Enabled, blockRemainingEnergy);
}
use of org.aion.base.AionTransaction 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;
}
Aggregations