use of co.rsk.remasc.RemascContract in project rskj by rsksmart.
the class Program method callToPrecompiledAddress.
public void callToPrecompiledAddress(MessageCall msg, PrecompiledContract contract) {
if (getCallDeep() == MAX_DEPTH) {
stackPushZero();
this.refundGas(msg.getGas().longValue(), " call deep limit reach");
return;
}
Repository track = getStorage().startTracking();
RskAddress senderAddress = new RskAddress(getOwnerAddress());
RskAddress codeAddress = new RskAddress(msg.getCodeAddress());
RskAddress contextAddress = msg.getType().isStateless() ? senderAddress : codeAddress;
Coin endowment = new Coin(msg.getEndowment().getData());
Coin senderBalance = track.getBalance(senderAddress);
if (senderBalance.compareTo(endowment) < 0) {
stackPushZero();
this.refundGas(msg.getGas().longValue(), "refund gas from message call");
return;
}
byte[] data = this.memoryChunk(msg.getInDataOffs().intValue(), msg.getInDataSize().intValue());
// Charge for endowment - is not reversible by rollback
track.transfer(senderAddress, contextAddress, new Coin(msg.getEndowment().getData()));
if (byTestingSuite()) {
// This keeps track of the calls created for a test
this.getResult().addCallCreate(data, codeAddress.getBytes(), msg.getGas().longValueSafe(), msg.getEndowment().getNoLeadZeroesData());
stackPushOne();
return;
}
long requiredGas = contract.getGasForData(data);
if (requiredGas > msg.getGas().longValue()) {
// matches cpp logic
this.refundGas(0, "call pre-compiled");
this.stackPushZero();
track.rollback();
} else {
this.refundGas(msg.getGas().longValue() - requiredGas, "call pre-compiled");
if (contract instanceof Bridge || contract instanceof RemascContract) {
// CREATE CALL INTERNAL TRANSACTION
InternalTransaction internalTx = addInternalTx(null, getGasLimit(), senderAddress, contextAddress, endowment, EMPTY_BYTE_ARRAY, "call");
Block executionBlock = new Block(getPrevHash().getData(), EMPTY_BYTE_ARRAY, getCoinbase().getData(), EMPTY_BYTE_ARRAY, getDifficulty().getData(), getNumber().longValue(), getGasLimit().getData(), 0, getTimestamp().longValue(), EMPTY_BYTE_ARRAY, EMPTY_BYTE_ARRAY, EMPTY_BYTE_ARRAY, new ArrayList<>(), new ArrayList<>(), null);
contract.init(internalTx, executionBlock, track, this.invoke.getBlockStore(), null, null);
}
byte[] out = contract.execute(data);
this.memorySave(msg.getOutDataOffs().intValue(), out);
this.stackPushOne();
track.commit();
}
}
Aggregations