Search in sources :

Example 11 with ContractDetails

use of org.ethereum.db.ContractDetails in project rskj by rsksmart.

the class ReversibleTransactionExecutorTest method executeTransactionGreeter.

@Test
public void executeTransactionGreeter() {
    TestContract greeter = TestContract.greeter();
    CallTransaction.Function greeterFn = greeter.functions.get("greet");
    ContractDetails contract = contractRunner.addContract(greeter.runtimeBytecode);
    RskAddress from = RskAddress.nullAddress();
    byte[] gasPrice = Hex.decode("00");
    byte[] value = Hex.decode("00");
    byte[] gasLimit = Hex.decode("f424");
    Block bestBlock = factory.getBlockchain().getBestBlock();
    ProgramResult result = reversibleTransactionExecutor.executeTransaction(bestBlock, bestBlock.getCoinbase(), gasPrice, gasLimit, contract.getAddress(), value, greeterFn.encode("greet me"), from.getBytes());
    Assert.assertNull(result.getException());
    Assert.assertArrayEquals(new String[] { "greet me" }, greeterFn.decodeResult(result.getHReturn()));
}
Also used : TestContract(co.rsk.util.TestContract) ProgramResult(org.ethereum.vm.program.ProgramResult) CallTransaction(org.ethereum.core.CallTransaction) Block(org.ethereum.core.Block) ContractDetails(org.ethereum.db.ContractDetails) Test(org.junit.Test)

Example 12 with ContractDetails

use of org.ethereum.db.ContractDetails in project rskj by rsksmart.

the class VM method dumpLine.

/*
     * Dumping the VM state at the current operation in various styles
     *  - standard  Not Yet Implemented
     *  - standard+ (owner address, program counter, operation, gas left)
     *  - pretty (stack, memory, storage, level, contract,
     *              vmCounter, internalSteps, operation
                    gasBefore, gasCost, memWords)
     */
private void dumpLine(OpCode op, long gasBefore, long gasCost, long memWords, Program program) {
    if ("standard+".equals(vmConfig.dumpStyle())) {
        switch(op) {
            case STOP:
            case RETURN:
            case SUICIDE:
                ContractDetails details = program.getStorage().getContractDetails(new RskAddress(program.getOwnerAddress()));
                List<DataWord> storageKeys = new ArrayList<>(details.getStorage().keySet());
                Collections.sort(storageKeys);
                storageKeys.forEach(key -> dumpLogger.trace("{} {}", Hex.toHexString(key.getNoLeadZeroesData()), Hex.toHexString(details.getStorage().get(key).getNoLeadZeroesData())));
                break;
            default:
                break;
        }
        String addressString = Hex.toHexString(program.getOwnerAddress().getLast20Bytes());
        String pcString = Hex.toHexString(new DataWord(program.getPC()).getNoLeadZeroesData());
        String opString = Hex.toHexString(new byte[] { op.val() });
        String gasString = Long.toHexString(program.getRemainingGas());
        dumpLogger.trace("{} {} {} {}", addressString, pcString, opString, gasString);
    } else if ("pretty".equals(vmConfig.dumpStyle())) {
        dumpLogger.trace("-------------------------------------------------------------------------");
        dumpLogger.trace("    STACK");
        program.getStack().forEach(item -> dumpLogger.trace("{}", item));
        dumpLogger.trace("    MEMORY");
        String memoryString = program.memoryToString();
        if (!"".equals(memoryString)) {
            dumpLogger.trace("{}", memoryString);
        }
        dumpLogger.trace("    STORAGE");
        ContractDetails details = program.getStorage().getContractDetails(new RskAddress(program.getOwnerAddress()));
        List<DataWord> storageKeys = new ArrayList<>(details.getStorage().keySet());
        Collections.sort(storageKeys);
        storageKeys.forEach(key -> dumpLogger.trace("{}: {}", key.shortHex(), details.getStorage().get(key).shortHex()));
        int level = program.getCallDeep();
        String contract = Hex.toHexString(program.getOwnerAddress().getLast20Bytes());
        String internalSteps = String.format("%4s", Integer.toHexString(program.getPC())).replace(' ', '0').toUpperCase();
        dumpLogger.trace("{} | {} | #{} | {} : {} | {} | -{} | {}x32", level, contract, vmCounter, internalSteps, op, gasBefore, gasCost, memWords);
    }
}
Also used : Logger(org.slf4j.Logger) MsgType(org.ethereum.vm.MessageCall.MsgType) HashUtil(org.ethereum.crypto.HashUtil) Hex(org.spongycastle.util.encoders.Hex) LoggerFactory(org.slf4j.LoggerFactory) EMPTY_BYTE_ARRAY(org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY) RskAddress(co.rsk.core.RskAddress) ArrayList(java.util.ArrayList) Program(org.ethereum.vm.program.Program) List(java.util.List) VmConfig(co.rsk.config.VmConfig) ContractDetails(org.ethereum.db.ContractDetails) BigInteger(java.math.BigInteger) Stack(org.ethereum.vm.program.Stack) Collections(java.util.Collections) RskAddress(co.rsk.core.RskAddress) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) ContractDetails(org.ethereum.db.ContractDetails)

