Search in sources :

Example 1 with ProgramSubtrace

use of co.rsk.rpc.modules.trace.ProgramSubtrace in project rskj by rsksmart.

the class RemascFeesPayer method transferPayment.

private void transferPayment(Coin value, RskAddress toAddress) {
    this.repository.addBalance(contractAddress, value.negate());
    this.repository.addBalance(toAddress, value);
    DataWord from = DataWord.valueOf(contractAddress.getBytes());
    DataWord to = DataWord.valueOf(toAddress.getBytes());
    long gas = 0L;
    DataWord amount = DataWord.valueOf(value.getBytes());
    TransferInvoke invoke = new TransferInvoke(from, to, gas, amount);
    ProgramResult result = new ProgramResult();
    ProgramSubtrace subtrace = ProgramSubtrace.newCallSubtrace(CallType.CALL, invoke, result, null, Collections.emptyList());
    this.subtraces.add(subtrace);
}
Also used : ProgramSubtrace(co.rsk.rpc.modules.trace.ProgramSubtrace) ProgramResult(org.ethereum.vm.program.ProgramResult) DataWord(org.ethereum.vm.DataWord) TransferInvoke(org.ethereum.vm.program.invoke.TransferInvoke)

Example 2 with ProgramSubtrace

use of co.rsk.rpc.modules.trace.ProgramSubtrace in project rskj by rsksmart.

the class TransactionExecutor method extractTrace.

/**
 * This extracts the trace to an object in memory.
 * Refer to {@link org.ethereum.vm.VMUtils#saveProgramTraceFile} for a way to saving the trace to a file.
 */
public void extractTrace(ProgramTraceProcessor programTraceProcessor) {
    if (program != null) {
        // TODO improve this settings; the trace should already have the values
        ProgramTrace trace = program.getTrace().result(result.getHReturn()).error(result.getException()).revert(result.isRevert());
        programTraceProcessor.processProgramTrace(trace, tx.getHash());
    } else {
        TransferInvoke invoke = new TransferInvoke(DataWord.valueOf(tx.getSender().getBytes()), DataWord.valueOf(tx.getReceiveAddress().getBytes()), 0L, DataWord.valueOf(tx.getValue().getBytes()));
        SummarizedProgramTrace trace = new SummarizedProgramTrace(invoke);
        if (this.subtraces != null) {
            for (ProgramSubtrace subtrace : this.subtraces) {
                trace.addSubTrace(subtrace);
            }
        }
        programTraceProcessor.processProgramTrace(trace, tx.getHash());
    }
}
Also used : SummarizedProgramTrace(org.ethereum.vm.trace.SummarizedProgramTrace) ProgramTrace(org.ethereum.vm.trace.ProgramTrace) ProgramSubtrace(co.rsk.rpc.modules.trace.ProgramSubtrace) TransferInvoke(org.ethereum.vm.program.invoke.TransferInvoke) SummarizedProgramTrace(org.ethereum.vm.trace.SummarizedProgramTrace)

Example 3 with ProgramSubtrace

use of co.rsk.rpc.modules.trace.ProgramSubtrace in project rskj by rsksmart.

the class Program method callToAddress.

/**
 * That method is for internal code invocations
 * <p/>
 * - Normal calls invoke a specified contract which updates itself
 * - Stateless calls invoke code from another contract, within the context of the caller
 *
 * @param msg         is the message call object
 */
public void callToAddress(MessageCall msg) {
    if (getCallDeep() == getMaxDepth()) {
        stackPushZero();
        refundGas(msg.getGas().longValue(), " call deep limit reach");
        return;
    }
    byte[] data = memoryChunk(msg.getInDataOffs().intValue(), msg.getInDataSize().intValue());
    // FETCH THE SAVED STORAGE
    RskAddress codeAddress = new RskAddress(msg.getCodeAddress());
    RskAddress senderAddress = getOwnerRskAddress();
    RskAddress contextAddress = msg.getType().isStateless() ? senderAddress : codeAddress;
    if (isLogEnabled) {
        logger.info("{} for existing contract: address: [{}], outDataOffs: [{}], outDataSize: [{}]  ", msg.getType().name(), contextAddress, msg.getOutDataOffs().longValue(), msg.getOutDataSize().longValue());
    }
    Repository track = getStorage().startTracking();
    // 2.1 PERFORM THE VALUE (endowment) PART
    Coin endowment = new Coin(msg.getEndowment().getData());
    Coin senderBalance = track.getBalance(senderAddress);
    if (isNotCovers(senderBalance, endowment)) {
        stackPushZero();
        refundGas(msg.getGas().longValue(), "refund gas from message call");
        this.cleanReturnDataBuffer();
        return;
    }
    // FETCH THE CODE
    byte[] programCode = getStorage().isExist(codeAddress) ? getStorage().getCode(codeAddress) : EMPTY_BYTE_ARRAY;
    // programCode  can be null
    // Always first remove funds from sender
    track.addBalance(senderAddress, endowment.negate());
    Coin contextBalance;
    if (byTestingSuite()) {
        // This keeps track of the calls created for a test
        getResult().addCallCreate(data, contextAddress.getBytes(), msg.getGas().longValueSafe(), msg.getEndowment().getNoLeadZeroesData());
        return;
    }
    contextBalance = track.addBalance(contextAddress, endowment);
    // CREATE CALL INTERNAL TRANSACTION
    InternalTransaction internalTx = addInternalTx(null, getGasLimit(), senderAddress, contextAddress, endowment, programCode, "call");
    boolean callResult;
    if (!isEmpty(programCode)) {
        callResult = executeCode(msg, contextAddress, contextBalance, internalTx, track, programCode, senderAddress, data);
    } else {
        track.commit();
        callResult = true;
        refundGas(GasCost.toGas(msg.getGas().longValue()), "remaining gas from the internal call");
        DataWord callerAddress = DataWord.valueOf(senderAddress.getBytes());
        DataWord ownerAddress = DataWord.valueOf(contextAddress.getBytes());
        DataWord transferValue = DataWord.valueOf(endowment.getBytes());
        TransferInvoke invoke = new TransferInvoke(callerAddress, ownerAddress, msg.getGas().longValue(), transferValue);
        ProgramResult result = new ProgramResult();
        ProgramSubtrace subtrace = ProgramSubtrace.newCallSubtrace(CallType.fromMsgType(msg.getType()), invoke, result, null, Collections.emptyList());
        getTrace().addSubTrace(subtrace);
        this.cleanReturnDataBuffer();
    }
    // 4. THE FLAG OF SUCCESS IS ONE PUSHED INTO THE STACK
    if (callResult) {
        stackPushOne();
    } else {
        stackPushZero();
    }
}
Also used : Coin(co.rsk.core.Coin) Repository(org.ethereum.core.Repository) ProgramSubtrace(co.rsk.rpc.modules.trace.ProgramSubtrace) RskAddress(co.rsk.core.RskAddress)

