github.com/onflow/flow-go@v0.33.17/fvm/evm/emulator/config.go (about)

     1  package emulator
     2  
     3  import (
     4  	"math"
     5  	"math/big"
     6  
     7  	"github.com/ethereum/go-ethereum/common"
     8  	"github.com/ethereum/go-ethereum/core"
     9  	"github.com/ethereum/go-ethereum/core/vm"
    10  	"github.com/ethereum/go-ethereum/crypto"
    11  	"github.com/ethereum/go-ethereum/params"
    12  )
    13  
    14  var (
    15  	FlowEVMTestnetChainID = big.NewInt(666)
    16  	FlowEVMMainnetChainID = big.NewInt(777)
    17  	BlockLevelGasLimit    = uint64(math.MaxUint64)
    18  	zero                  = uint64(0)
    19  )
    20  
    21  // Config sets the required parameters
    22  type Config struct {
    23  	// Chain Config
    24  	ChainConfig *params.ChainConfig
    25  	// EVM config
    26  	EVMConfig vm.Config
    27  	// block context
    28  	BlockContext *vm.BlockContext
    29  	// transaction context
    30  	TxContext *vm.TxContext
    31  	// base unit of gas for direct calls
    32  	DirectCallBaseGasUsage uint64
    33  }
    34  
    35  // DefaultChainConfig is the default chain config which
    36  // considers majority of EVM upgrades (e.g. Shanghai update) already been applied
    37  // this has done through setting the height of these changes
    38  // to zero nad setting the time for some other changes to zero
    39  // For the future changes of EVM, we need to update the EVM go mod version
    40  // and set a proper height for the specific release based on the Flow EVM heights
    41  // so it could gets activated at a desired time.
    42  var DefaultChainConfig = &params.ChainConfig{
    43  	ChainID: FlowEVMTestnetChainID, // default is testnet
    44  
    45  	// Fork scheduling based on block heights
    46  	HomesteadBlock:      big.NewInt(0),
    47  	DAOForkBlock:        big.NewInt(0),
    48  	DAOForkSupport:      false,
    49  	EIP150Block:         big.NewInt(0),
    50  	EIP155Block:         big.NewInt(0),
    51  	EIP158Block:         big.NewInt(0),
    52  	ByzantiumBlock:      big.NewInt(0), // already on Byzantium
    53  	ConstantinopleBlock: big.NewInt(0), // already on Constantinople
    54  	PetersburgBlock:     big.NewInt(0), // already on Petersburg
    55  	IstanbulBlock:       big.NewInt(0), // already on Istanbul
    56  	BerlinBlock:         big.NewInt(0), // already on Berlin
    57  	LondonBlock:         big.NewInt(0), // already on London
    58  	MuirGlacierBlock:    big.NewInt(0), // already on MuirGlacier
    59  
    60  	// Fork scheduling based on timestamps
    61  	ShanghaiTime: &zero, // already on Shanghai
    62  	CancunTime:   &zero, // already on Cancun
    63  	PragueTime:   &zero, // already on Prague
    64  }
    65  
    66  func defaultConfig() *Config {
    67  	return &Config{
    68  		ChainConfig: DefaultChainConfig,
    69  		EVMConfig: vm.Config{
    70  			NoBaseFee: true,
    71  		},
    72  		TxContext: &vm.TxContext{
    73  			GasPrice:   new(big.Int),
    74  			BlobFeeCap: new(big.Int),
    75  		},
    76  		BlockContext: &vm.BlockContext{
    77  			CanTransfer: core.CanTransfer,
    78  			Transfer:    core.Transfer,
    79  			GasLimit:    BlockLevelGasLimit, // block gas limit
    80  			BaseFee:     big.NewInt(0),
    81  			GetHash: func(n uint64) common.Hash { // default returns some random hash values
    82  				return common.BytesToHash(crypto.Keccak256([]byte(new(big.Int).SetUint64(n).String())))
    83  			},
    84  		},
    85  	}
    86  }
    87  
    88  // NewConfig initializes a new config
    89  func NewConfig(opts ...Option) *Config {
    90  	ctx := defaultConfig()
    91  	for _, applyOption := range opts {
    92  		ctx = applyOption(ctx)
    93  	}
    94  	return ctx
    95  }
    96  
    97  type Option func(*Config) *Config
    98  
    99  // WithMainnetChainID sets the chain ID to flow evm testnet
   100  func WithTestnetChainID() Option {
   101  	return func(c *Config) *Config {
   102  		c.ChainConfig.ChainID = FlowEVMTestnetChainID
   103  		return c
   104  	}
   105  }
   106  
   107  // WithMainnetChainID sets the chain ID to flow evm mainnet
   108  func WithMainnetChainID() Option {
   109  	return func(c *Config) *Config {
   110  		c.ChainConfig.ChainID = FlowEVMMainnetChainID
   111  		return c
   112  	}
   113  
   114  }
   115  
   116  // WithOrigin sets the origin of the transaction (signer)
   117  func WithOrigin(origin common.Address) Option {
   118  	return func(c *Config) *Config {
   119  		c.TxContext.Origin = origin
   120  		return c
   121  	}
   122  }
   123  
   124  // WithGasPrice sets the gas price for the transaction (usually the one sets by the sender)
   125  func WithGasPrice(gasPrice *big.Int) Option {
   126  	return func(c *Config) *Config {
   127  		c.TxContext.GasPrice = gasPrice
   128  		return c
   129  	}
   130  }
   131  
   132  // WithGasLimit sets the gas limit of the transaction
   133  func WithGasLimit(gasLimit uint64) Option {
   134  	return func(c *Config) *Config {
   135  		c.BlockContext.GasLimit = gasLimit
   136  		return c
   137  	}
   138  }
   139  
   140  // WithCoinbase sets the coinbase of the block where the fees are collected in
   141  func WithCoinbase(coinbase common.Address) Option {
   142  	return func(c *Config) *Config {
   143  		c.BlockContext.Coinbase = coinbase
   144  		return c
   145  	}
   146  }
   147  
   148  // WithBlockNumber sets the block height in the block context
   149  func WithBlockNumber(blockNumber *big.Int) Option {
   150  	return func(c *Config) *Config {
   151  		c.BlockContext.BlockNumber = blockNumber
   152  		return c
   153  	}
   154  }
   155  
   156  // WithBlockTime sets the block time in the block context
   157  func WithBlockTime(time uint64) Option {
   158  	return func(c *Config) *Config {
   159  		c.BlockContext.Time = time
   160  		return c
   161  	}
   162  }
   163  
   164  // WithGetBlockHashFunction sets the functionality to look up block hash by height
   165  func WithGetBlockHashFunction(getHash vm.GetHashFunc) Option {
   166  	return func(c *Config) *Config {
   167  		c.BlockContext.GetHash = getHash
   168  		return c
   169  	}
   170  }
   171  
   172  // WithDirectCallBaseGasUsage sets the base direct call gas usage
   173  func WithDirectCallBaseGasUsage(gas uint64) Option {
   174  	return func(c *Config) *Config {
   175  		c.DirectCallBaseGasUsage = gas
   176  		return c
   177  	}
   178  }