mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 02:42:27 +00:00
eth,internal: Add blob results to eth_feeHistory RPC
This commit is contained in:
parent
492ca8b76b
commit
4fdde0f956
7 changed files with 159 additions and 36 deletions
|
|
@ -362,7 +362,7 @@ func (b *EthAPIBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error)
|
||||||
return b.gpo.SuggestTipCap(ctx)
|
return b.gpo.SuggestTipCap(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthAPIBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (firstBlock *big.Int, reward [][]*big.Int, baseFee []*big.Int, gasUsedRatio []float64, err error) {
|
func (b *EthAPIBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (firstBlock *big.Int, reward [][]*big.Int, baseFee []*big.Int, gasUsedRatio []float64, baseFeePerBlobGas []*big.Int, blobGasUsedRatio []float64, err error) {
|
||||||
return b.gpo.FeeHistory(ctx, blockCount, lastBlock, rewardPercentiles)
|
return b.gpo.FeeHistory(ctx, blockCount, lastBlock, rewardPercentiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,14 @@ import (
|
||||||
"slices"
|
"slices"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -66,6 +70,8 @@ type processedFees struct {
|
||||||
reward []*big.Int
|
reward []*big.Int
|
||||||
baseFee, nextBaseFee *big.Int
|
baseFee, nextBaseFee *big.Int
|
||||||
gasUsedRatio float64
|
gasUsedRatio float64
|
||||||
|
blobGasUsedRatio float64
|
||||||
|
blobBaseFee *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// txGasAndReward is sorted in ascending order based on reward
|
// txGasAndReward is sorted in ascending order based on reward
|
||||||
|
|
@ -88,6 +94,16 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
|
||||||
bf.results.nextBaseFee = new(big.Int)
|
bf.results.nextBaseFee = new(big.Int)
|
||||||
}
|
}
|
||||||
bf.results.gasUsedRatio = float64(bf.header.GasUsed) / float64(bf.header.GasLimit)
|
bf.results.gasUsedRatio = float64(bf.header.GasUsed) / float64(bf.header.GasLimit)
|
||||||
|
bf.results.blobGasUsedRatio = 0.0
|
||||||
|
bf.results.blobBaseFee = new(big.Int)
|
||||||
|
if bf.header != nil && chainconfig.IsCancun(bf.header.Number, bf.header.Time) {
|
||||||
|
if blobGasUsed := bf.header.BlobGasUsed; blobGasUsed != nil {
|
||||||
|
bf.results.blobGasUsedRatio = float64(*blobGasUsed) / params.MaxBlobGasPerBlock
|
||||||
|
}
|
||||||
|
if excessBlobGas := bf.header.ExcessBlobGas; excessBlobGas != nil {
|
||||||
|
bf.results.blobBaseFee = eip4844.CalcBlobFee(*excessBlobGas)
|
||||||
|
}
|
||||||
|
}
|
||||||
if len(percentiles) == 0 {
|
if len(percentiles) == 0 {
|
||||||
// rewards were not requested, return null
|
// rewards were not requested, return null
|
||||||
return
|
return
|
||||||
|
|
@ -211,9 +227,9 @@ func (oracle *Oracle) resolveBlockRange(ctx context.Context, reqEnd rpc.BlockNum
|
||||||
//
|
//
|
||||||
// Note: baseFee includes the next block after the newest of the returned range, because this
|
// Note: baseFee includes the next block after the newest of the returned range, because this
|
||||||
// value can be derived from the newest block.
|
// value can be derived from the newest block.
|
||||||
func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedLastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) {
|
func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedLastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, []*big.Int, []float64, error) {
|
||||||
if blocks < 1 {
|
if blocks < 1 {
|
||||||
return common.Big0, nil, nil, nil, nil // returning with no data and no error means there are no retrievable blocks
|
return common.Big0, nil, nil, nil, nil, nil, nil // returning with no data and no error means there are no retrievable blocks
|
||||||
}
|
}
|
||||||
maxFeeHistory := oracle.maxHeaderHistory
|
maxFeeHistory := oracle.maxHeaderHistory
|
||||||
if len(rewardPercentiles) != 0 {
|
if len(rewardPercentiles) != 0 {
|
||||||
|
|
@ -225,10 +241,10 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL
|
||||||
}
|
}
|
||||||
for i, p := range rewardPercentiles {
|
for i, p := range rewardPercentiles {
|
||||||
if p < 0 || p > 100 {
|
if p < 0 || p > 100 {
|
||||||
return common.Big0, nil, nil, nil, fmt.Errorf("%w: %f", errInvalidPercentile, p)
|
return common.Big0, nil, nil, nil, nil, nil, fmt.Errorf("%w: %f", errInvalidPercentile, p)
|
||||||
}
|
}
|
||||||
if i > 0 && p <= rewardPercentiles[i-1] {
|
if i > 0 && p <= rewardPercentiles[i-1] {
|
||||||
return common.Big0, nil, nil, nil, fmt.Errorf("%w: #%d:%f >= #%d:%f", errInvalidPercentile, i-1, rewardPercentiles[i-1], i, p)
|
return common.Big0, nil, nil, nil, nil, nil, fmt.Errorf("%w: #%d:%f >= #%d:%f", errInvalidPercentile, i-1, rewardPercentiles[i-1], i, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
|
|
@ -238,7 +254,7 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL
|
||||||
)
|
)
|
||||||
pendingBlock, pendingReceipts, lastBlock, blocks, err := oracle.resolveBlockRange(ctx, unresolvedLastBlock, blocks)
|
pendingBlock, pendingReceipts, lastBlock, blocks, err := oracle.resolveBlockRange(ctx, unresolvedLastBlock, blocks)
|
||||||
if err != nil || blocks == 0 {
|
if err != nil || blocks == 0 {
|
||||||
return common.Big0, nil, nil, nil, err
|
return common.Big0, nil, nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
oldestBlock := lastBlock + 1 - blocks
|
oldestBlock := lastBlock + 1 - blocks
|
||||||
|
|
||||||
|
|
@ -295,19 +311,22 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
reward = make([][]*big.Int, blocks)
|
reward = make([][]*big.Int, blocks)
|
||||||
baseFee = make([]*big.Int, blocks+1)
|
baseFee = make([]*big.Int, blocks+1)
|
||||||
gasUsedRatio = make([]float64, blocks)
|
gasUsedRatio = make([]float64, blocks)
|
||||||
firstMissing = blocks
|
blobGasUsedRatio = make([]float64, blocks)
|
||||||
|
blobBaseFee = make([]*big.Int, blocks)
|
||||||
|
firstMissing = blocks
|
||||||
)
|
)
|
||||||
for ; blocks > 0; blocks-- {
|
for ; blocks > 0; blocks-- {
|
||||||
fees := <-results
|
fees := <-results
|
||||||
if fees.err != nil {
|
if fees.err != nil {
|
||||||
return common.Big0, nil, nil, nil, fees.err
|
return common.Big0, nil, nil, nil, nil, nil, fees.err
|
||||||
}
|
}
|
||||||
i := fees.blockNumber - oldestBlock
|
i := fees.blockNumber - oldestBlock
|
||||||
if fees.results.baseFee != nil {
|
if fees.results.baseFee != nil {
|
||||||
reward[i], baseFee[i], baseFee[i+1], gasUsedRatio[i] = fees.results.reward, fees.results.baseFee, fees.results.nextBaseFee, fees.results.gasUsedRatio
|
reward[i], baseFee[i], baseFee[i+1], gasUsedRatio[i] = fees.results.reward, fees.results.baseFee, fees.results.nextBaseFee, fees.results.gasUsedRatio
|
||||||
|
blobGasUsedRatio[i], blobBaseFee[i] = fees.results.blobGasUsedRatio, fees.results.blobBaseFee
|
||||||
} else {
|
} else {
|
||||||
// getting no block and no error means we are requesting into the future (might happen because of a reorg)
|
// getting no block and no error means we are requesting into the future (might happen because of a reorg)
|
||||||
if i < firstMissing {
|
if i < firstMissing {
|
||||||
|
|
@ -316,7 +335,7 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if firstMissing == 0 {
|
if firstMissing == 0 {
|
||||||
return common.Big0, nil, nil, nil, nil
|
return common.Big0, nil, nil, nil, nil, nil, nil
|
||||||
}
|
}
|
||||||
if len(rewardPercentiles) != 0 {
|
if len(rewardPercentiles) != 0 {
|
||||||
reward = reward[:firstMissing]
|
reward = reward[:firstMissing]
|
||||||
|
|
@ -324,5 +343,5 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedL
|
||||||
reward = nil
|
reward = nil
|
||||||
}
|
}
|
||||||
baseFee, gasUsedRatio = baseFee[:firstMissing+1], gasUsedRatio[:firstMissing]
|
baseFee, gasUsedRatio = baseFee[:firstMissing+1], gasUsedRatio[:firstMissing]
|
||||||
return new(big.Int).SetUint64(oldestBlock), reward, baseFee, gasUsedRatio, nil
|
return new(big.Int).SetUint64(oldestBlock), reward, baseFee, gasUsedRatio, blobBaseFee, blobGasUsedRatio, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,10 +58,10 @@ func TestFeeHistory(t *testing.T) {
|
||||||
MaxHeaderHistory: c.maxHeader,
|
MaxHeaderHistory: c.maxHeader,
|
||||||
MaxBlockHistory: c.maxBlock,
|
MaxBlockHistory: c.maxBlock,
|
||||||
}
|
}
|
||||||
backend := newTestBackend(t, big.NewInt(16), c.pending)
|
backend := newTestBackend(t, big.NewInt(16), c.pending, true)
|
||||||
oracle := NewOracle(backend, config)
|
oracle := NewOracle(backend, config)
|
||||||
|
|
||||||
first, reward, baseFee, ratio, err := oracle.FeeHistory(context.Background(), c.count, c.last, c.percent)
|
first, reward, baseFee, ratio, blobBaseFee, blobUsed, err := oracle.FeeHistory(context.Background(), c.count, c.last, c.percent)
|
||||||
backend.teardown()
|
backend.teardown()
|
||||||
expReward := c.expCount
|
expReward := c.expCount
|
||||||
if len(c.percent) == 0 {
|
if len(c.percent) == 0 {
|
||||||
|
|
@ -84,6 +84,9 @@ func TestFeeHistory(t *testing.T) {
|
||||||
if len(ratio) != c.expCount {
|
if len(ratio) != c.expCount {
|
||||||
t.Fatalf("Test case %d: gasUsedRatio array length mismatch, want %d, got %d", i, c.expCount, len(ratio))
|
t.Fatalf("Test case %d: gasUsedRatio array length mismatch, want %d, got %d", i, c.expCount, len(ratio))
|
||||||
}
|
}
|
||||||
|
if len(blobBaseFee) != len(blobUsed) || len(blobBaseFee) != c.expCount {
|
||||||
|
t.Fatalf("Test case %d: blob arrays length mismatch, want %d, got %d and %d", i, c.expCount, len(blobBaseFee), len(blobUsed))
|
||||||
|
}
|
||||||
if err != c.expErr && !errors.Is(err, c.expErr) {
|
if err != c.expErr && !errors.Is(err, c.expErr) {
|
||||||
t.Fatalf("Test case %d: error mismatch, want %v, got %v", i, c.expErr, err)
|
t.Fatalf("Test case %d: error mismatch, want %v, got %v", i, c.expErr, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,18 @@ package gasprice
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/sha256"
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/holiman/uint256"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/beacon"
|
||||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
|
@ -30,6 +37,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
|
@ -121,7 +129,7 @@ func (b *testBackend) teardown() {
|
||||||
|
|
||||||
// newTestBackend creates a test backend. OBS: don't forget to invoke tearDown
|
// newTestBackend creates a test backend. OBS: don't forget to invoke tearDown
|
||||||
// after use, otherwise the blockchain instance will mem-leak via goroutines.
|
// after use, otherwise the blockchain instance will mem-leak via goroutines.
|
||||||
func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBackend {
|
func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool, addCancunBlocks bool) *testBackend {
|
||||||
var (
|
var (
|
||||||
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
addr = crypto.PubkeyToAddress(key.PublicKey)
|
addr = crypto.PubkeyToAddress(key.PublicKey)
|
||||||
|
|
@ -130,17 +138,32 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke
|
||||||
Config: &config,
|
Config: &config,
|
||||||
Alloc: types.GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}},
|
Alloc: types.GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}},
|
||||||
}
|
}
|
||||||
signer = types.LatestSigner(gspec.Config)
|
signer = types.LatestSigner(gspec.Config)
|
||||||
|
blobSigners = [6]struct {
|
||||||
|
key *ecdsa.PrivateKey
|
||||||
|
addr common.Address
|
||||||
|
}{}
|
||||||
)
|
)
|
||||||
config.LondonBlock = londonBlock
|
config.LondonBlock = londonBlock
|
||||||
config.ArrowGlacierBlock = londonBlock
|
config.ArrowGlacierBlock = londonBlock
|
||||||
config.GrayGlacierBlock = londonBlock
|
config.GrayGlacierBlock = londonBlock
|
||||||
config.TerminalTotalDifficulty = common.Big0
|
var engine consensus.Engine = beacon.New(ethash.NewFaker())
|
||||||
engine := ethash.NewFaker()
|
td := int(params.GenesisDifficulty.Uint64())
|
||||||
|
|
||||||
|
if addCancunBlocks {
|
||||||
|
for i := range blobSigners {
|
||||||
|
key, _ := crypto.GenerateKey()
|
||||||
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
|
blobSigners[i].key = key
|
||||||
|
blobSigners[i].addr = addr
|
||||||
|
gspec.Alloc[addr] = types.Account{Balance: big.NewInt(math.MaxInt64)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Generate testing blocks
|
// Generate testing blocks
|
||||||
_, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, testHead+1, func(i int, b *core.BlockGen) {
|
genDb, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, testHead+1, func(i int, b *core.BlockGen) {
|
||||||
b.SetCoinbase(common.Address{1})
|
b.SetCoinbase(common.Address{1})
|
||||||
|
td += int(b.Difficulty().Uint64())
|
||||||
|
|
||||||
var txdata types.TxData
|
var txdata types.TxData
|
||||||
if londonBlock != nil && b.Number().Cmp(londonBlock) >= 0 {
|
if londonBlock != nil && b.Number().Cmp(londonBlock) >= 0 {
|
||||||
|
|
@ -166,13 +189,78 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke
|
||||||
b.AddTx(types.MustSignNewTx(key, signer, txdata))
|
b.AddTx(types.MustSignNewTx(key, signer, txdata))
|
||||||
})
|
})
|
||||||
// Construct testing chain
|
// Construct testing chain
|
||||||
chain, err := core.NewBlockChain(rawdb.NewMemoryDatabase(), &core.CacheConfig{TrieCleanNoPrefetch: true}, gspec, nil, engine, vm.Config{}, nil, nil)
|
db := rawdb.NewMemoryDatabase()
|
||||||
|
merger := consensus.NewMerger(db)
|
||||||
|
chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieCleanNoPrefetch: true}, gspec, nil, engine, vm.Config{}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create local chain, %v", err)
|
t.Fatalf("Failed to create local chain, %v", err)
|
||||||
}
|
}
|
||||||
chain.InsertChain(blocks)
|
if i, err := chain.InsertChain(blocks); err != nil {
|
||||||
|
panic(fmt.Errorf("error inserting block %d: %w", i, err))
|
||||||
|
}
|
||||||
chain.SetFinalized(chain.GetBlockByNumber(25).Header())
|
chain.SetFinalized(chain.GetBlockByNumber(25).Header())
|
||||||
chain.SetSafe(chain.GetBlockByNumber(25).Header())
|
chain.SetSafe(chain.GetBlockByNumber(25).Header())
|
||||||
|
|
||||||
|
if addCancunBlocks {
|
||||||
|
if err := chain.SetHead(26); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
head := chain.GetBlockByNumber(26)
|
||||||
|
ts := head.Time()
|
||||||
|
config.ShanghaiTime = &ts
|
||||||
|
config.CancunTime = &ts
|
||||||
|
ttd := chain.GetTd(head.Hash(), head.NumberU64())
|
||||||
|
config.TerminalTotalDifficulty = ttd
|
||||||
|
signer = types.LatestSigner(gspec.Config)
|
||||||
|
|
||||||
|
merger.ReachTTD()
|
||||||
|
merger.FinalizePoS()
|
||||||
|
|
||||||
|
var (
|
||||||
|
emptyBlob = kzg4844.Blob{}
|
||||||
|
emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob)
|
||||||
|
emptyBlobVHash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit)
|
||||||
|
)
|
||||||
|
|
||||||
|
postBlocks, _ := core.GenerateChain(gspec.Config, head, engine, genDb, 6+1, func(i int, b *core.BlockGen) {
|
||||||
|
b.SetPoS()
|
||||||
|
|
||||||
|
txdata := &types.DynamicFeeTx{
|
||||||
|
ChainID: gspec.Config.ChainID,
|
||||||
|
Nonce: b.TxNonce(addr),
|
||||||
|
To: &common.Address{},
|
||||||
|
Gas: 30000,
|
||||||
|
GasFeeCap: big.NewInt(100 * params.GWei),
|
||||||
|
GasTipCap: big.NewInt(int64(i+1) * params.GWei),
|
||||||
|
Data: []byte{},
|
||||||
|
}
|
||||||
|
b.AddTx(types.MustSignNewTx(key, signer, txdata))
|
||||||
|
|
||||||
|
// put more blobs in each new block
|
||||||
|
for j := 0; j < i && j < 6; j++ {
|
||||||
|
blobTx := &types.BlobTx{
|
||||||
|
ChainID: uint256.MustFromBig(gspec.Config.ChainID),
|
||||||
|
Nonce: b.TxNonce(blobSigners[j].addr),
|
||||||
|
To: common.Address{},
|
||||||
|
Gas: 30000,
|
||||||
|
GasFeeCap: uint256.NewInt(100 * params.GWei),
|
||||||
|
GasTipCap: uint256.NewInt(uint64(i+1) * params.GWei),
|
||||||
|
Data: []byte{},
|
||||||
|
BlobFeeCap: uint256.NewInt(1),
|
||||||
|
BlobHashes: []common.Hash{emptyBlobVHash},
|
||||||
|
Value: uint256.NewInt(100),
|
||||||
|
Sidecar: nil,
|
||||||
|
}
|
||||||
|
b.AddTx(types.MustSignNewTx(blobSigners[j].key, signer, blobTx))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if i, err := chain.InsertChain(postBlocks); err != nil {
|
||||||
|
panic(fmt.Errorf("error inserting block %d: %w", i, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return &testBackend{chain: chain, pending: pending}
|
return &testBackend{chain: chain, pending: pending}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,7 +289,7 @@ func TestSuggestTipCap(t *testing.T) {
|
||||||
{big.NewInt(33), big.NewInt(params.GWei * int64(30))}, // Fork point in the future
|
{big.NewInt(33), big.NewInt(params.GWei * int64(30))}, // Fork point in the future
|
||||||
}
|
}
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
backend := newTestBackend(t, c.fork, false)
|
backend := newTestBackend(t, c.fork, false, false)
|
||||||
oracle := NewOracle(backend, config)
|
oracle := NewOracle(backend, config)
|
||||||
|
|
||||||
// The gas price sampled is: 32G, 31G, 30G, 29G, 28G, 27G
|
// The gas price sampled is: 32G, 31G, 30G, 29G, 28G, 27G
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
|
"github.com/tyler-smith/go-bip39"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||||
"github.com/ethereum/go-ethereum/accounts/scwallet"
|
"github.com/ethereum/go-ethereum/accounts/scwallet"
|
||||||
|
|
@ -48,8 +51,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"github.com/holiman/uint256"
|
|
||||||
"github.com/tyler-smith/go-bip39"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// estimateGasErrorRatio is the amount of overestimation eth_estimateGas is
|
// estimateGasErrorRatio is the amount of overestimation eth_estimateGas is
|
||||||
|
|
@ -90,15 +91,17 @@ func (s *EthereumAPI) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, e
|
||||||
}
|
}
|
||||||
|
|
||||||
type feeHistoryResult struct {
|
type feeHistoryResult struct {
|
||||||
OldestBlock *hexutil.Big `json:"oldestBlock"`
|
OldestBlock *hexutil.Big `json:"oldestBlock"`
|
||||||
Reward [][]*hexutil.Big `json:"reward,omitempty"`
|
Reward [][]*hexutil.Big `json:"reward,omitempty"`
|
||||||
BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"`
|
BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"`
|
||||||
GasUsedRatio []float64 `json:"gasUsedRatio"`
|
GasUsedRatio []float64 `json:"gasUsedRatio"`
|
||||||
|
BlobBaseFee []*hexutil.Big `json:"baseFeePerBlobGas,omitempty"`
|
||||||
|
BlobGasUsedRatio []float64 `json:"blobGasUsedRatio,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FeeHistory returns the fee market history.
|
// FeeHistory returns the fee market history.
|
||||||
func (s *EthereumAPI) FeeHistory(ctx context.Context, blockCount math.HexOrDecimal64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*feeHistoryResult, error) {
|
func (s *EthereumAPI) FeeHistory(ctx context.Context, blockCount math.HexOrDecimal64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*feeHistoryResult, error) {
|
||||||
oldest, reward, baseFee, gasUsed, err := s.b.FeeHistory(ctx, uint64(blockCount), lastBlock, rewardPercentiles)
|
oldest, reward, baseFee, gasUsed, blobBaseFee, blobGasUsed, err := s.b.FeeHistory(ctx, uint64(blockCount), lastBlock, rewardPercentiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -121,6 +124,15 @@ func (s *EthereumAPI) FeeHistory(ctx context.Context, blockCount math.HexOrDecim
|
||||||
results.BaseFee[i] = (*hexutil.Big)(v)
|
results.BaseFee[i] = (*hexutil.Big)(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if blobBaseFee != nil {
|
||||||
|
results.BlobBaseFee = make([]*hexutil.Big, len(blobBaseFee))
|
||||||
|
for i, v := range blobBaseFee {
|
||||||
|
results.BlobBaseFee[i] = (*hexutil.Big)(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if blobGasUsed != nil {
|
||||||
|
results.BlobGasUsedRatio = blobGasUsed
|
||||||
|
}
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/holiman/uint256"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum"
|
"github.com/ethereum/go-ethereum"
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||||
|
|
@ -53,8 +56,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/internal/blocktest"
|
"github.com/ethereum/go-ethereum/internal/blocktest"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/holiman/uint256"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func testTransactionMarshal(t *testing.T, tests []txData, config *params.ChainConfig) {
|
func testTransactionMarshal(t *testing.T, tests []txData, config *params.ChainConfig) {
|
||||||
|
|
@ -468,8 +469,8 @@ func (b testBackend) SyncProgress() ethereum.SyncProgress { return ethereum.Sync
|
||||||
func (b testBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
|
func (b testBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
|
||||||
return big.NewInt(0), nil
|
return big.NewInt(0), nil
|
||||||
}
|
}
|
||||||
func (b testBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) {
|
func (b testBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, []*big.Int, []float64, error) {
|
||||||
return nil, nil, nil, nil, nil
|
return nil, nil, nil, nil, nil, nil, nil
|
||||||
}
|
}
|
||||||
func (b testBackend) BlobBaseFee(ctx context.Context) (*big.Int, error) { return big.NewInt(0), nil }
|
func (b testBackend) BlobBaseFee(ctx context.Context) (*big.Int, error) { return big.NewInt(0), nil }
|
||||||
func (b testBackend) ChainDb() ethdb.Database { return b.db }
|
func (b testBackend) ChainDb() ethdb.Database { return b.db }
|
||||||
|
|
|
||||||
|
|
@ -319,8 +319,8 @@ func (b *backendMock) ChainConfig() *params.ChainConfig { return b.config }
|
||||||
|
|
||||||
// Other methods needed to implement Backend interface.
|
// Other methods needed to implement Backend interface.
|
||||||
func (b *backendMock) SyncProgress() ethereum.SyncProgress { return ethereum.SyncProgress{} }
|
func (b *backendMock) SyncProgress() ethereum.SyncProgress { return ethereum.SyncProgress{} }
|
||||||
func (b *backendMock) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) {
|
func (b *backendMock) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, []*big.Int, []float64, error) {
|
||||||
return nil, nil, nil, nil, nil
|
return nil, nil, nil, nil, nil, nil, nil
|
||||||
}
|
}
|
||||||
func (b *backendMock) BlobBaseFee(ctx context.Context) (*big.Int, error) {
|
func (b *backendMock) BlobBaseFee(ctx context.Context) (*big.Int, error) {
|
||||||
return big.NewInt(42), nil
|
return big.NewInt(42), nil
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue