github.com/klaytn/klaytn@v1.12.1/node/cn/gasprice/gasprice_test.go (about) 1 // Copyright 2019 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn 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 klaytn 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 klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package gasprice 18 19 import ( 20 "context" 21 "math/big" 22 "testing" 23 24 "github.com/klaytn/klaytn/blockchain" 25 "github.com/klaytn/klaytn/blockchain/types" 26 "github.com/klaytn/klaytn/blockchain/vm" 27 "github.com/klaytn/klaytn/common" 28 "github.com/klaytn/klaytn/common/math" 29 "github.com/klaytn/klaytn/consensus/gxhash" 30 "github.com/klaytn/klaytn/crypto" 31 "github.com/klaytn/klaytn/networks/rpc" 32 "github.com/klaytn/klaytn/params" 33 "github.com/klaytn/klaytn/storage/database" 34 35 "github.com/golang/mock/gomock" 36 mock_api "github.com/klaytn/klaytn/api/mocks" 37 "github.com/stretchr/testify/assert" 38 ) 39 40 const testHead = 32 41 42 type testBackend struct { 43 chain *blockchain.BlockChain 44 } 45 46 func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { 47 if number > testHead { 48 return nil, nil 49 } 50 if number == rpc.LatestBlockNumber { 51 number = testHead 52 } 53 return b.chain.GetHeaderByNumber(uint64(number)), nil 54 } 55 56 func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { 57 if number > testHead { 58 return nil, nil 59 } 60 if number == rpc.LatestBlockNumber { 61 number = testHead 62 } 63 return b.chain.GetBlockByNumber(uint64(number)), nil 64 } 65 66 func (b *testBackend) GetBlockReceipts(ctx context.Context, hash common.Hash) types.Receipts { 67 return b.chain.GetReceiptsByBlockHash(hash) 68 } 69 70 func (b *testBackend) ChainConfig() *params.ChainConfig { 71 return b.chain.Config() 72 } 73 74 func (b *testBackend) CurrentBlock() *types.Block { 75 return b.chain.CurrentBlock() 76 } 77 78 func newTestBackend(t *testing.T) *testBackend { 79 var ( 80 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 81 addr = crypto.PubkeyToAddress(key.PublicKey) 82 83 gspec = &blockchain.Genesis{ 84 Config: params.TestChainConfig, 85 Alloc: blockchain.GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}}, 86 } 87 db = database.NewMemoryDBManager() 88 genesis = gspec.MustCommit(db) 89 ) 90 // Generate testing blocks 91 blocks, _ := blockchain.GenerateChain(gspec.Config, genesis, gxhash.NewFaker(), db, testHead+1, func(i int, b *blockchain.BlockGen) { 92 b.SetRewardbase(addr) 93 94 toaddr := common.Address{} 95 data := make([]byte, 1) 96 gas, _ := types.IntrinsicGas(data, nil, false, params.TestChainConfig.Rules(big.NewInt(0))) 97 signer := types.NewEIP155Signer(params.TestChainConfig.ChainID) 98 tx, _ := types.SignTx(types.NewTransaction(b.TxNonce(addr), toaddr, big.NewInt(1), gas, nil, data), signer, key) 99 b.AddTx(tx) 100 }) 101 // Construct testing chain 102 chain, err := blockchain.NewBlockChain(db, nil, gspec.Config, gxhash.NewFaker(), vm.Config{}) 103 if err != nil { 104 t.Fatalf("Failed to create local chain, %v", err) 105 } 106 chain.InsertChain(blocks) 107 return &testBackend{chain: chain} 108 } 109 110 func TestGasPrice_NewOracle(t *testing.T) { 111 mockCtrl := gomock.NewController(t) 112 defer mockCtrl.Finish() 113 mockBackend := mock_api.NewMockBackend(mockCtrl) 114 params := Config{} 115 oracle := NewOracle(mockBackend, params, nil) 116 117 assert.Nil(t, oracle.lastPrice) 118 assert.Equal(t, 1, oracle.checkBlocks) 119 assert.Equal(t, 0, oracle.maxEmpty) 120 assert.Equal(t, 5, oracle.maxBlocks) 121 assert.Equal(t, 0, oracle.percentile) 122 123 params = Config{Blocks: 2} 124 oracle = NewOracle(mockBackend, params, nil) 125 126 assert.Nil(t, oracle.lastPrice) 127 assert.Equal(t, 2, oracle.checkBlocks) 128 assert.Equal(t, 1, oracle.maxEmpty) 129 assert.Equal(t, 10, oracle.maxBlocks) 130 assert.Equal(t, 0, oracle.percentile) 131 132 params = Config{Percentile: -1} 133 oracle = NewOracle(mockBackend, params, nil) 134 135 assert.Nil(t, oracle.lastPrice) 136 assert.Equal(t, 1, oracle.checkBlocks) 137 assert.Equal(t, 0, oracle.maxEmpty) 138 assert.Equal(t, 5, oracle.maxBlocks) 139 assert.Equal(t, 0, oracle.percentile) 140 141 params = Config{Percentile: 101} 142 oracle = NewOracle(mockBackend, params, nil) 143 144 assert.Nil(t, oracle.lastPrice) 145 assert.Equal(t, 1, oracle.checkBlocks) 146 assert.Equal(t, 0, oracle.maxEmpty) 147 assert.Equal(t, 5, oracle.maxBlocks) 148 assert.Equal(t, 100, oracle.percentile) 149 150 params = Config{Percentile: 101, Default: big.NewInt(123)} 151 oracle = NewOracle(mockBackend, params, nil) 152 153 assert.Equal(t, big.NewInt(123), oracle.lastPrice) 154 assert.Equal(t, 1, oracle.checkBlocks) 155 assert.Equal(t, 0, oracle.maxEmpty) 156 assert.Equal(t, 5, oracle.maxBlocks) 157 assert.Equal(t, 100, oracle.percentile) 158 } 159 160 func TestGasPrice_SuggestPrice(t *testing.T) { 161 mockCtrl := gomock.NewController(t) 162 defer mockCtrl.Finish() 163 mockBackend := mock_api.NewMockBackend(mockCtrl) 164 params := Config{} 165 testBackend := newTestBackend(t) 166 chainConfig := testBackend.ChainConfig() 167 chainConfig.UnitPrice = 0 168 txPoolWith0 := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, chainConfig, testBackend.chain) 169 oracle := NewOracle(mockBackend, params, txPoolWith0) 170 171 currentBlock := testBackend.CurrentBlock() 172 mockBackend.EXPECT().ChainConfig().Return(chainConfig).Times(2) 173 mockBackend.EXPECT().CurrentBlock().Return(currentBlock).Times(2) 174 175 price, err := oracle.SuggestPrice(nil) 176 assert.Equal(t, price, common.Big0) 177 assert.Nil(t, err) 178 179 params = Config{Default: big.NewInt(123)} 180 chainConfig.UnitPrice = 25 181 txPoolWith25 := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, chainConfig, testBackend.chain) 182 oracle = NewOracle(mockBackend, params, txPoolWith25) 183 184 price, err = oracle.SuggestPrice(nil) 185 assert.Equal(t, big.NewInt(25), price) 186 assert.Nil(t, err) 187 }