github.com/MetalBlockchain/subnet-evm@v0.4.9/internal/ethapi/transaction_args_test.go (about) 1 // (c) 2022, Ava Labs, Inc. 2 // 3 // This file is a derived work, based on the go-ethereum library whose original 4 // notices appear below. 5 // 6 // It is distributed under a license compatible with the licensing terms of the 7 // original code from which it is derived. 8 // 9 // Much love to the original authors for their work. 10 // ********** 11 // Copyright 2022 The go-ethereum Authors 12 // This file is part of the go-ethereum library. 13 // 14 // The go-ethereum library is free software: you can redistribute it and/or modify 15 // it under the terms of the GNU Lesser General Public License as published by 16 // the Free Software Foundation, either version 3 of the License, or 17 // (at your option) any later version. 18 // 19 // The go-ethereum library is distributed in the hope that it will be useful, 20 // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 // GNU Lesser General Public License for more details. 23 // 24 // You should have received a copy of the GNU Lesser General Public License 25 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 26 27 package ethapi 28 29 import ( 30 "context" 31 "fmt" 32 "math/big" 33 "reflect" 34 "testing" 35 36 "github.com/MetalBlockchain/subnet-evm/core/types" 37 "github.com/MetalBlockchain/subnet-evm/params" 38 "github.com/ethereum/go-ethereum/common" 39 "github.com/ethereum/go-ethereum/common/hexutil" 40 ) 41 42 var _ feeBackend = &backendMock{} 43 44 // TestSetFeeDefaults tests the logic for filling in default fee values works as expected. 45 func TestSetFeeDefaults(t *testing.T) { 46 type test struct { 47 name string 48 isLondon bool 49 in *TransactionArgs 50 want *TransactionArgs 51 err error 52 } 53 54 var ( 55 b = newBackendMock() 56 fortytwo = (*hexutil.Big)(big.NewInt(42)) 57 maxFee = (*hexutil.Big)(new(big.Int).Add(new(big.Int).Mul(b.current.BaseFee, big.NewInt(2)), fortytwo.ToInt())) 58 al = &types.AccessList{types.AccessTuple{Address: common.Address{0xaa}, StorageKeys: []common.Hash{{0x01}}}} 59 ) 60 61 tests := []test{ 62 // Legacy txs 63 { 64 "legacy tx pre-London", 65 false, 66 &TransactionArgs{}, 67 &TransactionArgs{GasPrice: fortytwo}, 68 nil, 69 }, 70 { 71 "legacy tx post-London, explicit gas price", 72 true, 73 &TransactionArgs{GasPrice: fortytwo}, 74 &TransactionArgs{GasPrice: fortytwo}, 75 nil, 76 }, 77 78 // Access list txs 79 { 80 "access list tx pre-London", 81 false, 82 &TransactionArgs{AccessList: al}, 83 &TransactionArgs{AccessList: al, GasPrice: fortytwo}, 84 nil, 85 }, 86 { 87 "access list tx post-London, explicit gas price", 88 false, 89 &TransactionArgs{AccessList: al, GasPrice: fortytwo}, 90 &TransactionArgs{AccessList: al, GasPrice: fortytwo}, 91 nil, 92 }, 93 { 94 "access list tx post-London", 95 true, 96 &TransactionArgs{AccessList: al}, 97 &TransactionArgs{AccessList: al, MaxFeePerGas: maxFee, MaxPriorityFeePerGas: fortytwo}, 98 nil, 99 }, 100 { 101 "access list tx post-London, only max fee", 102 true, 103 &TransactionArgs{AccessList: al, MaxFeePerGas: maxFee}, 104 &TransactionArgs{AccessList: al, MaxFeePerGas: maxFee, MaxPriorityFeePerGas: fortytwo}, 105 nil, 106 }, 107 { 108 "access list tx post-London, only priority fee", 109 true, 110 &TransactionArgs{AccessList: al, MaxFeePerGas: maxFee}, 111 &TransactionArgs{AccessList: al, MaxFeePerGas: maxFee, MaxPriorityFeePerGas: fortytwo}, 112 nil, 113 }, 114 115 // Dynamic fee txs 116 { 117 "dynamic tx post-London", 118 true, 119 &TransactionArgs{}, 120 &TransactionArgs{MaxFeePerGas: maxFee, MaxPriorityFeePerGas: fortytwo}, 121 nil, 122 }, 123 { 124 "dynamic tx post-London, only max fee", 125 true, 126 &TransactionArgs{MaxFeePerGas: maxFee}, 127 &TransactionArgs{MaxFeePerGas: maxFee, MaxPriorityFeePerGas: fortytwo}, 128 nil, 129 }, 130 { 131 "dynamic tx post-London, only priority fee", 132 true, 133 &TransactionArgs{MaxFeePerGas: maxFee}, 134 &TransactionArgs{MaxFeePerGas: maxFee, MaxPriorityFeePerGas: fortytwo}, 135 nil, 136 }, 137 { 138 "dynamic fee tx pre-London, maxFee set", 139 false, 140 &TransactionArgs{MaxFeePerGas: maxFee}, 141 nil, 142 fmt.Errorf("maxFeePerGas and maxPriorityFeePerGas are not valid before London is active"), 143 }, 144 { 145 "dynamic fee tx pre-London, priorityFee set", 146 false, 147 &TransactionArgs{MaxPriorityFeePerGas: fortytwo}, 148 nil, 149 fmt.Errorf("maxFeePerGas and maxPriorityFeePerGas are not valid before London is active"), 150 }, 151 { 152 "dynamic fee tx, maxFee < priorityFee", 153 true, 154 &TransactionArgs{MaxFeePerGas: maxFee, MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(1000))}, 155 nil, 156 fmt.Errorf("maxFeePerGas (0x3e) < maxPriorityFeePerGas (0x3e8)"), 157 }, 158 { 159 "dynamic fee tx, maxFee < priorityFee while setting default", 160 true, 161 &TransactionArgs{MaxFeePerGas: (*hexutil.Big)(big.NewInt(7))}, 162 nil, 163 fmt.Errorf("maxFeePerGas (0x7) < maxPriorityFeePerGas (0x2a)"), 164 }, 165 166 // Misc 167 { 168 "set all fee parameters", 169 false, 170 &TransactionArgs{GasPrice: fortytwo, MaxFeePerGas: maxFee, MaxPriorityFeePerGas: fortytwo}, 171 nil, 172 fmt.Errorf("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified"), 173 }, 174 { 175 "set gas price and maxPriorityFee", 176 false, 177 &TransactionArgs{GasPrice: fortytwo, MaxPriorityFeePerGas: fortytwo}, 178 nil, 179 fmt.Errorf("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified"), 180 }, 181 { 182 "set gas price and maxFee", 183 true, 184 &TransactionArgs{GasPrice: fortytwo, MaxFeePerGas: maxFee}, 185 nil, 186 fmt.Errorf("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified"), 187 }, 188 } 189 190 ctx := context.Background() 191 for i, test := range tests { 192 if test.isLondon { 193 b.activateLondon() 194 } else { 195 b.deactivateLondon() 196 } 197 got := test.in 198 err := got.setFeeDefaults(ctx, b) 199 if err != nil && err.Error() == test.err.Error() { 200 // Test threw expected error. 201 continue 202 } else if err != nil { 203 t.Fatalf("test %d (%s): unexpected error: %s", i, test.name, err) 204 } 205 if !reflect.DeepEqual(got, test.want) { 206 t.Fatalf("test %d (%s): did not fill defaults as expected: (got: %v, want: %v)", i, test.name, got, test.want) 207 } 208 } 209 } 210 211 type backendMock struct { 212 current *types.Header 213 config *params.ChainConfig 214 } 215 216 func newBackendMock() *backendMock { 217 config := ¶ms.ChainConfig{ 218 ChainID: big.NewInt(42), 219 HomesteadBlock: big.NewInt(0), 220 EIP150Block: big.NewInt(0), 221 EIP155Block: big.NewInt(0), 222 EIP158Block: big.NewInt(0), 223 ByzantiumBlock: big.NewInt(0), 224 ConstantinopleBlock: big.NewInt(0), 225 PetersburgBlock: big.NewInt(0), 226 IstanbulBlock: big.NewInt(0), 227 MuirGlacierBlock: big.NewInt(0), 228 NetworkUpgrades: params.NetworkUpgrades{ 229 SubnetEVMTimestamp: big.NewInt(1000), 230 }, 231 } 232 return &backendMock{ 233 current: &types.Header{ 234 Difficulty: big.NewInt(10000000000), 235 Number: big.NewInt(1100), 236 GasLimit: 8_000_000, 237 GasUsed: 8_000_000, 238 Time: 555, 239 Extra: make([]byte, 32), 240 BaseFee: big.NewInt(10), 241 }, 242 config: config, 243 } 244 } 245 246 func (b *backendMock) activateLondon() { 247 b.current.Time = uint64(1100) 248 } 249 250 func (b *backendMock) deactivateLondon() { 251 b.current.Time = uint64(900) 252 } 253 func (b *backendMock) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { 254 return big.NewInt(42), nil 255 } 256 func (b *backendMock) CurrentHeader() *types.Header { return b.current } 257 func (b *backendMock) ChainConfig() *params.ChainConfig { return b.config }