use of org.aion.base.db.RepositoryCache in project aion by aionnetwork.
the class ExternalStateForAvm method getVmType.
private InternalVmType getVmType(AionAddress destination) {
// will load contract into memory otherwise leading to consensus issues
RepositoryCache track = repositoryCache.startTracking();
AccountState accountState = track.getAccountState(destination);
InternalVmType vm;
if (accountState == null) {
// the address doesn't exist yet, so it can be used by either vm
vm = InternalVmType.EITHER;
} else {
vm = repositoryCache.getVMUsed(destination, accountState.getCodeHash());
// UNKNOWN is returned when there was no contract information stored
if (vm == InternalVmType.UNKNOWN) {
// use the in-memory value
vm = track.getVmType(destination);
}
}
return vm;
}
use of org.aion.base.db.RepositoryCache in project aion by aionnetwork.
the class AionRepositoryImplTest method test17NodePreviousRootTest.
// test that intermediate nodes also get rolled back properly
// intermediate nodes get created when two accounts have a common substring
@Test
public void test17NodePreviousRootTest() {
// not that it matters since things are going to be hashed, but at least
// the root node should point to a node that contains references to both
final AionAddress DOG_ACC = new AionAddress("00000000000000000000000000000dog".getBytes());
final AionAddress DOGE_ACC = new AionAddress("0000000000000000000000000000doge".getBytes());
AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig);
RepositoryCache track = repository.startTracking();
track.addBalance(DOG_ACC, BigInteger.ONE);
track.addBalance(DOGE_ACC, BigInteger.ONE);
track.flushTo(repository, true);
final byte[] root = repository.getRoot();
repository.flush();
System.out.println("trie state after adding two accounts");
System.out.println(repository.getWorldState().getTrieDump());
track = repository.startTracking();
track.addBalance(DOG_ACC, BigInteger.ONE);
track.flushTo(repository, true);
System.out.println("trie state after updating balance on one account");
System.out.println(repository.getWorldState().getTrieDump());
assertThat(repository.getBalance(DOG_ACC)).isEqualTo(BigInteger.TWO);
repository.flush();
repository.syncToRoot(root);
assertThat(repository.getBalance(DOG_ACC)).isEqualTo(BigInteger.ONE);
}
use of org.aion.base.db.RepositoryCache in project aion by aionnetwork.
the class AionRepositoryImplTest method testSyncToPreviousRootWithFlush.
@Test
public void testSyncToPreviousRootWithFlush() {
final AionAddress FIRST_ACC = AddressUtils.wrapAddress(value2);
AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig);
byte[] originalRoot = repository.getRoot();
RepositoryCache track = repository.startTracking();
track.addBalance(FIRST_ACC, BigInteger.ONE);
track.flushTo(repository, true);
byte[] newRoot = repository.getRoot();
System.out.println("state after add one account");
System.out.println(repository.getWorldState().getTrieDump());
// flush into cache/db
repository.flush();
track = repository.startTracking();
// total should be 2
track.addBalance(FIRST_ACC, BigInteger.ONE);
track.flushTo(repository, true);
assertThat(repository.getBalance(FIRST_ACC)).isEqualTo(BigInteger.TWO);
System.out.println("state after adding balance to FIRST_ACC");
System.out.println(repository.getWorldState().getTrieDump());
// flush this state into cache/db
repository.flush();
repository.setRoot(newRoot);
System.out.println("state after rewinding to previous root");
System.out.println(repository.getWorldState().getTrieDump());
assertThat(repository.getBalance(FIRST_ACC)).isEqualTo(BigInteger.ONE);
}
use of org.aion.base.db.RepositoryCache in project aion by aionnetwork.
the class TransactionCreateSpecificationTests method deployAvmContractOnTopOfAddressWithStorageUsingAvmVersion1.
@Test
public void deployAvmContractOnTopOfAddressWithStorageUsingAvmVersion1() throws VmFatalException {
AvmTestConfig.clearConfigurations();
AvmTestConfig.supportOnlyAvmVersion1();
// Deploy AVM contract.
AionTransaction deployTxAvm = BlockchainTestUtils.deployAvmContractTransaction(AvmContract.HELLO_WORLD, resourceProvider.factoryForVersion1, SENDER_KEY, BigInteger.ZERO);
AionAddress contract = TxUtil.calculateContractAddress(deployTxAvm);
// Manipulate the repository to have a non-default storage value.
RepositoryCache cache = blockchain.getRepository().startTracking();
cache.addStorageRow(contract, ByteArrayWrapper.wrap(RandomUtils.nextBytes(16)), ByteArrayWrapper.wrap(RandomUtils.nextBytes(16)));
cache.saveVmType(contract, InternalVmType.AVM);
cache.flushTo(cache.getParent(), true);
// Check assumptions about contract state.
AccountState contractState = (AccountState) blockchain.getRepository().startTracking().getAccountState(contract);
assertThat(contractState.getBalance()).isEqualTo(BigInteger.ZERO);
assertThat(contractState.getNonce()).isEqualTo(BigInteger.ZERO);
assertThat(contractState.getStateRoot()).isNotEqualTo(EMPTY_TRIE_HASH);
assertThat(contractState.getCodeHash()).isEqualTo(EMPTY_DATA_HASH);
byte[] oldRoot = contractState.getStateRoot();
// Next, process the deploy transaction with fork040 enabled.
AionTxExecSummary result = executeTransaction(deployTxAvm, true);
assertThat(result.isFailed()).isFalse();
assertThat(result.isRejected()).isFalse();
assertThat(result.getReceipt().getError()).isEmpty();
assertThat(result.getNrgUsed()).isLessThan(BigInteger.valueOf(deployTxAvm.getEnergyLimit()));
assertThat(result.getLogs()).isEmpty();
contractState = (AccountState) blockchain.getRepository().startTracking().getAccountState(contract);
assertThat(contractState.getBalance()).isEqualTo(BigInteger.ZERO);
assertThat(contractState.getNonce()).isEqualTo(BigInteger.ZERO);
assertThat(contractState.getStateRoot()).isNotEqualTo(EMPTY_TRIE_HASH);
assertThat(contractState.getStateRoot()).isNotEqualTo(oldRoot);
assertThat(contractState.getCodeHash()).isNotEqualTo(EMPTY_DATA_HASH);
}
use of org.aion.base.db.RepositoryCache in project aion by aionnetwork.
the class TransactionCreateSpecificationTests method deployInternalAvmContractOnTopOfAddressWithStorageUsingAvmVersion1.
@Test
public void deployInternalAvmContractOnTopOfAddressWithStorageUsingAvmVersion1() throws VmFatalException {
AvmTestConfig.clearConfigurations();
AvmTestConfig.supportOnlyAvmVersion1();
// Deploy AVM contract.
AionTransaction deployTxAvm = BlockchainTestUtils.deployAvmContractTransaction(AvmContract.DEPLOY_INTERNAL, resourceProvider.factoryForVersion1, SENDER_KEY, BigInteger.ZERO);
AionAddress contract = TxUtil.calculateContractAddress(deployTxAvm);
Pair<Block, ImportResult> resultImport = BlockchainTestUtils.addMiningBlock(blockchain, blockchain.getBestBlock(), List.of(deployTxAvm));
assertThat(resultImport.getRight()).isEqualTo(ImportResult.IMPORTED_BEST);
// Call AVM contract to deploy new internal AVM contract (version without required success).
long internalLimit = 1_000_000;
AionTransaction deployInternal = BlockchainTestUtils.callSimpleAvmContractTransaction(resourceProvider.factoryForVersion1, SENDER_KEY, BigInteger.ONE, contract, "deploy", deployTxAvm.getData(), internalLimit);
AionAddress internalContract = new AionAddress(Hex.decode("a0268090998a99666b72cc452b9307438a34341047d9e0d7b92c9207bf413655"));
assertThat(blockchain.getRepository().hasAccountState(internalContract)).isFalse();
// Manipulate the repository to have a non-default storage value.
RepositoryCache cache = blockchain.getRepository().startTracking();
cache.addStorageRow(internalContract, ByteArrayWrapper.wrap(RandomUtils.nextBytes(16)), ByteArrayWrapper.wrap(RandomUtils.nextBytes(16)));
cache.saveVmType(internalContract, InternalVmType.AVM);
cache.flushTo(cache.getParent(), true);
// Check assumptions about contract state.
AccountState contractState = (AccountState) blockchain.getRepository().startTracking().getAccountState(internalContract);
assertThat(contractState.getBalance()).isEqualTo(BigInteger.ZERO);
assertThat(contractState.getNonce()).isEqualTo(BigInteger.ZERO);
assertThat(contractState.getStateRoot()).isNotEqualTo(EMPTY_TRIE_HASH);
assertThat(contractState.getCodeHash()).isEqualTo(EMPTY_DATA_HASH);
byte[] oldRoot = contractState.getStateRoot();
// Next, process the deploy transaction with fork040 enabled.
AionTxExecSummary result = executeTransaction(deployInternal, true);
assertThat(result.isFailed()).isFalse();
assertThat(result.isRejected()).isFalse();
assertThat(result.getReceipt().getError()).isEmpty();
assertThat(result.getNrgUsed()).isLessThan(BigInteger.valueOf(deployInternal.getEnergyLimit()));
assertThat(result.getLogs()).isEmpty();
InternalTransaction itx = result.getInternalTransactions().get(0);
assertThat(itx.isCreate).isTrue();
assertThat(TxUtil.calculateContractAddress(itx)).isEqualTo(internalContract);
assertThat(itx.isRejected).isFalse();
assertThat(itx.energyLimit).isEqualTo(internalLimit);
assertThat(result.getNrgUsed()).isLessThan(BigInteger.valueOf(itx.energyLimit));
contractState = (AccountState) blockchain.getRepository().startTracking().getAccountState(internalContract);
assertThat(contractState.getBalance()).isEqualTo(BigInteger.ZERO);
assertThat(contractState.getNonce()).isEqualTo(BigInteger.ZERO);
assertThat(contractState.getStateRoot()).isNotEqualTo(EMPTY_TRIE_HASH);
assertThat(contractState.getStateRoot()).isNotEqualTo(oldRoot);
assertThat(contractState.getCodeHash()).isNotEqualTo(EMPTY_DATA_HASH);
}
Aggregations