Search in sources :

Example 6 with VMException

use of org.ethereum.vm.exception.VMException in project rskj by rsksmart.

the class BridgePerformanceTestCase method executeAndAverage.

protected ExecutionStats executeAndAverage(String name, int times, ABIEncoder abiEncoder, BridgeStorageProviderInitializer storageInitializer, TxBuilder txBuilder, HeightProvider heightProvider, ExecutionStats stats, ResultCallback resultCallback, PostInitCallback postInitCallback) throws VMException {
    EnvironmentBuilder environmentBuilder = new EnvironmentBuilder() {

        private Bridge bridge;

        private RepositoryTrackWithBenchmarking benchmarkerTrack;

        private BridgeStorageProvider storageProvider;

        private TrieStore createTrieStore() {
            return new TrieStoreImpl(new HashMapDB());
        }

        @Override
        public Environment build(int executionIndex, TxBuilder txBuilder, int height) throws VMException {
            TrieStore trieStore = createTrieStore();
            Trie trie = new Trie(trieStore);
            benchmarkerTrack = new RepositoryTrackWithBenchmarking(trieStore, trie);
            Repository repository = benchmarkerTrack.startTracking();
            storageProvider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants, activationConfig.forBlock((long) executionIndex));
            BtcBlockStore btcBlockStore = btcBlockStoreFactory.newInstance(repository, bridgeConstants, storageProvider, activationConfig.forBlock((long) executionIndex));
            storageInitializer.initialize(storageProvider, repository, executionIndex, btcBlockStore);
            repository.addBalance(PrecompiledContracts.BRIDGE_ADDR, co.rsk.core.Coin.fromBitcoin(Coin.COIN.multiply(21_000_000L)));
            try {
                storageProvider.save();
            } catch (Exception e) {
                throw new RuntimeException("Error trying to save the storage after initialization", e);
            }
            repository.commit();
            benchmarkerTrack.commit();
            benchmarkerTrack = new RepositoryTrackWithBenchmarking(trieStore, benchmarkerTrack.getTrie());
            List<LogInfo> logs = new ArrayList<>();
            // TODO: This was commented to make registerBtcCoinbaseTransactionTest & getBtcTransactionConfirmationTest work.
            // Cache is not being populated.
            // Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(
            // constants.getBridgeConstants().getBtcParams());
            BridgeSupportFactory bridgeSupportFactory = new BridgeSupportFactory(btcBlockStoreFactory, constants.getBridgeConstants(), activationConfig);
            bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, bridgeSupportFactory);
            BlockChainBuilder blockChainBuilder = new BlockChainBuilder();
            Blockchain blockchain = blockChainBuilder.ofSize(height);
            Transaction tx = txBuilder.build(executionIndex);
            bridge.init(tx, blockchain.getBestBlock(), benchmarkerTrack, blockChainBuilder.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.
            boolean oldLocalCall = tx.isLocalCallTransaction();
            tx.setLocalCallTransaction(true);
            bridge.execute(Bridge.GET_FEDERATION_SIZE.encode());
            tx.setLocalCallTransaction(oldLocalCall);
            benchmarkerTrack.getStatistics().clear();
            Environment environment = new Environment() {

                @Override
                public PrecompiledContracts.PrecompiledContract getContract() {
                    return bridge;
                }

                @Override
                public BenchmarkedRepository getBenchmarkedRepository() {
                    return benchmarkerTrack;
                }

                @Override
                public void finalise() {
                    benchmarkerTrack.commit();
                }
            };
            if (postInitCallback != null) {
                postInitCallback.afterInit(environment);
            }
            return environment;
        }
    };
    return super.executeAndAverage(name, times, environmentBuilder, abiEncoder, txBuilder, heightProvider, stats, resultCallback);
}
Also used : TrieStoreImpl(co.rsk.trie.TrieStoreImpl) LogInfo(org.ethereum.vm.LogInfo) Blockchain(org.ethereum.core.Blockchain) BtcBlockStore(co.rsk.bitcoinj.store.BtcBlockStore) HashMapDB(org.ethereum.datasource.HashMapDB) TrieStore(co.rsk.trie.TrieStore) BlockChainBuilder(co.rsk.test.builders.BlockChainBuilder) RepositoryTrackWithBenchmarking(co.rsk.db.RepositoryTrackWithBenchmarking) VMException(org.ethereum.vm.exception.VMException) BenchmarkedRepository(co.rsk.db.BenchmarkedRepository) Repository(org.ethereum.core.Repository) PrecompiledContracts(org.ethereum.vm.PrecompiledContracts) InternalTransaction(org.ethereum.vm.program.InternalTransaction) Transaction(org.ethereum.core.Transaction) Trie(co.rsk.trie.Trie)

