Update eth_call code.
This commit is contained in:
parent
0f2b6fd843
commit
cc6822f7a6
202
pkg/eth/api.go
202
pkg/eth/api.go
@ -27,10 +27,12 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/common/math"
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth/filters"
|
"github.com/ethereum/go-ethereum/eth/filters"
|
||||||
@ -819,50 +821,59 @@ func (pea *PublicEthAPI) localGetProof(ctx context.Context, address common.Addre
|
|||||||
}, state.Error()
|
}, state.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call executes the given transaction on the state for the given block number.
|
// revertError is an API error that encompassas an EVM revertal with JSON error
|
||||||
//
|
// code and a binary data blob.
|
||||||
// Additionally, the caller can specify a batch of contract for fields overriding.
|
type revertError struct {
|
||||||
//
|
error
|
||||||
// Note, this function doesn't make and changes in the state/blockchain and is
|
reason string // revert reason hex encoded
|
||||||
// useful to execute and retrieve values.
|
|
||||||
func (pea *PublicEthAPI) Call(ctx context.Context, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *map[common.Address]account) (hexutil.Bytes, error) {
|
|
||||||
var accounts map[common.Address]account
|
|
||||||
if overrides != nil {
|
|
||||||
accounts = *overrides
|
|
||||||
}
|
|
||||||
res, _, failed, err := DoCall(ctx, pea.B, args, blockNrOrHash, accounts, 5*time.Second, pea.B.Config.RPCGasCap)
|
|
||||||
if (failed || err != nil) && pea.rpc != nil {
|
|
||||||
var hex hexutil.Bytes
|
|
||||||
if err := pea.rpc.CallContext(ctx, &hex, "eth_call", args, blockNrOrHash, overrides); hex != nil && err == nil {
|
|
||||||
go pea.writeStateDiffAtOrFor(blockNrOrHash)
|
|
||||||
return hex, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if failed && err == nil {
|
|
||||||
return nil, errors.New("eth_call failed without error")
|
|
||||||
}
|
|
||||||
return (hexutil.Bytes)(res), err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func DoCall(ctx context.Context, b *Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides map[common.Address]account, timeout time.Duration, globalGasCap *big.Int) ([]byte, uint64, bool, error) {
|
// ErrorCode returns the JSON error code for a revertal.
|
||||||
defer func(start time.Time) {
|
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
|
||||||
logrus.Debugf("Executing EVM call finished %s runtime %s", time.Now().String(), time.Since(start).String())
|
func (e *revertError) ErrorCode() int {
|
||||||
}(time.Now())
|
return 3
|
||||||
state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
|
||||||
if state == nil || err != nil {
|
|
||||||
return nil, 0, false, err
|
|
||||||
}
|
}
|
||||||
// Set sender address or use a default if none specified
|
|
||||||
var addr common.Address
|
// ErrorData returns the hex encoded revert reason.
|
||||||
if args.From == nil {
|
func (e *revertError) ErrorData() interface{} {
|
||||||
if b.Config.DefaultSender != nil {
|
return e.reason
|
||||||
addr = *b.Config.DefaultSender
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
addr = *args.From
|
func newRevertError(result *core.ExecutionResult) *revertError {
|
||||||
|
reason, errUnpack := abi.UnpackRevert(result.Revert())
|
||||||
|
err := errors.New("execution reverted")
|
||||||
|
if errUnpack == nil {
|
||||||
|
err = fmt.Errorf("execution reverted: %v", reason)
|
||||||
}
|
}
|
||||||
// Override the fields of specified contracts before execution.
|
return &revertError{
|
||||||
for addr, account := range overrides {
|
error: err,
|
||||||
|
reason: hexutil.Encode(result.Revert()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OverrideAccount indicates the overriding fields of account during the execution
|
||||||
|
// of a message call.
|
||||||
|
// Note, state and stateDiff can't be specified at the same time. If state is
|
||||||
|
// set, message execution will only use the data in the given state. Otherwise
|
||||||
|
// if statDiff is set, all diff will be applied first and then execute the call
|
||||||
|
// message.
|
||||||
|
type OverrideAccount struct {
|
||||||
|
Nonce *hexutil.Uint64 `json:"nonce"`
|
||||||
|
Code *hexutil.Bytes `json:"code"`
|
||||||
|
Balance **hexutil.Big `json:"balance"`
|
||||||
|
State *map[common.Hash]common.Hash `json:"state"`
|
||||||
|
StateDiff *map[common.Hash]common.Hash `json:"stateDiff"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// StateOverride is the collection of overridden accounts.
|
||||||
|
type StateOverride map[common.Address]OverrideAccount
|
||||||
|
|
||||||
|
// Apply overrides the fields of specified accounts into the given state.
|
||||||
|
func (diff *StateOverride) Apply(state *state.StateDB) error {
|
||||||
|
if diff == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for addr, account := range *diff {
|
||||||
// Override account nonce.
|
// Override account nonce.
|
||||||
if account.Nonce != nil {
|
if account.Nonce != nil {
|
||||||
state.SetNonce(addr, uint64(*account.Nonce))
|
state.SetNonce(addr, uint64(*account.Nonce))
|
||||||
@ -876,7 +887,7 @@ func DoCall(ctx context.Context, b *Backend, args CallArgs, blockNrOrHash rpc.Bl
|
|||||||
state.SetBalance(addr, (*big.Int)(*account.Balance))
|
state.SetBalance(addr, (*big.Int)(*account.Balance))
|
||||||
}
|
}
|
||||||
if account.State != nil && account.StateDiff != nil {
|
if account.State != nil && account.StateDiff != nil {
|
||||||
return nil, 0, false, fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex())
|
return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex())
|
||||||
}
|
}
|
||||||
// Replace entire state if caller requires.
|
// Replace entire state if caller requires.
|
||||||
if account.State != nil {
|
if account.State != nil {
|
||||||
@ -889,74 +900,48 @@ func DoCall(ctx context.Context, b *Backend, args CallArgs, blockNrOrHash rpc.Bl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set default gas & gas price if none were set
|
return nil
|
||||||
gas := uint64(math.MaxUint64 / 2)
|
|
||||||
if args.Gas != nil {
|
|
||||||
gas = uint64(*args.Gas)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if globalGasCap != nil && globalGasCap.Uint64() < gas {
|
// Call executes the given transaction on the state for the given block number.
|
||||||
logrus.Warnf("Caller gas above allowance, capping; requested: %d, cap: %d", gas, globalGasCap)
|
//
|
||||||
gas = globalGasCap.Uint64()
|
// Additionally, the caller can specify a batch of contract for fields overriding.
|
||||||
|
//
|
||||||
|
// Note, this function doesn't make and changes in the state/blockchain and is
|
||||||
|
// useful to execute and retrieve values.
|
||||||
|
func (pea *PublicEthAPI) Call(ctx context.Context, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Bytes, error) {
|
||||||
|
result, err := DoCall(ctx, pea.B, args, blockNrOrHash, overrides, 5*time.Second, pea.B.Config.RPCGasCap.Uint64())
|
||||||
|
|
||||||
|
// If the result contains a revert reason, try to unpack and return it.
|
||||||
|
if err == nil && len(result.Revert()) > 0 {
|
||||||
|
// Doubt: Should we return this? This might indicate failure in VM.
|
||||||
|
err = newRevertError(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
if err != nil && pea.rpc != nil {
|
||||||
gasPrice *big.Int
|
var hex hexutil.Bytes
|
||||||
gasFeeCap *big.Int
|
if err := pea.rpc.CallContext(ctx, &hex, "eth_call", args, blockNrOrHash, overrides); hex != nil && err == nil {
|
||||||
gasTipCap *big.Int
|
go pea.writeStateDiffAtOrFor(blockNrOrHash)
|
||||||
)
|
return hex, nil
|
||||||
|
|
||||||
if header.BaseFee == nil {
|
|
||||||
// If there's no basefee, then it must be a non-1559 execution
|
|
||||||
gasPrice = new(big.Int)
|
|
||||||
if args.GasPrice != nil {
|
|
||||||
gasPrice = args.GasPrice.ToInt()
|
|
||||||
}
|
|
||||||
gasFeeCap, gasTipCap = gasPrice, gasPrice
|
|
||||||
} else {
|
|
||||||
// A basefee is provided, necessitating 1559-type execution
|
|
||||||
if args.GasPrice != nil {
|
|
||||||
// User specified the legacy gas field, convert to 1559 gas typing
|
|
||||||
gasPrice = args.GasPrice.ToInt()
|
|
||||||
gasFeeCap, gasTipCap = gasPrice, gasPrice
|
|
||||||
} else {
|
|
||||||
// User specified 1559 gas feilds (or none), use those
|
|
||||||
gasFeeCap = new(big.Int)
|
|
||||||
if args.MaxFeePerGas != nil {
|
|
||||||
gasFeeCap = args.MaxFeePerGas.ToInt()
|
|
||||||
}
|
|
||||||
gasTipCap = new(big.Int)
|
|
||||||
if args.MaxPriorityFeePerGas != nil {
|
|
||||||
gasTipCap = args.MaxPriorityFeePerGas.ToInt()
|
|
||||||
}
|
|
||||||
// Backfill the legacy gasPrice for EVM execution, unless we're all zeroes
|
|
||||||
gasPrice = new(big.Int)
|
|
||||||
if gasFeeCap.BitLen() > 0 || gasTipCap.BitLen() > 0 {
|
|
||||||
gasPrice = math.BigMin(new(big.Int).Add(gasTipCap, header.BaseFee), gasFeeCap)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result.Return(), result.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
value := new(big.Int)
|
func DoCall(ctx context.Context, b *Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
|
||||||
if args.Value != nil {
|
defer func(start time.Time) {
|
||||||
value = args.Value.ToInt()
|
logrus.Debugf("Executing EVM call finished %s runtime %s", time.Now().String(), time.Since(start).String())
|
||||||
|
}(time.Now())
|
||||||
|
|
||||||
|
state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
||||||
|
if state == nil || err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var data []byte
|
if err := overrides.Apply(state); err != nil {
|
||||||
if args.Input != nil {
|
return nil, err
|
||||||
data = *args.Input
|
|
||||||
} else if args.Data != nil {
|
|
||||||
data = *args.Data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var accessList types.AccessList
|
|
||||||
if args.AccessList != nil {
|
|
||||||
accessList = *args.AccessList
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new call message
|
|
||||||
msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, false)
|
|
||||||
|
|
||||||
// Setup context so it may be cancelled the call has completed
|
// Setup context so it may be cancelled the call has completed
|
||||||
// or, in case of unmetered gas, setup a context with a timeout.
|
// or, in case of unmetered gas, setup a context with a timeout.
|
||||||
var cancel context.CancelFunc
|
var cancel context.CancelFunc
|
||||||
@ -970,10 +955,16 @@ func DoCall(ctx context.Context, b *Backend, args CallArgs, blockNrOrHash rpc.Bl
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// Get a new instance of the EVM.
|
// Get a new instance of the EVM.
|
||||||
evm, err := b.GetEVM(ctx, msg, state, header)
|
msg, err := args.ToMessage(globalGasCap, header.BaseFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, false, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
evm, vmError, err := b.GetEVM(ctx, msg, state, header)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for the context to be done and cancel the evm. Even if the
|
// Wait for the context to be done and cancel the evm. Even if the
|
||||||
// EVM has finished, cancelling may be done (repeatedly)
|
// EVM has finished, cancelling may be done (repeatedly)
|
||||||
go func() {
|
go func() {
|
||||||
@ -981,18 +972,21 @@ func DoCall(ctx context.Context, b *Backend, args CallArgs, blockNrOrHash rpc.Bl
|
|||||||
evm.Cancel()
|
evm.Cancel()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Setup the gas pool (also for unmetered requests)
|
// Execute the message.
|
||||||
// and apply the message.
|
|
||||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
result, err := core.ApplyMessage(evm, msg, gp)
|
result, err := core.ApplyMessage(evm, msg, gp)
|
||||||
if err != nil {
|
if err := vmError(); err != nil {
|
||||||
return nil, 0, false, fmt.Errorf("execution failed: %v", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the timer caused an abort, return an appropriate error message
|
// If the timer caused an abort, return an appropriate error message
|
||||||
if evm.Cancelled() {
|
if evm.Cancelled() {
|
||||||
return nil, 0, false, fmt.Errorf("execution aborted (timeout = %v)", timeout)
|
return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout)
|
||||||
}
|
}
|
||||||
return result.Return(), result.UsedGas, result.Failed(), err
|
if err != nil {
|
||||||
|
return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas())
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeStateDiffAtOrFor calls out to the proxy statediffing geth client to fill in a gap in the index
|
// writeStateDiffAtOrFor calls out to the proxy statediffing geth client to fill in a gap in the index
|
||||||
|
@ -26,7 +26,6 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/common/math"
|
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
@ -620,11 +619,11 @@ func (b *Backend) GetCanonicalHeader(number uint64) (string, []byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetEVM constructs and returns a vm.EVM
|
// GetEVM constructs and returns a vm.EVM
|
||||||
func (b *Backend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, error) {
|
func (b *Backend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
|
||||||
state.SetBalance(msg.From(), math.MaxBig256)
|
vmError := func() error { return nil }
|
||||||
vmctx := core.NewEVMBlockContext(header, b, nil)
|
|
||||||
txContext := core.NewEVMTxContext(msg)
|
txContext := core.NewEVMTxContext(msg)
|
||||||
return vm.NewEVM(vmctx, txContext, state, b.Config.ChainConfig, b.Config.VMConfig), nil
|
context := core.NewEVMBlockContext(header, b, nil)
|
||||||
|
return vm.NewEVM(context, txContext, state, b.Config.ChainConfig, b.Config.VMConfig), vmError, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccountByNumberOrHash returns the account object for the provided address at the block corresponding to the provided number or hash
|
// GetAccountByNumberOrHash returns the account object for the provided address at the block corresponding to the provided number or hash
|
||||||
|
103
pkg/eth/types.go
103
pkg/eth/types.go
@ -17,14 +17,17 @@
|
|||||||
package eth
|
package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/statediff/indexer/ipfs"
|
"github.com/ethereum/go-ethereum/statediff/indexer/ipfs"
|
||||||
"github.com/ethereum/go-ethereum/statediff/indexer/models"
|
"github.com/ethereum/go-ethereum/statediff/indexer/models"
|
||||||
sdtypes "github.com/ethereum/go-ethereum/statediff/types"
|
sdtypes "github.com/ethereum/go-ethereum/statediff/types"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
|
// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
|
||||||
@ -99,18 +102,94 @@ type CallArgs struct {
|
|||||||
Input *hexutil.Bytes `json:"input"`
|
Input *hexutil.Bytes `json:"input"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// account indicates the overriding fields of account during the execution of
|
// from retrieves the transaction sender address.
|
||||||
// a message call.
|
func (arg *CallArgs) from() common.Address {
|
||||||
// Note, state and stateDiff can't be specified at the same time. If state is
|
if arg.From == nil {
|
||||||
// set, message execution will only use the data in the given state. Otherwise
|
return common.Address{}
|
||||||
// if statDiff is set, all diff will be applied first and then execute the call
|
}
|
||||||
// message.
|
return *arg.From
|
||||||
type account struct {
|
}
|
||||||
Nonce *hexutil.Uint64 `json:"nonce"`
|
|
||||||
Code *hexutil.Bytes `json:"code"`
|
// data retrieves the transaction calldata. Input field is preferred.
|
||||||
Balance **hexutil.Big `json:"balance"`
|
func (arg *CallArgs) data() []byte {
|
||||||
State *map[common.Hash]common.Hash `json:"state"`
|
if arg.Input != nil {
|
||||||
StateDiff *map[common.Hash]common.Hash `json:"stateDiff"`
|
return *arg.Input
|
||||||
|
}
|
||||||
|
if arg.Data != nil {
|
||||||
|
return *arg.Data
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToMessage converts the transaction arguments to the Message type used by the
|
||||||
|
// core evm. This method is used in calls and traces that do not require a real
|
||||||
|
// live transaction.
|
||||||
|
func (arg *CallArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (types.Message, error) {
|
||||||
|
// Reject invalid combinations of pre- and post-1559 fee styles
|
||||||
|
if arg.GasPrice != nil && (arg.MaxFeePerGas != nil || arg.MaxPriorityFeePerGas != nil) {
|
||||||
|
return types.Message{}, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||||
|
}
|
||||||
|
// Set sender address or use zero address if none specified.
|
||||||
|
addr := arg.from()
|
||||||
|
|
||||||
|
// Set default gas & gas price if none were set
|
||||||
|
gas := globalGasCap
|
||||||
|
if gas == 0 {
|
||||||
|
gas = uint64(math.MaxUint64 / 2)
|
||||||
|
}
|
||||||
|
if arg.Gas != nil {
|
||||||
|
gas = uint64(*arg.Gas)
|
||||||
|
}
|
||||||
|
if globalGasCap != 0 && globalGasCap < gas {
|
||||||
|
logrus.Warn("Caller gas above allowance, capping", "requested", gas, "cap", globalGasCap)
|
||||||
|
gas = globalGasCap
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
gasPrice *big.Int
|
||||||
|
gasFeeCap *big.Int
|
||||||
|
gasTipCap *big.Int
|
||||||
|
)
|
||||||
|
if baseFee == nil {
|
||||||
|
// If there's no basefee, then it must be a non-1559 execution
|
||||||
|
gasPrice = new(big.Int)
|
||||||
|
if arg.GasPrice != nil {
|
||||||
|
gasPrice = arg.GasPrice.ToInt()
|
||||||
|
}
|
||||||
|
gasFeeCap, gasTipCap = gasPrice, gasPrice
|
||||||
|
} else {
|
||||||
|
// A basefee is provided, necessitating 1559-type execution
|
||||||
|
if arg.GasPrice != nil {
|
||||||
|
// User specified the legacy gas field, convert to 1559 gas typing
|
||||||
|
gasPrice = arg.GasPrice.ToInt()
|
||||||
|
gasFeeCap, gasTipCap = gasPrice, gasPrice
|
||||||
|
} else {
|
||||||
|
// User specified 1559 gas feilds (or none), use those
|
||||||
|
gasFeeCap = new(big.Int)
|
||||||
|
if arg.MaxFeePerGas != nil {
|
||||||
|
gasFeeCap = arg.MaxFeePerGas.ToInt()
|
||||||
|
}
|
||||||
|
gasTipCap = new(big.Int)
|
||||||
|
if arg.MaxPriorityFeePerGas != nil {
|
||||||
|
gasTipCap = arg.MaxPriorityFeePerGas.ToInt()
|
||||||
|
}
|
||||||
|
// Backfill the legacy gasPrice for EVM execution, unless we're all zeroes
|
||||||
|
gasPrice = new(big.Int)
|
||||||
|
if gasFeeCap.BitLen() > 0 || gasTipCap.BitLen() > 0 {
|
||||||
|
gasPrice = math.BigMin(new(big.Int).Add(gasTipCap, baseFee), gasFeeCap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value := new(big.Int)
|
||||||
|
if arg.Value != nil {
|
||||||
|
value = arg.Value.ToInt()
|
||||||
|
}
|
||||||
|
data := arg.data()
|
||||||
|
var accessList types.AccessList
|
||||||
|
if arg.AccessList != nil {
|
||||||
|
accessList = *arg.AccessList
|
||||||
|
}
|
||||||
|
msg := types.NewMessage(addr, arg.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, true)
|
||||||
|
return msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPLDs is used to package raw IPLD block data fetched from IPFS and returned by the server
|
// IPLDs is used to package raw IPLD block data fetched from IPFS and returned by the server
|
||||||
|
@ -835,16 +835,20 @@ func (b *Block) Call(ctx context.Context, args struct {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result, gas, failed, err := eth.DoCall(ctx, b.backend, args.Data, *b.numberOrHash, nil, 5*time.Second, b.backend.RPCGasCap())
|
result, err := eth.DoCall(ctx, b.backend, args.Data, *b.numberOrHash, nil, 5*time.Second, b.backend.RPCGasCap().Uint64())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
status := hexutil.Uint64(1)
|
status := hexutil.Uint64(1)
|
||||||
if failed {
|
if result.Failed() {
|
||||||
status = 0
|
status = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return &CallResult{
|
return &CallResult{
|
||||||
data: hexutil.Bytes(result),
|
data: result.ReturnData,
|
||||||
gasUsed: hexutil.Uint64(gas),
|
gasUsed: hexutil.Uint64(result.UsedGas),
|
||||||
status: status,
|
status: status,
|
||||||
}, err
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolver is the top-level object in the GraphQL hierarchy.
|
// Resolver is the top-level object in the GraphQL hierarchy.
|
||||||
|
@ -100,7 +100,7 @@ func NewServer(settings *Config) (Server, error) {
|
|||||||
var err error
|
var err error
|
||||||
sap.backend, err = eth.NewEthBackend(sap.db, ð.Config{
|
sap.backend, err = eth.NewEthBackend(sap.db, ð.Config{
|
||||||
ChainConfig: settings.ChainConfig,
|
ChainConfig: settings.ChainConfig,
|
||||||
VMConfig: vm.Config{},
|
VMConfig: vm.Config{NoBaseFee: true},
|
||||||
DefaultSender: settings.DefaultSender,
|
DefaultSender: settings.DefaultSender,
|
||||||
RPCGasCap: settings.RPCGasCap,
|
RPCGasCap: settings.RPCGasCap,
|
||||||
GroupCacheConfig: settings.GroupCache,
|
GroupCacheConfig: settings.GroupCache,
|
||||||
|
Loading…
Reference in New Issue
Block a user