Search in sources :

Example 51 with RepositoryImpl

use of co.rsk.db.RepositoryImpl in project rskj by rsksmart.

the class BlockExecutorTest method executeBlockWithoutTransaction.

@Test
public void executeBlockWithoutTransaction() {
    BlockGenerator blockGenerator = new BlockGenerator();
    Block block = blockGenerator.createChildBlock(blockGenerator.getGenesisBlock());
    Repository repository = new RepositoryImpl(config, new TrieStoreImpl(new HashMapDB()));
    Repository track = repository.startTracking();
    Account account = createAccount("acctest1", track, Coin.valueOf(10L));
    Assert.assertTrue(account.getEcKey().hasPrivKey());
    track.commit();
    Assert.assertFalse(Arrays.equals(EMPTY_TRIE_HASH, repository.getRoot()));
    BlockExecutor executor = new BlockExecutor(config, repository, null, null, null);
    BlockResult result = executor.execute(block, repository.getRoot(), false);
    Assert.assertNotNull(result);
    Assert.assertNotNull(result.getTransactionReceipts());
    Assert.assertTrue(result.getTransactionReceipts().isEmpty());
    Assert.assertArrayEquals(repository.getRoot(), result.getStateRoot());
    AccountState accountState = repository.getAccountState(account.getAddress());
    Assert.assertNotNull(accountState);
    Assert.assertEquals(BigInteger.TEN, accountState.getBalance().asBigInteger());
}
Also used : TrieStoreImpl(co.rsk.trie.TrieStoreImpl) RepositoryImpl(co.rsk.db.RepositoryImpl) HashMapDB(org.ethereum.datasource.HashMapDB) BlockGenerator(co.rsk.blockchain.utils.BlockGenerator) Test(org.junit.Test)

Example 52 with RepositoryImpl

use of co.rsk.db.RepositoryImpl in project rskj by rsksmart.

the class BlockExecutorTest method executeAndFillBlockWithTxToExcludeBecauseSenderHasNoBalance.

@Test
public void executeAndFillBlockWithTxToExcludeBecauseSenderHasNoBalance() {
    Repository repository = new RepositoryImpl(config, new TrieStoreImpl(new HashMapDB()));
    Repository track = repository.startTracking();
    Account account = createAccount("acctest1", track, Coin.valueOf(30000));
    Account account2 = createAccount("acctest2", track, Coin.valueOf(10L));
    Account account3 = createAccount("acctest3", track, Coin.ZERO);
    track.commit();
    Assert.assertFalse(Arrays.equals(EMPTY_TRIE_HASH, repository.getRoot()));
    BlockExecutor executor = new BlockExecutor(config, repository, null, null, null);
    Transaction tx = createTransaction(account, account2, BigInteger.TEN, repository.getNonce(account.getAddress()));
    Transaction tx2 = createTransaction(account3, account2, BigInteger.TEN, repository.getNonce(account3.getAddress()));
    List<Transaction> txs = new ArrayList<>();
    txs.add(tx);
    txs.add(tx2);
    List<BlockHeader> uncles = new ArrayList<>();
    BlockGenerator blockGenerator = new BlockGenerator();
    Block genesis = blockGenerator.getGenesisBlock();
    genesis.setStateRoot(repository.getRoot());
    Block block = blockGenerator.createChildBlock(genesis, txs, uncles, 1, null);
    executor.executeAndFill(block, genesis);
    // Check tx2 was excluded
    Assert.assertEquals(1, block.getTransactionsList().size());
    Assert.assertEquals(tx, block.getTransactionsList().get(0));
    Assert.assertArrayEquals(Block.getTxTrie(Lists.newArrayList(tx)).getHash().getBytes(), block.getTxTrieRoot());
    Assert.assertEquals(3141592, new BigInteger(1, block.getGasLimit()).longValue());
}
Also used : TrieStoreImpl(co.rsk.trie.TrieStoreImpl) ArrayList(java.util.ArrayList) HashMapDB(org.ethereum.datasource.HashMapDB) BlockGenerator(co.rsk.blockchain.utils.BlockGenerator) RepositoryImpl(co.rsk.db.RepositoryImpl) BigInteger(java.math.BigInteger) Test(org.junit.Test)