Example 7 with VMException

use of org.ethereum.vm.exception.VMException in project rskj by rsksmart.

the class UpdateCollectionsTest method updateCollections_confirmTxs.

private void updateCollections_confirmTxs(ExecutionStats stats, int numCases) throws IOException, VMException {
    final int minTxsWaitingForSigs = 0;
    final int maxTxsWaitingForSigs = 10;
    final int minReleaseTxs = 1;
    final int maxReleaseTxs = 100;
    final int minBlockNumber = 10;
    final int maxBlockNumber = 100;
    final int minHeight = 50;
    final int maxHeight = 150;
    final int minCentOutput = 1;
    final int maxCentOutput = 100;
    final NetworkParameters parameters = NetworkParameters.fromID(NetworkParameters.ID_REGTEST);
    BridgeStorageProviderInitializer storageInitializer = (BridgeStorageProvider provider, Repository repository, int executionIndex, BtcBlockStore blockStore) -> {
        Random rnd = new Random();
        SortedMap<Keccak256, BtcTransaction> txsWaitingForSignatures;
        ReleaseTransactionSet txSet;
        try {
            txsWaitingForSignatures = provider.getRskTxsWaitingForSignatures();
        } catch (Exception e) {
            throw new RuntimeException("Unable to gather txs waiting for signatures");
        }
        try {
            txSet = provider.getReleaseTransactionSet();
        } catch (Exception e) {
            throw new RuntimeException("Unable to gather release tx set");
        }
        // Generate some txs waiting for signatures
        Script genesisFederationScript = bridgeConstants.getGenesisFederation().getP2SHScript();
        for (int i = 0; i < Helper.randomInRange(minTxsWaitingForSigs, maxTxsWaitingForSigs); i++) {
            Keccak256 rskHash = new Keccak256(HashUtil.keccak256(BigInteger.valueOf(rnd.nextLong()).toByteArray()));
            BtcTransaction btcTx = new BtcTransaction(networkParameters);
            Sha256Hash inputHash = Sha256Hash.wrap(HashUtil.sha256(BigInteger.valueOf(rnd.nextLong()).toByteArray()));
            btcTx.addInput(inputHash, 0, genesisFederationScript);
            btcTx.addOutput(Helper.randomCoin(Coin.CENT, minCentOutput, maxCentOutput), new BtcECKey());
            txsWaitingForSignatures.put(rskHash, btcTx);
        }
        // Generate some txs waiting for confirmations
        for (int i = 0; i < Helper.randomInRange(minReleaseTxs, maxReleaseTxs); i++) {
            BtcTransaction btcTx = new BtcTransaction(networkParameters);
            Sha256Hash inputHash = Sha256Hash.wrap(HashUtil.sha256(BigInteger.valueOf(rnd.nextLong()).toByteArray()));
            btcTx.addInput(inputHash, 0, genesisFederationScript);
            btcTx.addOutput(Helper.randomCoin(Coin.CENT, minCentOutput, maxCentOutput), new BtcECKey());
            long blockNumber = Helper.randomInRange(minBlockNumber, maxBlockNumber);
            txSet.add(btcTx, blockNumber);
        }
    };
    final byte[] updateCollectionsEncoded = Bridge.UPDATE_COLLECTIONS.encode();
    ABIEncoder abiEncoder = (int executionIndex) -> updateCollectionsEncoded;
    HeightProvider heightProvider = (int executionIndex) -> Helper.randomInRange(minHeight, maxHeight);
    executeAndAverage("updateCollections-releaseTxs", numCases, abiEncoder, storageInitializer, Helper.getZeroValueValueTxBuilderFromFedMember(), heightProvider, stats);
}
Also used : Script(co.rsk.bitcoinj.script.Script) BridgeStorageProvider(co.rsk.peg.BridgeStorageProvider) BtcBlockStore(co.rsk.bitcoinj.store.BtcBlockStore) Keccak256(co.rsk.crypto.Keccak256) VMException(org.ethereum.vm.exception.VMException) IOException(java.io.IOException) Repository(org.ethereum.core.Repository) Random(java.util.Random) ReleaseTransactionSet(co.rsk.peg.ReleaseTransactionSet) SortedMap(java.util.SortedMap)

