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);
}
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());
}
}
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();
}
}
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);
}
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);
}
Aggregations