Example 13 with ContractDetails

use of org.ethereum.db.ContractDetails in project rskj by rsksmart.

the class TransactionExecutor method finalization.

public void finalization() {
    if (!readyToExecute) {
        return;
    }
    // RSK if local call gas balances must not be changed
    if (localCall) {
        return;
    }
    logger.trace("Finalize transaction {} {}", toBI(tx.getNonce()), tx.getHash());
    cacheTrack.commit();
    // Should include only LogInfo's that was added during not rejected transactions
    List<LogInfo> notRejectedLogInfos = result.getLogInfoList().stream().filter(logInfo -> !logInfo.isRejected()).collect(Collectors.toList());
    TransactionExecutionSummary.Builder summaryBuilder = TransactionExecutionSummary.builderFor(tx).gasLeftover(mEndGas).logs(notRejectedLogInfos).result(result.getHReturn());
    if (result != null) {
        // Accumulate refunds for suicides
        result.addFutureRefund((long) result.getDeleteAccounts().size() * GasCost.SUICIDE_REFUND);
        long gasRefund = Math.min(result.getFutureRefund(), result.getGasUsed() / 2);
        RskAddress addr = tx.isContractCreation() ? tx.getContractAddress() : tx.getReceiveAddress();
        mEndGas = mEndGas.add(BigInteger.valueOf(gasRefund));
        summaryBuilder.gasUsed(toBI(result.getGasUsed())).gasRefund(toBI(gasRefund)).deletedAccounts(result.getDeleteAccounts()).internalTransactions(result.getInternalTransactions());
        ContractDetails cdetails = track.getContractDetails(addr);
        if (cdetails != null) {
            summaryBuilder.storageDiff(cdetails.getStorage());
        }
        if (result.getException() != null) {
            summaryBuilder.markAsFailed();
        }
    }
    logger.trace("Building transaction execution summary");
    TransactionExecutionSummary summary = summaryBuilder.build();
    // Refund for gas leftover
    track.addBalance(tx.getSender(), summary.getLeftover().add(summary.getRefund()));
    logger.trace("Pay total refund to sender: [{}], refund val: [{}]", tx.getSender(), summary.getRefund());
    // Transfer fees to miner
    Coin summaryFee = summary.getFee();
    // TODO: REMOVE THIS WHEN THE LocalBLockTests starts working with REMASC
    if (config.isRemascEnabled()) {
        logger.trace("Adding fee to remasc contract account");
        track.addBalance(PrecompiledContracts.REMASC_ADDR, summaryFee);
    } else {
        track.addBalance(coinbase, summaryFee);
    }
    this.paidFees = summaryFee;
    if (result != null) {
        logger.trace("Processing result");
        logs = notRejectedLogInfos;
        result.getCodeChanges().forEach((key, value) -> track.saveCode(new RskAddress(key), value));
        // Traverse list of suicides
        result.getDeleteAccounts().forEach(address -> track.delete(new RskAddress(address)));
    }
    if (listener != null) {
        listener.onTransactionExecuted(summary);
    }
    logger.trace("tx listener done");
    if (config.vmTrace() && program != null && result != null) {
        ProgramTrace trace = program.getTrace().result(result.getHReturn()).error(result.getException());
        String txHash = tx.getHash().toHexString();
        try {
            saveProgramTraceFile(config, txHash, trace);
            if (listener != null) {
                listener.onVMTraceCreated(txHash, trace);
            }
        } catch (IOException e) {
            String errorMessage = String.format("Cannot write trace to file: %s", e.getMessage());
            panicProcessor.panic("executor", errorMessage);
            logger.error(errorMessage);
        }
    }
    logger.trace("tx finalization done");
}
Also used : Arrays(java.util.Arrays) LoggerFactory(org.slf4j.LoggerFactory) EMPTY_BYTE_ARRAY(org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY) RskAddress(co.rsk.core.RskAddress) EthereumListenerAdapter(org.ethereum.listener.EthereumListenerAdapter) Coin(co.rsk.core.Coin) ArrayUtils.isEmpty(org.apache.commons.lang3.ArrayUtils.isEmpty) ContractDetails(org.ethereum.db.ContractDetails) BlockchainConfig(org.ethereum.config.BlockchainConfig) BigInteger(java.math.BigInteger) VMUtils.saveProgramTraceFile(org.ethereum.vm.VMUtils.saveProgramTraceFile) ProgramInvoke(org.ethereum.vm.program.invoke.ProgramInvoke) PanicProcessor(co.rsk.panic.PanicProcessor) Logger(org.slf4j.Logger) IOException(java.io.IOException) BlockStore(org.ethereum.db.BlockStore) EthereumListener(org.ethereum.listener.EthereumListener) Collectors(java.util.stream.Collectors) BIUtil(org.ethereum.util.BIUtil) ArrayUtils.getLength(org.apache.commons.lang3.ArrayUtils.getLength) ReceiptStore(org.ethereum.db.ReceiptStore) Program(org.ethereum.vm.program.Program) ProgramTrace(org.ethereum.vm.trace.ProgramTrace) List(java.util.List) VmConfig(co.rsk.config.VmConfig) org.ethereum.vm(org.ethereum.vm) ProgramResult(org.ethereum.vm.program.ProgramResult) ProgramInvokeFactory(org.ethereum.vm.program.invoke.ProgramInvokeFactory) RskSystemProperties(co.rsk.config.RskSystemProperties) Constants(org.ethereum.config.Constants) Coin(co.rsk.core.Coin) ProgramTrace(org.ethereum.vm.trace.ProgramTrace) RskAddress(co.rsk.core.RskAddress) IOException(java.io.IOException) ContractDetails(org.ethereum.db.ContractDetails)

