forked from cerc-io/plugeth
eth/gasprice/feehistory: support finalized block (#25442)
This commit is contained in:
parent
1b34ed2ed6
commit
a0b88ce869
@ -137,44 +137,68 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
|
|||||||
// also returned if requested and available.
|
// also returned if requested and available.
|
||||||
// Note: an error is only returned if retrieving the head header has failed. If there are no
|
// Note: an error is only returned if retrieving the head header has failed. If there are no
|
||||||
// retrievable blocks in the specified range then zero block count is returned with no error.
|
// retrievable blocks in the specified range then zero block count is returned with no error.
|
||||||
func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.BlockNumber, blocks int) (*types.Block, []*types.Receipt, uint64, int, error) {
|
func (oracle *Oracle) resolveBlockRange(ctx context.Context, reqEnd rpc.BlockNumber, blocks int) (*types.Block, []*types.Receipt, uint64, int, error) {
|
||||||
var (
|
var (
|
||||||
headBlock rpc.BlockNumber
|
headBlock *types.Header
|
||||||
pendingBlock *types.Block
|
pendingBlock *types.Block
|
||||||
pendingReceipts types.Receipts
|
pendingReceipts types.Receipts
|
||||||
|
err error
|
||||||
)
|
)
|
||||||
// query either pending block or head header and set headBlock
|
|
||||||
if lastBlock == rpc.PendingBlockNumber {
|
// Get the chain's current head.
|
||||||
|
if headBlock, err = oracle.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber); err != nil {
|
||||||
|
return nil, nil, 0, 0, err
|
||||||
|
}
|
||||||
|
head := rpc.BlockNumber(headBlock.Number.Uint64())
|
||||||
|
|
||||||
|
// Fail if request block is beyond the chain's current head.
|
||||||
|
if head < reqEnd {
|
||||||
|
return nil, nil, 0, 0, fmt.Errorf("%w: requested %d, head %d", errRequestBeyondHead, reqEnd, head)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve block tag.
|
||||||
|
if reqEnd < 0 {
|
||||||
|
var (
|
||||||
|
resolved *types.Header
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
switch reqEnd {
|
||||||
|
case rpc.PendingBlockNumber:
|
||||||
if pendingBlock, pendingReceipts = oracle.backend.PendingBlockAndReceipts(); pendingBlock != nil {
|
if pendingBlock, pendingReceipts = oracle.backend.PendingBlockAndReceipts(); pendingBlock != nil {
|
||||||
lastBlock = rpc.BlockNumber(pendingBlock.NumberU64())
|
resolved = pendingBlock.Header()
|
||||||
headBlock = lastBlock - 1
|
|
||||||
} else {
|
} else {
|
||||||
// pending block not supported by backend, process until latest block
|
// Pending block not supported by backend, process only until latest block.
|
||||||
lastBlock = rpc.LatestBlockNumber
|
resolved = headBlock
|
||||||
|
|
||||||
|
// Update total blocks to return to account for this.
|
||||||
blocks--
|
blocks--
|
||||||
|
}
|
||||||
|
case rpc.LatestBlockNumber:
|
||||||
|
// Retrieved above.
|
||||||
|
resolved = headBlock
|
||||||
|
case rpc.SafeBlockNumber:
|
||||||
|
resolved, err = oracle.backend.HeaderByNumber(ctx, rpc.SafeBlockNumber)
|
||||||
|
case rpc.FinalizedBlockNumber:
|
||||||
|
resolved, err = oracle.backend.HeaderByNumber(ctx, rpc.FinalizedBlockNumber)
|
||||||
|
case rpc.EarliestBlockNumber:
|
||||||
|
resolved, err = oracle.backend.HeaderByNumber(ctx, rpc.EarliestBlockNumber)
|
||||||
|
}
|
||||||
|
if resolved == nil || err != nil {
|
||||||
|
return nil, nil, 0, 0, err
|
||||||
|
}
|
||||||
|
// Absolute number resolved.
|
||||||
|
reqEnd = rpc.BlockNumber(resolved.Number.Uint64())
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are no blocks to return, short circuit.
|
||||||
if blocks == 0 {
|
if blocks == 0 {
|
||||||
return nil, nil, 0, 0, nil
|
return nil, nil, 0, 0, nil
|
||||||
}
|
}
|
||||||
|
// Ensure not trying to retrieve before genesis.
|
||||||
|
if int(reqEnd+1) < blocks {
|
||||||
|
blocks = int(reqEnd + 1)
|
||||||
}
|
}
|
||||||
}
|
return pendingBlock, pendingReceipts, uint64(reqEnd), blocks, nil
|
||||||
if pendingBlock == nil {
|
|
||||||
// if pending block is not fetched then we retrieve the head header to get the head block number
|
|
||||||
if latestHeader, err := oracle.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber); err == nil {
|
|
||||||
headBlock = rpc.BlockNumber(latestHeader.Number.Uint64())
|
|
||||||
} else {
|
|
||||||
return nil, nil, 0, 0, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if lastBlock == rpc.LatestBlockNumber {
|
|
||||||
lastBlock = headBlock
|
|
||||||
} else if pendingBlock == nil && lastBlock > headBlock {
|
|
||||||
return nil, nil, 0, 0, fmt.Errorf("%w: requested %d, head %d", errRequestBeyondHead, lastBlock, headBlock)
|
|
||||||
}
|
|
||||||
// ensure not trying to retrieve before genesis
|
|
||||||
if rpc.BlockNumber(blocks) > lastBlock+1 {
|
|
||||||
blocks = int(lastBlock + 1)
|
|
||||||
}
|
|
||||||
return pendingBlock, pendingReceipts, uint64(lastBlock), blocks, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FeeHistory returns data relevant for fee estimation based on the specified range of blocks.
|
// FeeHistory returns data relevant for fee estimation based on the specified range of blocks.
|
||||||
|
@ -50,6 +50,8 @@ func TestFeeHistory(t *testing.T) {
|
|||||||
{false, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 1, nil},
|
{false, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 1, nil},
|
||||||
{true, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 2, nil},
|
{true, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 2, nil},
|
||||||
{true, 1000, 1000, 2, rpc.PendingBlockNumber, []float64{0, 10}, 32, 2, nil},
|
{true, 1000, 1000, 2, rpc.PendingBlockNumber, []float64{0, 10}, 32, 2, nil},
|
||||||
|
{false, 1000, 1000, 2, rpc.FinalizedBlockNumber, []float64{0, 10}, 24, 2, nil},
|
||||||
|
{false, 1000, 1000, 2, rpc.SafeBlockNumber, []float64{0, 10}, 24, 2, nil},
|
||||||
}
|
}
|
||||||
for i, c := range cases {
|
for i, c := range cases {
|
||||||
config := Config{
|
config := Config{
|
||||||
|
@ -45,6 +45,15 @@ func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber
|
|||||||
if number > testHead {
|
if number > testHead {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
if number == rpc.EarliestBlockNumber {
|
||||||
|
number = 0
|
||||||
|
}
|
||||||
|
if number == rpc.FinalizedBlockNumber {
|
||||||
|
return b.chain.CurrentFinalizedBlock().Header(), nil
|
||||||
|
}
|
||||||
|
if number == rpc.SafeBlockNumber {
|
||||||
|
return b.chain.CurrentSafeBlock().Header(), nil
|
||||||
|
}
|
||||||
if number == rpc.LatestBlockNumber {
|
if number == rpc.LatestBlockNumber {
|
||||||
number = testHead
|
number = testHead
|
||||||
}
|
}
|
||||||
@ -62,6 +71,15 @@ func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber)
|
|||||||
if number > testHead {
|
if number > testHead {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
if number == rpc.EarliestBlockNumber {
|
||||||
|
number = 0
|
||||||
|
}
|
||||||
|
if number == rpc.FinalizedBlockNumber {
|
||||||
|
return b.chain.CurrentFinalizedBlock(), nil
|
||||||
|
}
|
||||||
|
if number == rpc.SafeBlockNumber {
|
||||||
|
return b.chain.CurrentSafeBlock(), nil
|
||||||
|
}
|
||||||
if number == rpc.LatestBlockNumber {
|
if number == rpc.LatestBlockNumber {
|
||||||
number = testHead
|
number = testHead
|
||||||
}
|
}
|
||||||
@ -109,6 +127,7 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke
|
|||||||
config.LondonBlock = londonBlock
|
config.LondonBlock = londonBlock
|
||||||
config.ArrowGlacierBlock = londonBlock
|
config.ArrowGlacierBlock = londonBlock
|
||||||
config.GrayGlacierBlock = londonBlock
|
config.GrayGlacierBlock = londonBlock
|
||||||
|
config.TerminalTotalDifficulty = common.Big0
|
||||||
engine := ethash.NewFaker()
|
engine := ethash.NewFaker()
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
genesis, err := gspec.Commit(db)
|
genesis, err := gspec.Commit(db)
|
||||||
@ -150,6 +169,8 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke
|
|||||||
t.Fatalf("Failed to create local chain, %v", err)
|
t.Fatalf("Failed to create local chain, %v", err)
|
||||||
}
|
}
|
||||||
chain.InsertChain(blocks)
|
chain.InsertChain(blocks)
|
||||||
|
chain.SetFinalized(chain.GetBlockByNumber(25))
|
||||||
|
chain.SetSafe(chain.GetBlockByNumber(25))
|
||||||
return &testBackend{chain: chain, pending: pending}
|
return &testBackend{chain: chain, pending: pending}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user