Search in sources :

Example 1 with RemascContract

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();
    }
}
Also used : Coin(co.rsk.core.Coin) Repository(org.ethereum.core.Repository) RemascContract(co.rsk.remasc.RemascContract) RskAddress(co.rsk.core.RskAddress) Block(org.ethereum.core.Block) Bridge(co.rsk.peg.Bridge)

Aggregations

Coin (co.rsk.core.Coin)1 RskAddress (co.rsk.core.RskAddress)1 Bridge (co.rsk.peg.Bridge)1 RemascContract (co.rsk.remasc.RemascContract)1 Block (org.ethereum.core.Block)1 Repository (org.ethereum.core.Repository)1