Example 4 with ProgramSubtrace

use of co.rsk.rpc.modules.trace.ProgramSubtrace in project rskj by rsksmart.

the class Program method suicide.

public void suicide(DataWord obtainerAddress) {
    RskAddress owner = getOwnerRskAddress();
    Coin balance = getStorage().getBalance(owner);
    RskAddress obtainer = new RskAddress(obtainerAddress);
    if (!balance.equals(Coin.ZERO)) {
        logger.info("Transfer to: [{}] heritage: [{}]", obtainer, balance);
        addInternalTx(null, null, owner, obtainer, balance, null, "suicide");
        if (FastByteComparisons.compareTo(owner.getBytes(), 0, 20, obtainer.getBytes(), 0, 20) == 0) {
            // if owner == obtainer just zeroing account according to Yellow Paper
            getStorage().addBalance(owner, balance.negate());
        } else {
            getStorage().transfer(owner, obtainer, balance);
        }
    }
    // In any case, remove the account
    getResult().addDeleteAccount(this.getOwnerAddress());
    SuicideInvoke invoke = new SuicideInvoke(DataWord.valueOf(owner.getBytes()), obtainerAddress, DataWord.valueOf(balance.getBytes()));
    ProgramSubtrace subtrace = ProgramSubtrace.newSuicideSubtrace(invoke);
    getTrace().addSubTrace(subtrace);
}
Also used : Coin(co.rsk.core.Coin) ProgramSubtrace(co.rsk.rpc.modules.trace.ProgramSubtrace) RskAddress(co.rsk.core.RskAddress)

Example 5 with ProgramSubtrace

use of co.rsk.rpc.modules.trace.ProgramSubtrace in project rskj by rsksmart.

the class BridgeSupport method transferTo.

/**
 * Internal method to transfer RSK to an RSK account
 * It also produce the appropiate internal transaction subtrace if needed
 *
 * @param receiver  address that receives the amount
 * @param amount    amount to transfer
 */
private void transferTo(RskAddress receiver, co.rsk.core.Coin amount) {
    rskRepository.transfer(PrecompiledContracts.BRIDGE_ADDR, receiver, amount);
    DataWord from = DataWord.valueOf(PrecompiledContracts.BRIDGE_ADDR.getBytes());
    DataWord to = DataWord.valueOf(receiver.getBytes());
    long gas = 0L;
    DataWord value = DataWord.valueOf(amount.getBytes());
    TransferInvoke invoke = new TransferInvoke(from, to, gas, value);
    ProgramResult result = ProgramResult.empty();
    ProgramSubtrace subtrace = ProgramSubtrace.newCallSubtrace(CallType.CALL, invoke, result, null, Collections.emptyList());
    logger.info("Transferred {} weis to {}", amount, receiver);
    this.subtraces.add(subtrace);
}
Also used : ProgramSubtrace(co.rsk.rpc.modules.trace.ProgramSubtrace) ProgramResult(org.ethereum.vm.program.ProgramResult) DataWord(org.ethereum.vm.DataWord) TransferInvoke(org.ethereum.vm.program.invoke.TransferInvoke)

Aggregations

ProgramSubtrace (co.rsk.rpc.modules.trace.ProgramSubtrace)6 Coin (co.rsk.core.Coin)3 RskAddress (co.rsk.core.RskAddress)3 TransferInvoke (org.ethereum.vm.program.invoke.TransferInvoke)3 Repository (org.ethereum.core.Repository)2 DataWord (org.ethereum.vm.DataWord)2 ProgramResult (org.ethereum.vm.program.ProgramResult)2 ArrayList (java.util.ArrayList)1 RLPElement (org.ethereum.util.RLPElement)1 RLPList (org.ethereum.util.RLPList)1 LogInfo (org.ethereum.vm.LogInfo)1 ProgramTrace (org.ethereum.vm.trace.ProgramTrace)1 SummarizedProgramTrace (org.ethereum.vm.trace.SummarizedProgramTrace)1 Test (org.junit.Test)1