use of org.aion.types.TransactionResult in project aion by aionnetwork.
the class AvmProviderTest method testBalanceTransferTransactionVersion2.
@Test
public void testBalanceTransferTransactionVersion2() throws Exception {
Assert.assertTrue(AvmProvider.tryAcquireLock(1, TimeUnit.MINUTES));
AvmProvider.enableAvmVersion(AvmVersion.VERSION_2, this.projectRootDir);
AvmProvider.startAvm(AvmVersion.VERSION_2);
// Set up the repo and give the sender account some balance.
RepositoryCache repository = newRepository();
AionAddress sender = randomAddress();
AionAddress recipient = randomAddress();
addBalance(repository, sender, BigInteger.valueOf(1_000_000));
// Run the transaction.
RepositoryCache repositoryChild = repository.startTracking();
IAvmExternalState externalState = newExternalState(AvmVersion.VERSION_2, repositoryChild, newEnergyRules());
Transaction transaction = newBalanceTransferTransaction(sender, recipient, BigInteger.TEN);
IAionVirtualMachine avm = AvmProvider.getAvm(AvmVersion.VERSION_2);
IAvmFutureResult[] futures = avm.run(externalState, new Transaction[] { transaction }, AvmExecutionType.MINING, 0);
// Assert the result and state changes we expect.
Assert.assertEquals(1, futures.length);
TransactionResult result = futures[0].getResult();
Assert.assertTrue(result.transactionStatus.isSuccess());
Assert.assertEquals(BigInteger.TEN, repositoryChild.getBalance(recipient));
AvmProvider.shutdownAvm(AvmVersion.VERSION_2);
AvmProvider.disableAvmVersion(AvmVersion.VERSION_2);
AvmProvider.releaseLock();
}
use of org.aion.types.TransactionResult in project aion by aionnetwork.
the class AvmProviderTest method testBalanceTransferTransactionVersion2WithCoinbaseLock.
@Test
public void testBalanceTransferTransactionVersion2WithCoinbaseLock() throws Exception {
Assert.assertTrue(AvmProvider.tryAcquireLock(1, TimeUnit.MINUTES));
AvmProvider.enableAvmVersion(AvmVersion.VERSION_2, this.projectRootDir);
AvmProvider.startAvm(AvmVersion.VERSION_2, true);
// Set up the repo and give the sender account some balance.
RepositoryCache repository = newRepository();
AionAddress sender = randomAddress();
AionAddress recipient = randomAddress();
addBalance(repository, sender, BigInteger.valueOf(1_000_000));
// Run the transaction.
RepositoryCache repositoryChild = repository.startTracking();
IAvmExternalState externalState = newExternalState(AvmVersion.VERSION_2, repositoryChild, newEnergyRules());
Transaction transaction = newBalanceTransferTransaction(sender, recipient, BigInteger.TEN);
IAionVirtualMachine avm = AvmProvider.getAvm(AvmVersion.VERSION_2);
IAvmFutureResult[] futures = avm.run(externalState, new Transaction[] { transaction }, AvmExecutionType.MINING, 0);
// Assert the result and state changes we expect.
Assert.assertEquals(1, futures.length);
TransactionResult result = futures[0].getResult();
Assert.assertTrue(result.transactionStatus.isSuccess());
Assert.assertEquals(BigInteger.TEN, repositoryChild.getBalance(recipient));
AvmProvider.shutdownAvm(AvmVersion.VERSION_2);
AvmProvider.disableAvmVersion(AvmVersion.VERSION_2);
AvmProvider.releaseLock();
}
use of org.aion.types.TransactionResult 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;
}
use of org.aion.types.TransactionResult 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.types.TransactionResult in project aion by aionnetwork.
the class AvmProviderTest method testBalanceTransferTransactionVersion1.
@Test
public void testBalanceTransferTransactionVersion1() throws Exception {
Assert.assertTrue(AvmProvider.tryAcquireLock(1, TimeUnit.MINUTES));
AvmProvider.enableAvmVersion(AvmVersion.VERSION_1, this.projectRootDir);
AvmProvider.startAvm(AvmVersion.VERSION_1);
// Set up the repo and give the sender account some balance.
RepositoryCache repository = newRepository();
AionAddress sender = randomAddress();
AionAddress recipient = randomAddress();
addBalance(repository, sender, BigInteger.valueOf(1_000_000));
// Run the transaction.
RepositoryCache repositoryChild = repository.startTracking();
IAvmExternalState externalState = newExternalState(AvmVersion.VERSION_1, repositoryChild, newEnergyRules());
Transaction transaction = newBalanceTransferTransaction(sender, recipient, BigInteger.TEN);
IAionVirtualMachine avm = AvmProvider.getAvm(AvmVersion.VERSION_1);
IAvmFutureResult[] futures = avm.run(externalState, new Transaction[] { transaction }, AvmExecutionType.MINING, 0);
// Assert the result and state changes we expect.
Assert.assertEquals(1, futures.length);
TransactionResult result = futures[0].getResult();
Assert.assertTrue(result.transactionStatus.isSuccess());
Assert.assertEquals(BigInteger.TEN, repositoryChild.getBalance(recipient));
AvmProvider.shutdownAvm(AvmVersion.VERSION_1);
AvmProvider.disableAvmVersion(AvmVersion.VERSION_1);
AvmProvider.releaseLock();
}
Aggregations