Example 14 with ContractDetails

use of org.ethereum.db.ContractDetails in project rskj by rsksmart.

the class ContractDetailsMapper method mapFromContract.

public ContractDetails mapFromContract(Contract contract) {
    ContractDetails contractDetails;
    contractDetails = new ContractDetailsImpl(config);
    if (contract.getCode() != null) {
        contractDetails.setCode(Hex.decode(contract.getCode()));
    }
    for (String key : contract.getData().keySet()) {
        String value = contract.getData().get(key);
        contractDetails.putBytes(new DataWord(Hex.decode(key)), Hex.decode(value));
    }
    return contractDetails;
}
Also used : ContractDetailsImpl(co.rsk.db.ContractDetailsImpl) DataWord(org.ethereum.vm.DataWord) ContractDetails(org.ethereum.db.ContractDetails)

Example 15 with ContractDetails

use of org.ethereum.db.ContractDetails in project rskj by rsksmart.

the class GenesisLoader method generatePreMine.

private static Map<RskAddress, InitialAddressState> generatePreMine(RskSystemProperties config, BigInteger initialNonce, Map<String, AllocatedAccount> alloc) {
    Map<RskAddress, InitialAddressState> premine = new HashMap<>();
    ContractDetailsMapper detailsMapper = new ContractDetailsMapper(config);
    for (Map.Entry<String, AllocatedAccount> accountEntry : alloc.entrySet()) {
        if (!StringUtils.equals("00", accountEntry.getKey())) {
            Coin balance = new Coin(new BigInteger(accountEntry.getValue().getBalance()));
            BigInteger nonce;
            if (accountEntry.getValue().getNonce() != null) {
                nonce = new BigInteger(accountEntry.getValue().getNonce());
            } else {
                nonce = initialNonce;
            }
            AccountState acctState = new AccountState(nonce, balance);
            ContractDetails contractDetails = null;
            Contract contract = accountEntry.getValue().getContract();
            if (contract != null) {
                contractDetails = detailsMapper.mapFromContract(contract);
                if (contractDetails.getCode() != null) {
                    acctState.setCodeHash(Keccak256Helper.keccak256(contractDetails.getCode()));
                }
                acctState.setStateRoot(contractDetails.getStorageHash());
            }
            premine.put(new RskAddress(accountEntry.getKey()), new InitialAddressState(acctState, contractDetails));
        }
    }
    return premine;
}
Also used : HashMap(java.util.HashMap) AccountState(org.ethereum.core.AccountState) ContractDetails(org.ethereum.db.ContractDetails) Coin(co.rsk.core.Coin) RskAddress(co.rsk.core.RskAddress) BigInteger(java.math.BigInteger) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

ContractDetails (org.ethereum.db.ContractDetails)24 Test (org.junit.Test)13 DataWord (org.ethereum.vm.DataWord)9 Repository (org.ethereum.core.Repository)8 RskAddress (co.rsk.core.RskAddress)7 AccountState (org.ethereum.core.AccountState)7 TrieStoreImpl (co.rsk.trie.TrieStoreImpl)6 HashMapDB (org.ethereum.datasource.HashMapDB)6 ProgramResult (org.ethereum.vm.program.ProgramResult)5 TestContract (co.rsk.util.TestContract)4 BigInteger (java.math.BigInteger)4 Block (org.ethereum.core.Block)4 CallTransaction (org.ethereum.core.CallTransaction)4 Coin (co.rsk.core.Coin)3 TrieStore (co.rsk.trie.TrieStore)3 HashMap (java.util.HashMap)3 RskSystemProperties (co.rsk.config.RskSystemProperties)2 VmConfig (co.rsk.config.VmConfig)2 RepositoryImpl (co.rsk.db.RepositoryImpl)2 ArrayList (java.util.ArrayList)2