gitlab.com/flarenetwork/coreth@v0.1.1/eth/gasprice/gasprice_test.go (about) 1 // (c) 2019-2020, 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 2020 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 gasprice 28 29 import ( 30 "context" 31 "math" 32 "math/big" 33 "testing" 34 35 "github.com/ethereum/go-ethereum/common" 36 "github.com/ethereum/go-ethereum/crypto" 37 "gitlab.com/flarenetwork/coreth/consensus/dummy" 38 "gitlab.com/flarenetwork/coreth/core" 39 "gitlab.com/flarenetwork/coreth/core/rawdb" 40 "gitlab.com/flarenetwork/coreth/core/types" 41 "gitlab.com/flarenetwork/coreth/core/vm" 42 "gitlab.com/flarenetwork/coreth/params" 43 "gitlab.com/flarenetwork/coreth/rpc" 44 ) 45 46 type testBackend struct { 47 chain *core.BlockChain 48 } 49 50 func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { 51 if number == rpc.LatestBlockNumber { 52 return b.chain.CurrentBlock().Header(), nil 53 } 54 return b.chain.GetHeaderByNumber(uint64(number)), nil 55 } 56 57 func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { 58 if number == rpc.LatestBlockNumber { 59 return b.chain.CurrentBlock(), nil 60 } 61 return b.chain.GetBlockByNumber(uint64(number)), nil 62 } 63 64 func (b *testBackend) ChainConfig() *params.ChainConfig { 65 return b.chain.Config() 66 } 67 68 func newTestBackend(t *testing.T, apricotPhase3BlockTimestamp *big.Int) *testBackend { 69 var ( 70 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 71 addr = crypto.PubkeyToAddress(key.PublicKey) 72 gspec = &core.Genesis{ 73 Config: params.TestChainConfig, 74 Alloc: core.GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}}, 75 } 76 signer = types.LatestSigner(gspec.Config) 77 ) 78 if apricotPhase3BlockTimestamp != nil { 79 gspec.Config.ApricotPhase3BlockTimestamp = apricotPhase3BlockTimestamp 80 signer = types.LatestSigner(gspec.Config) 81 } else { 82 gspec.Config.ApricotPhase3BlockTimestamp = nil 83 } 84 engine := dummy.NewFaker() 85 db := rawdb.NewMemoryDatabase() 86 genesis := gspec.MustCommit(db) 87 88 // Generate testing blocks 89 blocks, _ := core.GenerateChain(gspec.Config, genesis, engine, db, 32, func(i int, b *core.BlockGen) { 90 b.SetCoinbase(common.Address{1}) 91 92 var tx *types.Transaction 93 if apricotPhase3BlockTimestamp != nil && b.Number().Cmp(apricotPhase3BlockTimestamp) >= 0 { 94 txdata := &types.DynamicFeeTx{ 95 ChainID: gspec.Config.ChainID, 96 Nonce: b.TxNonce(addr), 97 To: &common.Address{}, 98 Gas: 30000, 99 GasFeeCap: big.NewInt(500 * params.GWei), 100 GasTipCap: big.NewInt(int64(i+1) * params.GWei), 101 Data: []byte{}, 102 } 103 tx = types.NewTx(txdata) 104 } else { 105 txdata := &types.LegacyTx{ 106 Nonce: b.TxNonce(addr), 107 To: &common.Address{}, 108 Gas: 21000, 109 GasPrice: big.NewInt(int64(i+500) * params.GWei), 110 Value: big.NewInt(100), 111 Data: []byte{}, 112 } 113 tx = types.NewTx(txdata) 114 } 115 tx, err := types.SignTx(tx, signer, key) 116 if err != nil { 117 t.Fatalf("failed to create tx: %v", err) 118 } 119 b.AddTx(tx) 120 }) 121 // Construct testing chain 122 diskdb := rawdb.NewMemoryDatabase() 123 gspec.Commit(diskdb) 124 chain, err := core.NewBlockChain(diskdb, core.DefaultCacheConfig, gspec.Config, engine, vm.Config{}, common.Hash{}) 125 if err != nil { 126 t.Fatalf("Failed to create local chain, %v", err) 127 } 128 chain.InsertChain(blocks) 129 return &testBackend{chain: chain} 130 } 131 132 func (b *testBackend) CurrentHeader() *types.Header { 133 return b.chain.CurrentHeader() 134 } 135 136 func (b *testBackend) GetBlockByNumber(number uint64) *types.Block { 137 return b.chain.GetBlockByNumber(number) 138 } 139 140 func TestSuggestTipCap(t *testing.T) { 141 config := Config{ 142 Blocks: 3, 143 Percentile: 60, 144 } 145 // TODO(aaronbuchwald) review modified test cases 146 var cases = []struct { 147 fork *big.Int // ApricotPhase3BlockTimestamp 148 expect *big.Int // Expected gasprice suggestion 149 }{ 150 {nil, big.NewInt(params.GWei * int64(225))}, 151 {big.NewInt(0), big.NewInt(params.GWei * int64(10))}, // Fork point in genesis 152 {big.NewInt(1), big.NewInt(params.GWei * int64(10))}, // Fork point in first block 153 {big.NewInt(32), big.NewInt(params.GWei * int64(10))}, // Fork point in last block 154 {big.NewInt(33), big.NewInt(params.GWei * int64(10))}, // Fork point in the future 155 } 156 for _, c := range cases { 157 backend := newTestBackend(t, c.fork) 158 oracle := NewOracle(backend, config) 159 160 // The gas price sampled is: 32G, 31G, 30G, 29G, 28G, 27G 161 got, err := oracle.SuggestTipCap(context.Background()) 162 if err != nil { 163 t.Fatalf("Failed to retrieve recommended gas price: %v", err) 164 } 165 if got.Cmp(c.expect) != 0 { 166 t.Fatalf("Gas price mismatch, want %d, got %d, with fork: %d", c.expect, got, c.fork) 167 } 168 } 169 }