github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/evm/emulator/config.go (about) 1 package emulator 2 3 import ( 4 "math" 5 "math/big" 6 7 gethCommon "github.com/onflow/go-ethereum/common" 8 gethCore "github.com/onflow/go-ethereum/core" 9 gethVM "github.com/onflow/go-ethereum/core/vm" 10 gethParams "github.com/onflow/go-ethereum/params" 11 12 "github.com/onflow/flow-go/fvm/evm/types" 13 ) 14 15 var ( 16 DefaultBlockLevelGasLimit = uint64(math.MaxUint64) 17 DefaultBaseFee = big.NewInt(0) 18 zero = uint64(0) 19 bigZero = big.NewInt(0) 20 ) 21 22 // Config sets the required parameters 23 type Config struct { 24 // Chain Config 25 ChainConfig *gethParams.ChainConfig 26 // EVM config 27 EVMConfig gethVM.Config 28 // block context 29 BlockContext *gethVM.BlockContext 30 // transaction context 31 TxContext *gethVM.TxContext 32 // base unit of gas for direct calls 33 DirectCallBaseGasUsage uint64 34 } 35 36 func (c *Config) ChainRules() gethParams.Rules { 37 return c.ChainConfig.Rules( 38 c.BlockContext.BlockNumber, 39 c.BlockContext.Random != nil, 40 c.BlockContext.Time) 41 } 42 43 // DefaultChainConfig is the default chain config which 44 // considers majority of EVM upgrades (e.g. Shanghai update) already been applied 45 // this has done through setting the height of these changes 46 // to zero nad setting the time for some other changes to zero 47 // For the future changes of EVM, we need to update the EVM go mod version 48 // and set a proper height for the specific release based on the Flow EVM heights 49 // so it could gets activated at a desired time. 50 var DefaultChainConfig = &gethParams.ChainConfig{ 51 ChainID: types.FlowEVMPreviewNetChainID, 52 53 // Fork scheduling based on block heights 54 HomesteadBlock: bigZero, 55 DAOForkBlock: bigZero, 56 DAOForkSupport: false, 57 EIP150Block: bigZero, 58 EIP155Block: bigZero, 59 EIP158Block: bigZero, 60 ByzantiumBlock: bigZero, // already on Byzantium 61 ConstantinopleBlock: bigZero, // already on Constantinople 62 PetersburgBlock: bigZero, // already on Petersburg 63 IstanbulBlock: bigZero, // already on Istanbul 64 BerlinBlock: bigZero, // already on Berlin 65 LondonBlock: bigZero, // already on London 66 MuirGlacierBlock: bigZero, // already on MuirGlacier 67 68 // Fork scheduling based on timestamps 69 ShanghaiTime: &zero, // already on Shanghai 70 CancunTime: &zero, // already on Cancun 71 PragueTime: &zero, // already on Prague 72 } 73 74 // Default config supports the dynamic fee structure (EIP-1559) 75 // so it accepts both legacy transactions with a fixed gas price 76 // and dynamic transactions with tip and cap. 77 // Yet default config keeps the base fee to zero (no automatic adjustment) 78 func defaultConfig() *Config { 79 return &Config{ 80 ChainConfig: DefaultChainConfig, 81 EVMConfig: gethVM.Config{ 82 // setting this flag let us we force the base fee to zero (coinbase will collect) 83 NoBaseFee: true, 84 }, 85 TxContext: &gethVM.TxContext{ 86 GasPrice: new(big.Int), 87 BlobFeeCap: new(big.Int), 88 }, 89 BlockContext: &gethVM.BlockContext{ 90 CanTransfer: gethCore.CanTransfer, 91 Transfer: gethCore.Transfer, 92 GasLimit: DefaultBlockLevelGasLimit, 93 BaseFee: DefaultBaseFee, 94 GetHash: func(n uint64) gethCommon.Hash { 95 return gethCommon.Hash{} 96 }, 97 GetPrecompile: gethCore.GetPrecompile, 98 }, 99 } 100 } 101 102 // NewConfig initializes a new config 103 func NewConfig(opts ...Option) *Config { 104 ctx := defaultConfig() 105 for _, applyOption := range opts { 106 ctx = applyOption(ctx) 107 } 108 return ctx 109 } 110 111 type Option func(*Config) *Config 112 113 // WithChainID sets the evm chain ID 114 func WithChainID(chainID *big.Int) Option { 115 return func(c *Config) *Config { 116 c.ChainConfig.ChainID = chainID 117 return c 118 } 119 } 120 121 // WithOrigin sets the origin of the transaction (signer) 122 func WithOrigin(origin gethCommon.Address) Option { 123 return func(c *Config) *Config { 124 c.TxContext.Origin = origin 125 return c 126 } 127 } 128 129 // WithGasPrice sets the gas price for the transaction (usually the one sets by the sender) 130 func WithGasPrice(gasPrice *big.Int) Option { 131 return func(c *Config) *Config { 132 c.TxContext.GasPrice = gasPrice 133 return c 134 } 135 } 136 137 // WithGasLimit sets the gas limit of the transaction 138 func WithGasLimit(gasLimit uint64) Option { 139 return func(c *Config) *Config { 140 c.BlockContext.GasLimit = gasLimit 141 return c 142 } 143 } 144 145 // WithCoinbase sets the coinbase of the block where the fees are collected in 146 func WithCoinbase(coinbase gethCommon.Address) Option { 147 return func(c *Config) *Config { 148 c.BlockContext.Coinbase = coinbase 149 return c 150 } 151 } 152 153 // WithBlockNumber sets the block height in the block context 154 func WithBlockNumber(blockNumber *big.Int) Option { 155 return func(c *Config) *Config { 156 c.BlockContext.BlockNumber = blockNumber 157 return c 158 } 159 } 160 161 // WithBlockTime sets the block time in the block context 162 func WithBlockTime(time uint64) Option { 163 return func(c *Config) *Config { 164 c.BlockContext.Time = time 165 return c 166 } 167 } 168 169 // WithGetBlockHashFunction sets the functionality to look up block hash by height 170 func WithGetBlockHashFunction(getHash gethVM.GetHashFunc) Option { 171 return func(c *Config) *Config { 172 c.BlockContext.GetHash = getHash 173 return c 174 } 175 } 176 177 // WithDirectCallBaseGasUsage sets the base direct call gas usage 178 func WithDirectCallBaseGasUsage(gas uint64) Option { 179 return func(c *Config) *Config { 180 c.DirectCallBaseGasUsage = gas 181 return c 182 } 183 } 184 185 // WithExtraPrecompiles appends precompile list with extra precompiles 186 func WithExtraPrecompiles(precompiles []types.Precompile) Option { 187 return func(c *Config) *Config { 188 extraPreCompMap := make(map[gethCommon.Address]gethVM.PrecompiledContract) 189 for _, pc := range precompiles { 190 extraPreCompMap[pc.Address().ToCommon()] = pc 191 } 192 c.BlockContext.GetPrecompile = func(rules gethParams.Rules, addr gethCommon.Address) (gethVM.PrecompiledContract, bool) { 193 prec, found := extraPreCompMap[addr] 194 if found { 195 return prec, true 196 } 197 return gethCore.GetPrecompile(rules, addr) 198 } 199 return c 200 } 201 } 202 203 // WithRandom sets the block context random field 204 func WithRandom(rand *gethCommon.Hash) Option { 205 return func(c *Config) *Config { 206 c.BlockContext.Random = rand 207 return c 208 } 209 }