Example 8 with VMException

use of org.ethereum.vm.exception.VMException in project rskj by rsksmart.

the class UpdateCollectionsTest method updateCollections_buildReleaseTxs.

private void updateCollections_buildReleaseTxs(ExecutionStats stats, int numCases) throws IOException, VMException {
    final int minUTXOs = 1;
    final int maxUTXOs = 1000;
    final int minMilliBtc = 1;
    final int maxMilliBtc = 1000;
    final int minReleaseRequests = 1;
    final int maxReleaseRequests = 100;
    final int minMilliReleaseBtc = 10;
    final int maxMilliReleaseBtc = 2000;
    final NetworkParameters parameters = NetworkParameters.fromID(NetworkParameters.ID_REGTEST);
    BridgeStorageProviderInitializer storageInitializer = (BridgeStorageProvider provider, Repository repository, int executionIndex, BtcBlockStore blockStore) -> {
        Random rnd = new Random();
        List<UTXO> utxos;
        ReleaseRequestQueue queue;
        try {
            utxos = provider.getNewFederationBtcUTXOs();
        } catch (Exception e) {
            throw new RuntimeException("Unable to gather active federation btc utxos");
        }
        try {
            queue = provider.getReleaseRequestQueue();
        } catch (Exception e) {
            throw new RuntimeException("Unable to gather release request queue");
        }
        // Generate some utxos
        int numUTXOs = Helper.randomInRange(minUTXOs, maxUTXOs);
        Script federationScript = BridgeRegTestConstants.getInstance().getGenesisFederation().getP2SHScript();
        for (int i = 0; i < numUTXOs; i++) {
            Sha256Hash hash = Sha256Hash.wrap(HashUtil.sha256(BigInteger.valueOf(rnd.nextLong()).toByteArray()));
            Coin value = Coin.MILLICOIN.multiply(Helper.randomInRange(minMilliBtc, maxMilliBtc));
            utxos.add(new UTXO(hash, 0, value, 1, false, federationScript));
        }
        // Generate some release requests to process
        for (int i = 0; i < Helper.randomInRange(minReleaseRequests, maxReleaseRequests); i++) {
            Coin value = Coin.MILLICOIN.multiply(Helper.randomInRange(minMilliReleaseBtc, maxMilliReleaseBtc));
            queue.add(new BtcECKey().toAddress(parameters), value, null);
        }
    };
    final byte[] updateCollectionsEncoded = Bridge.UPDATE_COLLECTIONS.encode();
    ABIEncoder abiEncoder = (int executionIndex) -> updateCollectionsEncoded;
    executeAndAverage("updateCollections-releaseRequests", numCases, abiEncoder, storageInitializer, Helper.getZeroValueValueTxBuilderFromFedMember(), Helper.getRandomHeightProvider(10), stats);
}
Also used : Script(co.rsk.bitcoinj.script.Script) BridgeStorageProvider(co.rsk.peg.BridgeStorageProvider) BtcBlockStore(co.rsk.bitcoinj.store.BtcBlockStore) ReleaseRequestQueue(co.rsk.peg.ReleaseRequestQueue) VMException(org.ethereum.vm.exception.VMException) IOException(java.io.IOException) Repository(org.ethereum.core.Repository) Random(java.util.Random) List(java.util.List)