Example 53 with RepositoryImpl

use of co.rsk.db.RepositoryImpl in project rskj by rsksmart.

the class TestRunner method runTestCase.

public List<String> runTestCase(TestCase testCase) {
    logger.info("\n***");
    logger.info(" Running test case: [" + testCase.getName() + "]");
    logger.info("***\n");
    List<String> results = new ArrayList<>();
    logger.info("--------- PRE ---------");
    Repository repository = loadRepository(new RepositoryImpl(config).startTracking(), testCase.getPre());
    try {
        /* 2. Create ProgramInvoke - Env/Exec */
        Env env = testCase.getEnv();
        Exec exec = testCase.getExec();
        Logs logs = testCase.getLogs();
        byte[] address = exec.getAddress();
        byte[] origin = exec.getOrigin();
        byte[] caller = exec.getCaller();
        byte[] balance = ByteUtil.bigIntegerToBytes(repository.getBalance(new RskAddress(exec.getAddress())).asBigInteger());
        byte[] gasPrice = exec.getGasPrice();
        byte[] gas = exec.getGas();
        byte[] callValue = exec.getValue();
        byte[] msgData = exec.getData();
        byte[] lastHash = env.getPreviousHash();
        byte[] coinbase = env.getCurrentCoinbase();
        long timestamp = ByteUtil.byteArrayToLong(env.getCurrentTimestamp());
        long number = ByteUtil.byteArrayToLong(env.getCurrentNumber());
        byte[] difficulty = env.getCurrentDifficulty();
        byte[] gaslimit = env.getCurrentGasLimit();
        // Origin and caller need to exist in order to be able to execute
        if (repository.getAccountState(new RskAddress(origin)) == null)
            repository.createAccount(new RskAddress(origin));
        if (repository.getAccountState(new RskAddress(caller)) == null)
            repository.createAccount(new RskAddress(caller));
        ProgramInvoke programInvoke = new ProgramInvokeImpl(address, origin, caller, balance, gasPrice, gas, callValue, msgData, lastHash, coinbase, timestamp, number, 0, difficulty, gaslimit, repository, new BlockStoreDummy(), true);
        /* 3. Create Program - exec.code */
        /* 4. run VM */
        VM vm = new VM(vmConfig, precompiledContracts);
        Program program = new Program(vmConfig, precompiledContracts, mock(BlockchainConfig.class), exec.getCode(), programInvoke, null);
        boolean vmDidThrowAnEception = false;
        Exception e = null;
        ThreadMXBean thread;
        Boolean oldMode;
        long startTime = 0;
        thread = ManagementFactory.getThreadMXBean();
        if (thread.isThreadCpuTimeSupported()) {
            oldMode = thread.isThreadCpuTimeEnabled();
            thread.setThreadCpuTimeEnabled(true);
            // in nanoseconds.
            startTime = thread.getCurrentThreadCpuTime();
        }
        try {
            vm.steps(program, Long.MAX_VALUE);
            ;
        } catch (RuntimeException ex) {
            vmDidThrowAnEception = true;
            e = ex;
        }
        if (startTime != 0) {
            long endTime = thread.getCurrentThreadCpuTime();
            // de nano a micro.
            long deltaTime = (endTime - startTime) / 1000;
            logger.info("Time elapsed [uS]: " + Long.toString(deltaTime));
        }
        try {
            saveProgramTraceFile(config, testCase.getName(), program.getTrace());
        } catch (IOException ioe) {
            vmDidThrowAnEception = true;
            e = ioe;
        }
        if (testCase.getPost().size() == 0) {
            if (vmDidThrowAnEception != true) {
                String output = "VM was expected to throw an exception";
                logger.info(output);
                results.add(output);
            } else
                logger.info("VM did throw an exception: " + e.toString());
        } else {
            if (vmDidThrowAnEception) {
                String output = "VM threw an unexpected exception: " + e.toString();
                logger.info(output, e);
                results.add(output);
                return results;
            }
            this.trace = program.getTrace();
            logger.info("--------- POST --------");
            /* 5. Assert Post values */
            for (RskAddress addr : testCase.getPost().keySet()) {
                AccountState accountState = testCase.getPost().get(addr);
                long expectedNonce = accountState.getNonceLong();
                Coin expectedBalance = accountState.getBalance();
                byte[] expectedCode = accountState.getCode();
                boolean accountExist = (null != repository.getAccountState(addr));
                if (!accountExist) {
                    String output = String.format("The expected account does not exist. key: [ %s ]", addr);
                    logger.info(output);
                    results.add(output);
                    continue;
                }
                long actualNonce = repository.getNonce(addr).longValue();
                Coin actualBalance = repository.getBalance(addr);
                byte[] actualCode = repository.getCode(addr);
                if (actualCode == null)
                    actualCode = "".getBytes();
                if (expectedNonce != actualNonce) {
                    String output = String.format("The nonce result is different. key: [ %s ],  expectedNonce: [ %d ] is actualNonce: [ %d ] ", addr, expectedNonce, actualNonce);
                    logger.info(output);
                    results.add(output);
                }
                if (!expectedBalance.equals(actualBalance)) {
                    String output = String.format("The balance result is different. key: [ %s ],  expectedBalance: [ %s ] is actualBalance: [ %s ] ", addr, expectedBalance.toString(), actualBalance.toString());
                    logger.info(output);
                    results.add(output);
                }
                if (!Arrays.equals(expectedCode, actualCode)) {
                    String output = String.format("The code result is different. account: [ %s ],  expectedCode: [ %s ] is actualCode: [ %s ] ", addr, Hex.toHexString(expectedCode), Hex.toHexString(actualCode));
                    logger.info(output);
                    results.add(output);
                }
                // assert storage
                Map<DataWord, DataWord> storage = accountState.getStorage();
                for (DataWord storageKey : storage.keySet()) {
                    byte[] expectedStValue = storage.get(storageKey).getData();
                    ContractDetails contractDetails = program.getStorage().getContractDetails(accountState.getAddress());
                    if (contractDetails == null) {
                        String output = String.format("Storage raw doesn't exist: key [ %s ], expectedValue: [ %s ]", Hex.toHexString(storageKey.getData()), Hex.toHexString(expectedStValue));
                        logger.info(output);
                        results.add(output);
                        continue;
                    }
                    Map<DataWord, DataWord> testStorage = contractDetails.getStorage();
                    DataWord actualValue = testStorage.get(new DataWord(storageKey.getData()));
                    if (actualValue == null || !Arrays.equals(expectedStValue, actualValue.getData())) {
                        String output = String.format("Storage value different: key [ %s ], expectedValue: [ %s ], actualValue: [ %s ]", Hex.toHexString(storageKey.getData()), Hex.toHexString(expectedStValue), actualValue == null ? "" : Hex.toHexString(actualValue.getNoLeadZeroesData()));
                        logger.info(output);
                        results.add(output);
                    }
                }
                /* asset logs */
                List<LogInfo> logResult = program.getResult().getLogInfoList();
                Iterator<LogInfo> postLogs = logs.getIterator();
                int i = 0;
                while (postLogs.hasNext()) {
                    LogInfo expectedLogInfo = postLogs.next();
                    LogInfo foundLogInfo = null;
                    if (logResult.size() > i) {
                        foundLogInfo = logResult.get(i);
                    }
                    if (foundLogInfo == null) {
                        String output = String.format("Expected log [ %s ]", expectedLogInfo.toString());
                        logger.info(output);
                        results.add(output);
                    } else {
                        if (!Arrays.equals(expectedLogInfo.getAddress(), foundLogInfo.getAddress())) {
                            String output = String.format("Expected address [ %s ], found [ %s ]", Hex.toHexString(expectedLogInfo.getAddress()), Hex.toHexString(foundLogInfo.getAddress()));
                            logger.info(output);
                            results.add(output);
                        }
                        if (!Arrays.equals(expectedLogInfo.getData(), foundLogInfo.getData())) {
                            String output = String.format("Expected data [ %s ], found [ %s ]", Hex.toHexString(expectedLogInfo.getData()), Hex.toHexString(foundLogInfo.getData()));
                            logger.info(output);
                            results.add(output);
                        }
                        if (!expectedLogInfo.getBloom().equals(foundLogInfo.getBloom())) {
                            String output = String.format("Expected bloom [ %s ], found [ %s ]", Hex.toHexString(expectedLogInfo.getBloom().getData()), Hex.toHexString(foundLogInfo.getBloom().getData()));
                            logger.info(output);
                            results.add(output);
                        }
                        if (expectedLogInfo.getTopics().size() != foundLogInfo.getTopics().size()) {
                            String output = String.format("Expected number of topics [ %d ], found [ %d ]", expectedLogInfo.getTopics().size(), foundLogInfo.getTopics().size());
                            logger.info(output);
                            results.add(output);
                        } else {
                            int j = 0;
                            for (DataWord topic : expectedLogInfo.getTopics()) {
                                byte[] foundTopic = foundLogInfo.getTopics().get(j).getData();
                                if (!Arrays.equals(topic.getData(), foundTopic)) {
                                    String output = String.format("Expected topic [ %s ], found [ %s ]", Hex.toHexString(topic.getData()), Hex.toHexString(foundTopic));
                                    logger.info(output);
                                    results.add(output);
                                }
                                ++j;
                            }
                        }
                    }
                    ++i;
                }
            }
            // TODO: assert that you have no extra accounts in the repository
            // TODO:  -> basically the deleted by suicide should be deleted
            // TODO:  -> and no unexpected created
            List<org.ethereum.vm.CallCreate> resultCallCreates = program.getResult().getCallCreateList();
            // assert call creates
            for (int i = 0; i < testCase.getCallCreateList().size(); ++i) {
                org.ethereum.vm.CallCreate resultCallCreate = null;
                if (resultCallCreates != null && resultCallCreates.size() > i) {
                    resultCallCreate = resultCallCreates.get(i);
                }
                CallCreate expectedCallCreate = testCase.getCallCreateList().get(i);
                if (resultCallCreate == null && expectedCallCreate != null) {
                    String output = String.format("Missing call/create invoke: to: [ %s ], data: [ %s ], gas: [ %s ], value: [ %s ]", Hex.toHexString(expectedCallCreate.getDestination()), Hex.toHexString(expectedCallCreate.getData()), Long.toHexString(expectedCallCreate.getGasLimit()), Hex.toHexString(expectedCallCreate.getValue()));
                    logger.info(output);
                    results.add(output);
                    continue;
                }
                boolean assertDestination = Arrays.equals(expectedCallCreate.getDestination(), resultCallCreate.getDestination());
                if (!assertDestination) {
                    String output = String.format("Call/Create destination is different. Expected: [ %s ], result: [ %s ]", Hex.toHexString(expectedCallCreate.getDestination()), Hex.toHexString(resultCallCreate.getDestination()));
                    logger.info(output);
                    results.add(output);
                }
                boolean assertData = Arrays.equals(expectedCallCreate.getData(), resultCallCreate.getData());
                if (!assertData) {
                    String output = String.format("Call/Create data is different. Expected: [ %s ], result: [ %s ]", Hex.toHexString(expectedCallCreate.getData()), Hex.toHexString(resultCallCreate.getData()));
                    logger.info(output);
                    results.add(output);
                }
                boolean assertGasLimit = expectedCallCreate.getGasLimit() == resultCallCreate.getGasLimit();
                if (!assertGasLimit) {
                    String output = String.format("Call/Create gasLimit is different. Expected: [ %s ], result: [ %s ]", Long.toHexString(expectedCallCreate.getGasLimit()), Long.toHexString(resultCallCreate.getGasLimit()));
                    logger.info(output);
                    results.add(output);
                }
                boolean assertValue = Arrays.equals(expectedCallCreate.getValue(), resultCallCreate.getValue());
                if (!assertValue) {
                    String output = String.format("Call/Create value is different. Expected: [ %s ], result: [ %s ]", Hex.toHexString(expectedCallCreate.getValue()), Hex.toHexString(resultCallCreate.getValue()));
                    logger.info(output);
                    results.add(output);
                }
            }
            // assert out
            byte[] expectedHReturn = testCase.getOut();
            byte[] actualHReturn = EMPTY_BYTE_ARRAY;
            if (program.getResult().getHReturn() != null) {
                actualHReturn = program.getResult().getHReturn();
            }
            if (!Arrays.equals(expectedHReturn, actualHReturn)) {
                String output = String.format("HReturn is different. Expected hReturn: [ %s ], actual hReturn: [ %s ]", Hex.toHexString(expectedHReturn), Hex.toHexString(actualHReturn));
                logger.info(output);
                results.add(output);
            }
            // assert gas
            BigInteger expectedGas = new BigInteger(1, testCase.getGas());
            BigInteger actualGas = new BigInteger(1, gas).subtract(BigInteger.valueOf(program.getResult().getGasUsed()));
            if (validateGasUsed)
                if (!expectedGas.equals(actualGas)) {
                    String output = String.format("Gas remaining is different. Expected gas remaining: [ %s ], actual gas remaining: [ %s ]", expectedGas.toString(), actualGas.toString());
                    logger.info(output);
                    results.add(output);
                }
        /*
                 * end of if(testCase.getPost().size() == 0)
                 */
        }
        return results;
    } finally {
    // repository.close();
    }
}
Also used : DataWord(org.ethereum.vm.DataWord) ProgramInvokeImpl(org.ethereum.vm.program.invoke.ProgramInvokeImpl) ProgramInvoke(org.ethereum.vm.program.invoke.ProgramInvoke) Coin(co.rsk.core.Coin) RskAddress(co.rsk.core.RskAddress) ThreadMXBean(java.lang.management.ThreadMXBean) Program(org.ethereum.vm.program.Program) LogInfo(org.ethereum.vm.LogInfo) IOException(java.io.IOException) IOException(java.io.IOException) Repository(org.ethereum.core.Repository) BlockchainConfig(org.ethereum.config.BlockchainConfig) RepositoryImpl(co.rsk.db.RepositoryImpl) VM(org.ethereum.vm.VM) BigInteger(java.math.BigInteger)

