github.com/MetalBlockchain/subnet-evm@v0.4.9/plugin/evm/message/cross_chain_handler.go (about)

     1  // (c) 2021-2022, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package message
     5  
     6  import (
     7  	"context"
     8  	"encoding/json"
     9  
    10  	"github.com/MetalBlockchain/metalgo/codec"
    11  	"github.com/MetalBlockchain/metalgo/ids"
    12  
    13  	"github.com/MetalBlockchain/subnet-evm/internal/ethapi"
    14  	"github.com/MetalBlockchain/subnet-evm/rpc"
    15  
    16  	"github.com/ethereum/go-ethereum/log"
    17  )
    18  
    19  var _ CrossChainRequestHandler = &crossChainHandler{}
    20  
    21  // crossChainHandler implements the CrossChainRequestHandler interface
    22  type crossChainHandler struct {
    23  	backend         ethapi.Backend
    24  	crossChainCodec codec.Manager
    25  }
    26  
    27  // NewCrossChainHandler creates and returns a new instance of CrossChainRequestHandler
    28  func NewCrossChainHandler(b ethapi.Backend, codec codec.Manager) CrossChainRequestHandler {
    29  	return &crossChainHandler{
    30  		backend:         b,
    31  		crossChainCodec: codec,
    32  	}
    33  }
    34  
    35  // HandleEthCallRequests returns an encoded EthCallResponse to the given [ethCallRequest]
    36  // This function executes EVM Call against the state associated with [rpc.AcceptedBlockNumber] with the given
    37  // transaction call object [ethCallRequest].
    38  // This function does not return an error as errors are treated as FATAL to the node.
    39  func (c *crossChainHandler) HandleEthCallRequest(ctx context.Context, requestingChainID ids.ID, requestID uint32, ethCallRequest EthCallRequest) ([]byte, error) {
    40  	lastAcceptedBlockNumber := rpc.BlockNumber(c.backend.LastAcceptedBlock().NumberU64())
    41  	lastAcceptedBlockNumberOrHash := rpc.BlockNumberOrHash{BlockNumber: &lastAcceptedBlockNumber}
    42  
    43  	transactionArgs := ethapi.TransactionArgs{}
    44  	err := json.Unmarshal(ethCallRequest.RequestArgs, &transactionArgs)
    45  	if err != nil {
    46  		log.Debug("error occurred with JSON unmarshalling ethCallRequest.RequestArgs", "err", err)
    47  		return nil, nil
    48  	}
    49  
    50  	result, err := ethapi.DoCall(ctx, c.backend, transactionArgs, lastAcceptedBlockNumberOrHash, nil, c.backend.RPCEVMTimeout(), c.backend.RPCGasCap())
    51  	if err != nil {
    52  		log.Debug("error occurred with EthCall", "err", err, "transactionArgs", ethCallRequest.RequestArgs, "blockNumberOrHash", lastAcceptedBlockNumberOrHash)
    53  		return nil, nil
    54  	}
    55  
    56  	executionResult, err := json.Marshal(&result)
    57  	if err != nil {
    58  		log.Debug("error occurred with JSON marshalling result", "err", err)
    59  		return nil, nil
    60  	}
    61  
    62  	response := EthCallResponse{
    63  		ExecutionResult: executionResult,
    64  	}
    65  
    66  	responseBytes, err := c.crossChainCodec.Marshal(Version, response)
    67  	if err != nil {
    68  		log.Warn("error occurred with marshalling EthCallResponse", "err", err, "EthCallResponse", response)
    69  		return nil, nil
    70  	}
    71  
    72  	return responseBytes, nil
    73  }