Example 9 with VMException

use of org.ethereum.vm.exception.VMException in project rskj by rsksmart.

the class NativeContract method execute.

@Override
public byte[] execute(byte[] data) throws VMException {
    try {
        // Preliminary validation: we need an execution environment
        if (executionEnvironment == null) {
            throw new VMException("Execution environment is null");
        }
        // Preliminary validation: the transaction on which we execute cannot be null
        if (executionEnvironment.getTransaction() == null) {
            throw new VMException("RSK Transaction is null");
        }
        Optional<NativeMethod.WithArguments> methodWithArguments = parseData(data);
        // No function found with the given data? => halt!
        if (!methodWithArguments.isPresent()) {
            String errorMessage = String.format("Invalid data given: %s.", ByteUtil.toHexString(data));
            logger.info(errorMessage);
            throw new NativeContractIllegalArgumentException(errorMessage);
        }
        NativeMethod method = methodWithArguments.get().getMethod();
        if (!executionEnvironment.isLocalCall() && method.onlyAllowsLocalCalls()) {
            String errorMessage = String.format("Non-local-call to %s. Returning without execution.", method.getName());
            logger.info(errorMessage);
            throw new NativeContractIllegalArgumentException(errorMessage);
        }
        before();
        Object result;
        try {
            result = methodWithArguments.get().execute();
        } catch (NativeContractIllegalArgumentException ex) {
            String errorMessage = String.format("Error executing: %s", method.getName());
            logger.warn(errorMessage, ex);
            throw new NativeContractIllegalArgumentException(errorMessage, ex);
        }
        after();
        // Note: this is hacky, but ultimately very short and to the point.
        if (result == null) {
            return null;
        } else if (result.getClass() == Optional.class) {
            Optional<?> optionalResult = (Optional<?>) result;
            if (!optionalResult.isPresent()) {
                return null;
            } else {
                result = optionalResult.get();
            }
        }
        return method.getFunction().encodeOutputs(result);
    } catch (Exception ex) {
        logger.error(ex.getMessage(), ex);
        panicProcessor.panic("nativecontractexecute", ex.getMessage());
        throw new VMException(String.format("Exception executing native contract: %s", ex.getMessage()), ex);
    }
}
Also used : Optional(java.util.Optional) VMException(org.ethereum.vm.exception.VMException) NativeContractIllegalArgumentException(co.rsk.pcc.exception.NativeContractIllegalArgumentException) NativeContractIllegalArgumentException(co.rsk.pcc.exception.NativeContractIllegalArgumentException) VMException(org.ethereum.vm.exception.VMException)

Example 10 with VMException

use of org.ethereum.vm.exception.VMException in project rskj by rsksmart.

the class TransactionExecutor method call.