Example 54 with RepositoryImpl

use of co.rsk.db.RepositoryImpl in project rskj by rsksmart.

the class RepositoryBuilder method build.

public static Repository build(Map<String, AccountTck> accounts) {
    HashMap<RskAddress, AccountState> stateBatch = new HashMap<>();
    HashMap<RskAddress, ContractDetails> detailsBatch = new HashMap<>();
    for (String address : accounts.keySet()) {
        RskAddress addr = new RskAddress(address);
        AccountTck accountTCK = accounts.get(address);
        AccountBuilder.StateWrap stateWrap = AccountBuilder.build(accountTCK);
        AccountState state = stateWrap.getAccountState();
        ContractDetails details = stateWrap.getContractDetails();
        stateBatch.put(addr, state);
        ContractDetailsCacheImpl detailsCache = new ContractDetailsCacheImpl(details);
        detailsCache.setDirty(true);
        detailsBatch.put(addr, detailsCache);
    }
    RepositoryImpl repositoryDummy = new RepositoryImpl(new RskSystemProperties(), new TrieStoreImpl(new HashMapDB()));
    Repository track = repositoryDummy.startTracking();
    track.updateBatch(stateBatch, detailsBatch);
    track.commit();
    return repositoryDummy;
}
Also used : AccountTck(org.ethereum.jsontestsuite.model.AccountTck) TrieStoreImpl(co.rsk.trie.TrieStoreImpl) HashMap(java.util.HashMap) AccountState(org.ethereum.core.AccountState) HashMapDB(org.ethereum.datasource.HashMapDB) ContractDetails(org.ethereum.db.ContractDetails) Repository(org.ethereum.core.Repository) RepositoryImpl(co.rsk.db.RepositoryImpl) RskAddress(co.rsk.core.RskAddress) ContractDetailsCacheImpl(org.ethereum.db.ContractDetailsCacheImpl) RskSystemProperties(co.rsk.config.RskSystemProperties)

