gitee.com/liu-zhao234568/cntest@v1.0.0/eth/gasprice/gasprice_test.go (about) 1 // Copyright 2020 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package gasprice 18 19 import ( 20 "context" 21 "math" 22 "math/big" 23 "testing" 24 25 "gitee.com/liu-zhao234568/cntest/common" 26 "gitee.com/liu-zhao234568/cntest/consensus/ethash" 27 "gitee.com/liu-zhao234568/cntest/core" 28 "gitee.com/liu-zhao234568/cntest/core/rawdb" 29 "gitee.com/liu-zhao234568/cntest/core/types" 30 "gitee.com/liu-zhao234568/cntest/core/vm" 31 "gitee.com/liu-zhao234568/cntest/crypto" 32 "gitee.com/liu-zhao234568/cntest/params" 33 "gitee.com/liu-zhao234568/cntest/rpc" 34 ) 35 36 const testHead = 32 37 38 type testBackend struct { 39 chain *core.BlockChain 40 pending bool // pending block available 41 } 42 43 func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { 44 if number > testHead { 45 return nil, nil 46 } 47 if number == rpc.LatestBlockNumber { 48 number = testHead 49 } 50 if number == rpc.PendingBlockNumber { 51 if b.pending { 52 number = testHead + 1 53 } else { 54 return nil, nil 55 } 56 } 57 return b.chain.GetHeaderByNumber(uint64(number)), nil 58 } 59 60 func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { 61 if number > testHead { 62 return nil, nil 63 } 64 if number == rpc.LatestBlockNumber { 65 number = testHead 66 } 67 if number == rpc.PendingBlockNumber { 68 if b.pending { 69 number = testHead + 1 70 } else { 71 return nil, nil 72 } 73 } 74 return b.chain.GetBlockByNumber(uint64(number)), nil 75 } 76 77 func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { 78 return b.chain.GetReceiptsByHash(hash), nil 79 } 80 81 func (b *testBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) { 82 if b.pending { 83 block := b.chain.GetBlockByNumber(testHead + 1) 84 return block, b.chain.GetReceiptsByHash(block.Hash()) 85 } 86 return nil, nil 87 } 88 89 func (b *testBackend) ChainConfig() *params.ChainConfig { 90 return b.chain.Config() 91 } 92 93 func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBackend { 94 var ( 95 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 96 addr = crypto.PubkeyToAddress(key.PublicKey) 97 gspec = &core.Genesis{ 98 Config: params.TestChainConfig, 99 Alloc: core.GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}}, 100 } 101 signer = types.LatestSigner(gspec.Config) 102 ) 103 if londonBlock != nil { 104 gspec.Config.LondonBlock = londonBlock 105 signer = types.LatestSigner(gspec.Config) 106 } else { 107 gspec.Config.LondonBlock = nil 108 } 109 engine := ethash.NewFaker() 110 db := rawdb.NewMemoryDatabase() 111 genesis, _ := gspec.Commit(db) 112 113 // Generate testing blocks 114 blocks, _ := core.GenerateChain(gspec.Config, genesis, engine, db, testHead+1, func(i int, b *core.BlockGen) { 115 b.SetCoinbase(common.Address{1}) 116 117 var tx *types.Transaction 118 if londonBlock != nil && b.Number().Cmp(londonBlock) >= 0 { 119 txdata := &types.DynamicFeeTx{ 120 ChainID: gspec.Config.ChainID, 121 Nonce: b.TxNonce(addr), 122 To: &common.Address{}, 123 Gas: 30000, 124 GasFeeCap: big.NewInt(100 * params.GWei), 125 GasTipCap: big.NewInt(int64(i+1) * params.GWei), 126 Data: []byte{}, 127 } 128 tx = types.NewTx(txdata) 129 } else { 130 txdata := &types.LegacyTx{ 131 Nonce: b.TxNonce(addr), 132 To: &common.Address{}, 133 Gas: 21000, 134 GasPrice: big.NewInt(int64(i+1) * params.GWei), 135 Value: big.NewInt(100), 136 Data: []byte{}, 137 } 138 tx = types.NewTx(txdata) 139 } 140 tx, err := types.SignTx(tx, signer, key) 141 if err != nil { 142 t.Fatalf("failed to create tx: %v", err) 143 } 144 b.AddTx(tx) 145 }) 146 // Construct testing chain 147 diskdb := rawdb.NewMemoryDatabase() 148 gspec.Commit(diskdb) 149 chain, err := core.NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil) 150 if err != nil { 151 t.Fatalf("Failed to create local chain, %v", err) 152 } 153 chain.InsertChain(blocks) 154 return &testBackend{chain: chain, pending: pending} 155 } 156 157 func (b *testBackend) CurrentHeader() *types.Header { 158 return b.chain.CurrentHeader() 159 } 160 161 func (b *testBackend) GetBlockByNumber(number uint64) *types.Block { 162 return b.chain.GetBlockByNumber(number) 163 } 164 165 func TestSuggestTipCap(t *testing.T) { 166 config := Config{ 167 Blocks: 3, 168 Percentile: 60, 169 Default: big.NewInt(params.GWei), 170 } 171 var cases = []struct { 172 fork *big.Int // London fork number 173 expect *big.Int // Expected gasprice suggestion 174 }{ 175 {nil, big.NewInt(params.GWei * int64(30))}, 176 {big.NewInt(0), big.NewInt(params.GWei * int64(30))}, // Fork point in genesis 177 {big.NewInt(1), big.NewInt(params.GWei * int64(30))}, // Fork point in first block 178 {big.NewInt(32), big.NewInt(params.GWei * int64(30))}, // Fork point in last block 179 {big.NewInt(33), big.NewInt(params.GWei * int64(30))}, // Fork point in the future 180 } 181 for _, c := range cases { 182 backend := newTestBackend(t, c.fork, false) 183 oracle := NewOracle(backend, config) 184 185 // The gas price sampled is: 32G, 31G, 30G, 29G, 28G, 27G 186 got, err := oracle.SuggestTipCap(context.Background()) 187 if err != nil { 188 t.Fatalf("Failed to retrieve recommended gas price: %v", err) 189 } 190 if got.Cmp(c.expect) != 0 { 191 t.Fatalf("Gas price mismatch, want %d, got %d", c.expect, got) 192 } 193 } 194 }