private void call() {
    logger.trace("Call transaction {} {}", toBI(tx.getNonce()), tx.getHash());
    RskAddress targetAddress = tx.getReceiveAddress();
    // DataWord(targetAddress)) can fail with exception:
    // java.lang.RuntimeException: Data word can't exceed 32 bytes:
    // if targetAddress size is greater than 32 bytes.
    // But init() will detect this earlier
    precompiledContract = precompiledContracts.getContractForAddress(activations, DataWord.valueOf(targetAddress.getBytes()));
    this.subtraces = new ArrayList<>();
    if (precompiledContract != null) {
        Metric metric = profiler.start(Profiler.PROFILING_TYPE.PRECOMPILED_CONTRACT_INIT);
        precompiledContract.init(tx, executionBlock, track, blockStore, receiptStore, result.getLogInfoList());
        profiler.stop(metric);
        metric = profiler.start(Profiler.PROFILING_TYPE.PRECOMPILED_CONTRACT_EXECUTE);
        long requiredGas = precompiledContract.getGasForData(tx.getData());
        long txGasLimit = GasCost.toGas(tx.getGasLimit());
        long gasUsed = GasCost.add(requiredGas, basicTxCost);
        if (!localCall && !enoughGas(txGasLimit, requiredGas, gasUsed)) {
            // no refund no endowment
            execError(String.format("Out of Gas calling precompiled contract at block %d " + "for address 0x%s. required: %s, used: %s, left: %s ", executionBlock.getNumber(), targetAddress.toString(), requiredGas, gasUsed, gasLeftover));
            gasLeftover = 0;
            profiler.stop(metric);
            return;
        }
        gasLeftover = activations.isActive(ConsensusRule.RSKIP136) ? GasCost.subtract(txGasLimit, gasUsed) : txGasLimit - gasUsed;
        // FIXME: save return for vm trace
        try {
            byte[] out = precompiledContract.execute(tx.getData());
            this.subtraces = precompiledContract.getSubtraces();
            result.setHReturn(out);
            if (!track.isExist(targetAddress)) {
                track.createAccount(targetAddress);
                track.setupContract(targetAddress);
            } else if (!track.isContract(targetAddress)) {
                track.setupContract(targetAddress);
            }
        } catch (VMException | RuntimeException e) {
            result.setException(e);
        }
        result.spendGas(gasUsed);
        profiler.stop(metric);
    } else {
        byte[] code = track.getCode(targetAddress);
        // Code can be null
        if (isEmpty(code)) {
            gasLeftover = GasCost.subtract(GasCost.toGas(tx.getGasLimit()), basicTxCost);
            result.spendGas(basicTxCost);
        } else {
            ProgramInvoke programInvoke = programInvokeFactory.createProgramInvoke(tx, txindex, executionBlock, cacheTrack, blockStore);
            this.vm = new VM(vmConfig, precompiledContracts);
            this.program = new Program(vmConfig, precompiledContracts, blockFactory, activations, code, programInvoke, tx, deletedAccounts);
        }
    }
    if (result.getException() == null) {
        Coin endowment = tx.getValue();
        cacheTrack.transfer(tx.getSender(), targetAddress, endowment);
    }
}
Also used : ProgramInvoke(org.ethereum.vm.program.invoke.ProgramInvoke) Coin(co.rsk.core.Coin) Program(org.ethereum.vm.program.Program) VMException(org.ethereum.vm.exception.VMException) RskAddress(co.rsk.core.RskAddress) Metric(co.rsk.metrics.profilers.Metric)

Aggregations

VMException (org.ethereum.vm.exception.VMException)29 IOException (java.io.IOException)16 BlockStoreException (co.rsk.bitcoinj.store.BlockStoreException)14 Test (org.junit.Test)11 BigInteger (java.math.BigInteger)9 ActivationConfigsForTest (org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest)9 SimpleBtcTransaction (co.rsk.peg.bitcoin.SimpleBtcTransaction)7 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)7 RskAddress (co.rsk.core.RskAddress)6 PrecompiledContracts (org.ethereum.vm.PrecompiledContracts)5 Keccak256 (co.rsk.crypto.Keccak256)4 co.rsk.bitcoinj.core (co.rsk.bitcoinj.core)3 BtcBlockStore (co.rsk.bitcoinj.store.BtcBlockStore)3 BridgeConstants (co.rsk.config.BridgeConstants)3 BridgeRegTestConstants (co.rsk.config.BridgeRegTestConstants)3 TestSystemProperties (co.rsk.config.TestSystemProperties)3 MerkleBranch (co.rsk.peg.bitcoin.MerkleBranch)3 OneOffWhiteListEntry (co.rsk.peg.whitelist.OneOffWhiteListEntry)3 StandardCharsets (java.nio.charset.StandardCharsets)3 Instant (java.time.Instant)3