Example 55 with RepositoryImpl

use of co.rsk.db.RepositoryImpl in project rskj by rsksmart.

the class BridgePerformanceTestCase method execute.

private ExecutionTracker execute(ABIEncoder abiEncoder, BridgeStorageProviderInitializer storageInitializer, TxBuilder txBuilder, HeightProvider heightProvider, int executionIndex) {
    ExecutionTracker executionInfo = new ExecutionTracker(thread);
    RepositoryImpl repository = new RepositoryImpl(config);
    Repository track = repository.startTracking();
    BridgeStorageProvider storageProvider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants);
    storageInitializer.initialize(storageProvider, track, executionIndex);
    try {
        storageProvider.save();
    } catch (Exception e) {
        throw new RuntimeException("Error trying to save the storage after initialization", e);
    }
    track.commit();
    Transaction tx = txBuilder.build(executionIndex);
    List<LogInfo> logs = new ArrayList<>();
    RepositoryTrackWithBenchmarking benchmarkerTrack = new RepositoryTrackWithBenchmarking(config, repository);
    Bridge bridge = new Bridge(config, PrecompiledContracts.BRIDGE_ADDR);
    Blockchain blockchain = BlockChainBuilder.ofSizeWithNoTransactionPoolCleaner(heightProvider.getHeight(executionIndex));
    bridge.init(tx, blockchain.getBestBlock(), benchmarkerTrack, blockchain.getBlockStore(), null, logs);
    // Execute a random method so that bridge support initialization
    // does its initial writes to the repo for e.g. genesis block,
    // federation, etc, etc. and we don't get
    // those recorded in the actual execution.
    bridge.execute(Bridge.GET_FEDERATION_SIZE.encode());
    benchmarkerTrack.getStatistics().clear();
    executionInfo.startTimer();
    bridge.execute(abiEncoder.encode(executionIndex));
    executionInfo.endTimer();
    benchmarkerTrack.commit();
    executionInfo.setRepositoryStatistics(benchmarkerTrack.getStatistics());
    return executionInfo;
}
Also used : LogInfo(org.ethereum.vm.LogInfo) BridgeStorageProvider(co.rsk.peg.BridgeStorageProvider) Blockchain(org.ethereum.core.Blockchain) ArrayList(java.util.ArrayList) RepositoryTrackWithBenchmarking(co.rsk.db.RepositoryTrackWithBenchmarking) Repository(org.ethereum.core.Repository) Transaction(org.ethereum.core.Transaction) RepositoryImpl(co.rsk.db.RepositoryImpl) Bridge(co.rsk.peg.Bridge)

Aggregations

RepositoryImpl (co.rsk.db.RepositoryImpl)62 Test (org.junit.Test)54 Repository (org.ethereum.core.Repository)25 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)22 RskAddress (co.rsk.core.RskAddress)19 TrieStoreImpl (co.rsk.trie.TrieStoreImpl)16 HashMapDB (org.ethereum.datasource.HashMapDB)15 co.rsk.bitcoinj.core (co.rsk.bitcoinj.core)13 org.ethereum.core (org.ethereum.core)13 BlockGenerator (co.rsk.blockchain.utils.BlockGenerator)12 LogInfo (org.ethereum.vm.LogInfo)12 SimpleRskTransaction (co.rsk.peg.simples.SimpleRskTransaction)11 BridgeConstants (co.rsk.config.BridgeConstants)10 BridgeEventLogger (co.rsk.peg.utils.BridgeEventLogger)10 DataWord (org.ethereum.vm.DataWord)9 ArrayList (java.util.ArrayList)8 BtcBlockStore (co.rsk.bitcoinj.store.BtcBlockStore)7 ECKey (org.ethereum.crypto.ECKey)7 Keccak256 (co.rsk.crypto.Keccak256)6 SimpleBlockChain (co.rsk.peg.simples.SimpleBlockChain)6