use of org.ethereum.db.MutableRepository in project rskj by rsksmart.
the class RemascStorageProviderTest method setSaveRetrieveAndGetBurnedBalance.
@Test
public void setSaveRetrieveAndGetBurnedBalance() throws IOException {
RskAddress accountAddress = randomAddress();
Repository repository = new MutableRepository(new MutableTrieImpl(null, new Trie()));
RemascStorageProvider provider = new RemascStorageProvider(repository, accountAddress);
provider.setBurnedBalance(Coin.valueOf(255));
provider.save();
RemascStorageProvider newProvider = new RemascStorageProvider(repository, accountAddress);
Assert.assertEquals(Coin.valueOf(255), newProvider.getBurnedBalance());
}
use of org.ethereum.db.MutableRepository in project rskj by rsksmart.
the class RepositoryBuilder method build.
public static Repository build(TrieStore trieStore, Map<String, AccountTck> accounts) {
Repository repositoryDummy = new MutableRepository(new MutableTrieImpl(trieStore, new Trie(trieStore)));
Repository track = repositoryDummy.startTracking();
for (String address : accounts.keySet()) {
RskAddress addr = new RskAddress(address);
AccountTck accountTCK = accounts.get(address);
AccountState state = new AccountState(unifiedNumericToBigInteger(accountTCK.getNonce()), new Coin(unifiedNumericToBigInteger(accountTCK.getBalance())));
track.updateAccountState(addr, state);
byte[] code = parseData(accountTCK.getCode());
if (accountTCK.isForcedContract() || code.length > 0 || !accountTCK.getStorage().isEmpty()) {
track.setupContract(addr);
track.saveCode(addr, code);
saveStorageValues(track, addr, accountTCK.getStorage());
}
}
track.commit();
return repositoryDummy;
}
use of org.ethereum.db.MutableRepository in project rskj by rsksmart.
the class BlockExecutorTest method generateBlockWithOneTransaction.
private static TestObjects generateBlockWithOneTransaction() {
TrieStore trieStore = new TrieStoreImpl(new HashMapDB());
Repository repository = new MutableRepository(trieStore, new Trie(trieStore));
Repository track = repository.startTracking();
Account account = createAccount("acctest1", track, Coin.valueOf(30000));
Account account2 = createAccount("acctest2", track, Coin.valueOf(10L));
track.commit();
Assert.assertFalse(Arrays.equals(EMPTY_TRIE_HASH, repository.getRoot()));
BlockExecutor executor = buildBlockExecutor(trieStore);
Transaction tx1 = Transaction.builder().nonce(repository.getNonce(account.getAddress())).gasPrice(BigInteger.ONE).gasLimit(BigInteger.valueOf(21000)).destination(account2.getAddress()).chainId(CONFIG.getNetworkConstants().getChainId()).value(BigInteger.TEN).build();
tx1.sign(account.getEcKey().getPrivKeyBytes());
Transaction tx = tx1;
List<Transaction> txs = new ArrayList<>();
txs.add(tx);
List<BlockHeader> uncles = new ArrayList<>();
// getGenesisBlock() modifies the repository, adding some pre-mined accounts
// Not nice for a getter, but it is what it is :(
Block genesis = BlockChainImplTest.getGenesisBlock(trieStore);
genesis.setStateRoot(repository.getRoot());
// Returns the root state prior block execution but after loading
// some sample accounts (account/account2) and the premined accounts
// in genesis.
byte[] rootPriorExecution = repository.getRoot();
Block block = new BlockGenerator().createChildBlock(genesis, txs, uncles, 1, null);
executor.executeAndFill(block, genesis.getHeader());
repository.save();
return new TestObjects(trieStore, block, genesis, tx, account, rootPriorExecution);
}
use of org.ethereum.db.MutableRepository in project rskj by rsksmart.
the class BlockExecutorTest method executeBlockWithTwoTransactions.
@Test
public void executeBlockWithTwoTransactions() {
// this changes the best block
Block block = getBlockWithTwoTransactions();
Block parent = blockchain.getBestBlock();
Transaction tx1 = block.getTransactionsList().get(0);
Transaction tx2 = block.getTransactionsList().get(1);
RskAddress account = tx1.getSender();
BlockResult result = executor.execute(block, parent.getHeader(), false);
Assert.assertNotNull(result);
Assert.assertNotNull(result.getTransactionReceipts());
Assert.assertFalse(result.getTransactionReceipts().isEmpty());
Assert.assertEquals(2, result.getTransactionReceipts().size());
TransactionReceipt receipt = result.getTransactionReceipts().get(0);
Assert.assertEquals(tx1, receipt.getTransaction());
Assert.assertEquals(21000, new BigInteger(1, receipt.getGasUsed()).longValue());
Assert.assertEquals(21000, BigIntegers.fromUnsignedByteArray(receipt.getCumulativeGas()).longValue());
Assert.assertTrue(receipt.hasTxStatus() && receipt.isTxStatusOK() && receipt.isSuccessful());
receipt = result.getTransactionReceipts().get(1);
Assert.assertEquals(tx2, receipt.getTransaction());
Assert.assertEquals(21000, new BigInteger(1, receipt.getGasUsed()).longValue());
Assert.assertEquals(42000, BigIntegers.fromUnsignedByteArray(receipt.getCumulativeGas()).longValue());
Assert.assertTrue(receipt.hasTxStatus() && receipt.isTxStatusOK() && receipt.isSuccessful());
Assert.assertEquals(42000, result.getGasUsed());
Assert.assertEquals(42000, result.getPaidFees().asBigInteger().intValueExact());
// here is the problem: in the prior code repository root would never be overwritten by childs
// while the new code does overwrite the root.
// Which semantic is correct ? I don't know
Assert.assertFalse(Arrays.equals(parent.getStateRoot(), result.getFinalState().getHash().getBytes()));
byte[] calculatedLogsBloom = BlockExecutor.calculateLogsBloom(result.getTransactionReceipts());
Assert.assertEquals(256, calculatedLogsBloom.length);
Assert.assertArrayEquals(new byte[256], calculatedLogsBloom);
AccountState accountState = repository.getAccountState(account);
Assert.assertNotNull(accountState);
Assert.assertEquals(BigInteger.valueOf(60000), accountState.getBalance().asBigInteger());
// here is the papa. my commit changes stateroot while previous commit did not.
Repository finalRepository = new MutableRepository(trieStore, trieStore.retrieve(result.getFinalState().getHash().getBytes()).get());
accountState = finalRepository.getAccountState(account);
Assert.assertNotNull(accountState);
Assert.assertEquals(BigInteger.valueOf(60000 - 42000 - 20), accountState.getBalance().asBigInteger());
}
use of org.ethereum.db.MutableRepository in project rskj by rsksmart.
the class RepositoryImplOriginalTest method testMultiThread.
// testing for snapshot
@Test
public void testMultiThread() throws InterruptedException {
TrieStore trieStore = new TrieStoreImpl(new HashMapDB());
MutableTrieImpl mutableTrie = new MutableTrieImpl(trieStore, new Trie(trieStore));
final Repository repository = new MutableRepository(mutableTrie);
final DataWord cowKey1 = DataWord.valueFromHex("c1");
final DataWord cowKey2 = DataWord.valueFromHex("c2");
final DataWord cowVal0 = DataWord.valueFromHex("c0a0");
Repository track2 = repository.startTracking();
track2.addStorageRow(COW, cowKey2, cowVal0);
track2.commit();
// Changes commited to repository
assertThat(repository.getStorageValue(COW, cowKey2), is(cowVal0));
final CountDownLatch failSema = new CountDownLatch(1);
// First create the 10 snapshots. The snapshots should not be created while the
// repository is being changed.
Repository[] snaps = new Repository[10];
for (int i = 0; i < 10; ++i) {
snaps[i] = new MutableRepository(trieStore, trieStore.retrieve(repository.getRoot()).get());
}
for (int i = 0; i < 10; ++i) {
int finalI = i;
new Thread(() -> {
try {
int cnt = 1;
while (running) {
Repository snap = snaps[finalI].startTracking();
snap.addBalance(COW, Coin.valueOf(10L));
snap.addStorageRow(COW, cowKey1, DataWord.valueOf(cnt));
snap.rollback();
cnt++;
}
} catch (Throwable e) {
e.printStackTrace();
failSema.countDown();
}
}).start();
}
new Thread(() -> {
int cnt = 1;
try {
while (running) {
Repository track21 = repository.startTracking();
DataWord cVal = DataWord.valueOf(cnt);
track21.addStorageRow(COW, cowKey1, cVal);
track21.addBalance(COW, Coin.valueOf(1L));
track21.commit();
assertEquals(BigInteger.valueOf(cnt), repository.getBalance(COW).asBigInteger());
assertEquals(cVal, repository.getStorageValue(COW, cowKey1));
assertEquals(cowVal0, repository.getStorageValue(COW, cowKey2));
cnt++;
}
} catch (Throwable e) {
e.printStackTrace();
try {
repository.addStorageRow(COW, cowKey1, DataWord.valueOf(123));
} catch (Exception e1) {
e1.printStackTrace();
}
failSema.countDown();
}
}).start();
failSema.await(10, TimeUnit.SECONDS);
running = false;
if (failSema.getCount() == 0) {
throw new RuntimeException("Test failed.");
}
}
Aggregations