use of org.aion.zero.impl.db.AionRepositoryImpl in project aion by aionnetwork.
the class AionContractDetailsTest method testExternalStorageSerialization.
@Test
public void testExternalStorageSerialization() {
Address address = Address.wrap(RandomUtils.nextBytes(Address.ADDRESS_LEN));
byte[] code = RandomUtils.nextBytes(512);
Map<DataWord, DataWord> elements = new HashMap<>();
AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig);
IByteArrayKeyValueDatabase externalStorage = repository.getDetailsDatabase();
AionContractDetailsImpl original = new AionContractDetailsImpl(0, 1000000);
original.setExternalStorageDataSource(externalStorage);
original.setAddress(address);
original.setCode(code);
original.externalStorage = true;
for (int i = 0; i < IN_MEMORY_STORAGE_LIMIT / 64 + 10; i++) {
DataWord key = new DataWord(RandomUtils.nextBytes(16));
DataWord value = new DataWord(RandomUtils.nextBytes(16));
elements.put(key, value);
original.put(key, value);
}
original.syncStorage();
byte[] rlp = original.getEncoded();
AionContractDetailsImpl deserialized = new AionContractDetailsImpl();
deserialized.setExternalStorageDataSource(externalStorage);
deserialized.decode(rlp);
assertEquals(deserialized.externalStorage, true);
assertTrue(address.equals(deserialized.getAddress()));
assertEquals(ByteUtil.toHexString(code), ByteUtil.toHexString(deserialized.getCode()));
Map<DataWord, DataWord> storage = deserialized.getStorage();
assertEquals(elements.size(), storage.size());
for (DataWord key : elements.keySet()) {
assertEquals(elements.get(key), storage.get(key));
}
DataWord deletedKey = elements.keySet().iterator().next();
deserialized.put(deletedKey, DataWord.ZERO);
deserialized.put(new DataWord(RandomUtils.nextBytes(16)), DataWord.ZERO);
}
use of org.aion.zero.impl.db.AionRepositoryImpl in project aion by aionnetwork.
the class AionContractDetailsTest method testExternalStorageTransition.
@Test
public void testExternalStorageTransition() {
Address address = Address.wrap(RandomUtils.nextBytes(Address.ADDRESS_LEN));
byte[] code = RandomUtils.nextBytes(512);
Map<DataWord, DataWord> elements = new HashMap<>();
AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig);
IByteArrayKeyValueDatabase externalStorage = repository.getDetailsDatabase();
AionContractDetailsImpl original = new AionContractDetailsImpl(0, 1000000);
original.setExternalStorageDataSource(externalStorage);
original.setAddress(address);
original.setCode(code);
for (int i = 0; i < IN_MEMORY_STORAGE_LIMIT / 64 + 10; i++) {
DataWord key = new DataWord(RandomUtils.nextBytes(16));
DataWord value = new DataWord(RandomUtils.nextBytes(16));
elements.put(key, value);
original.put(key, value);
}
original.syncStorage();
assertTrue(!externalStorage.isEmpty());
IContractDetails deserialized = deserialize(original.getEncoded(), externalStorage);
// adds keys for in-memory storage limit overflow
for (int i = 0; i < 10; i++) {
DataWord key = new DataWord(RandomUtils.nextBytes(16));
DataWord value = new DataWord(RandomUtils.nextBytes(16));
elements.put(key, value);
deserialized.put(key, value);
}
deserialized.syncStorage();
assertTrue(!externalStorage.isEmpty());
deserialized = deserialize(deserialized.getEncoded(), externalStorage);
Map<DataWord, DataWord> storage = deserialized.getStorage();
assertEquals(elements.size(), storage.size());
for (DataWord key : elements.keySet()) {
assertEquals(elements.get(key), storage.get(key));
}
}
use of org.aion.zero.impl.db.AionRepositoryImpl 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 Address DOG_ACC = Address.wrap("00000000000000000000000000000dog".getBytes());
final Address DOGE_ACC = Address.wrap("0000000000000000000000000000doge".getBytes());
AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig);
IRepositoryCache track = repository.startTracking();
track.addBalance(DOG_ACC, BigInteger.ONE);
track.addBalance(DOGE_ACC, BigInteger.ONE);
track.flush();
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.flush();
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.zero.impl.db.AionRepositoryImpl in project aion by aionnetwork.
the class AionRepositoryImplTest method testSyncToPreviousRootWithFlush.
@Test
public void testSyncToPreviousRootWithFlush() {
final Address FIRST_ACC = Address.wrap("CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE");
AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig);
byte[] originalRoot = repository.getRoot();
IRepositoryCache track = repository.startTracking();
track.addBalance(FIRST_ACC, BigInteger.ONE);
track.flush();
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.flush();
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.zero.impl.db.AionRepositoryImpl in project aion by aionnetwork.
the class AionRepositoryImplTest method testSyncToPreviousRootNoFlush.
/**
* Tests behaviour for trie when trying to revert to a previous root without
* first flushing. Note the behaviour here. Interestingly enough, it seems like
* the trie must first be flushed, so that the root node is in the caching/db layer.
*
* Otherwise the retrieval methods will not be able to find the temporal root value.
*/
@Test
public void testSyncToPreviousRootNoFlush() {
final Address FIRST_ACC = Address.wrap("CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE");
final Address SECOND_ACC = Address.wrap("BEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEF");
final AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig);
byte[] originalRoot = repository.getRoot();
// now create a new account
IRepositoryCache track = repository.startTracking();
track.addBalance(FIRST_ACC, BigInteger.ONE);
track.flush();
System.out.println("after first account added");
System.out.println(repository.getWorldState().getTrieDump());
byte[] firstRoot = repository.getRoot();
track = repository.startTracking();
track.addBalance(SECOND_ACC, BigInteger.TWO);
track.flush();
byte[] secondRoot = repository.getRoot();
System.out.println("after second account added");
System.out.println(repository.getWorldState().getTrieDump());
assertThat(firstRoot).isNotEqualTo(originalRoot);
assertThat(secondRoot).isNotEqualTo(firstRoot);
repository.syncToRoot(firstRoot);
assertThat(repository.getRoot()).isEqualTo(firstRoot);
BigInteger balance = repository.getBalance(FIRST_ACC);
// notice that the first blocks balance is also zero
assertThat(balance).isEqualTo(BigInteger.ZERO);
}
Aggregations