eth/gasprice: implement feeHistory API (#23033)

* eth/gasprice: implement feeHistory API

* eth/gasprice: factored out resolveBlockRange

* eth/gasprice: add sanity check for missing block

* eth/gasprice: fetch actual gas used from receipts

* miner, eth/gasprice: add PendingBlockAndReceipts

* internal/ethapi: use hexutil.Big

* eth/gasprice: return error when requesting beyond head block

* eth/gasprice: fixed tests and return errors correctly

* eth/gasprice: rename receiver name

* eth/gasprice: return directly if blockCount == 0

Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
This commit is contained in:
Felföldi Zsolt
2021-06-28 16:16:32 +02:00
committed by GitHub
parent 1b5582acf7
commit 35dbf7a8a3
13 changed files with 558 additions and 58 deletions

View File

@@ -33,29 +33,64 @@ import (
"github.com/ethereum/go-ethereum/rpc"
)
const testHead = 32
type testBackend struct {
chain *core.BlockChain
chain *core.BlockChain
pending bool // pending block available
}
func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
if number > testHead {
return nil, nil
}
if number == rpc.LatestBlockNumber {
return b.chain.CurrentBlock().Header(), nil
number = testHead
}
if number == rpc.PendingBlockNumber {
if b.pending {
number = testHead + 1
} else {
return nil, nil
}
}
return b.chain.GetHeaderByNumber(uint64(number)), nil
}
func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
if number > testHead {
return nil, nil
}
if number == rpc.LatestBlockNumber {
return b.chain.CurrentBlock(), nil
number = testHead
}
if number == rpc.PendingBlockNumber {
if b.pending {
number = testHead + 1
} else {
return nil, nil
}
}
return b.chain.GetBlockByNumber(uint64(number)), nil
}
func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
return b.chain.GetReceiptsByHash(hash), nil
}
func (b *testBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
if b.pending {
block := b.chain.GetBlockByNumber(testHead + 1)
return block, b.chain.GetReceiptsByHash(block.Hash())
}
return nil, nil
}
func (b *testBackend) ChainConfig() *params.ChainConfig {
return b.chain.Config()
}
func newTestBackend(t *testing.T, londonBlock *big.Int) *testBackend {
func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBackend {
var (
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr = crypto.PubkeyToAddress(key.PublicKey)
@@ -76,7 +111,7 @@ func newTestBackend(t *testing.T, londonBlock *big.Int) *testBackend {
genesis, _ := gspec.Commit(db)
// Generate testing blocks
blocks, _ := core.GenerateChain(gspec.Config, genesis, engine, db, 32, func(i int, b *core.BlockGen) {
blocks, _ := core.GenerateChain(gspec.Config, genesis, engine, db, testHead+1, func(i int, b *core.BlockGen) {
b.SetCoinbase(common.Address{1})
var tx *types.Transaction
@@ -116,7 +151,7 @@ func newTestBackend(t *testing.T, londonBlock *big.Int) *testBackend {
t.Fatalf("Failed to create local chain, %v", err)
}
chain.InsertChain(blocks)
return &testBackend{chain: chain}
return &testBackend{chain: chain, pending: pending}
}
func (b *testBackend) CurrentHeader() *types.Header {
@@ -144,7 +179,7 @@ func TestSuggestTipCap(t *testing.T) {
{big.NewInt(33), big.NewInt(params.GWei * int64(30))}, // Fork point in the future
}
for _, c := range cases {
backend := newTestBackend(t, c.fork)
backend := newTestBackend(t, c.fork, false)
oracle := NewOracle(backend, config)
// The gas price sampled is: 32G, 31G, 30G, 29G, 28G, 27G