core, eth, internal, les: RPC methods and fields for EIP 1559 (#22964)

* internal/ethapi: add baseFee to RPCMarshalHeader

* internal/ethapi: add FeeCap, Tip and correct GasPrice to EIP-1559 RPCTransaction results

* core,eth,les,internal: add support for tip estimation in gas price oracle

* internal/ethapi,eth/gasprice: don't suggest tip larger than fee cap

* core/types,internal: use correct eip1559 terminology for json marshalling

* eth, internal/ethapi: fix rebase problems

* internal/ethapi: fix rpc name of basefee

* internal/ethapi: address review concerns

* core, eth, internal, les: simplify gasprice oracle (#25)

* core, eth, internal, les: simplify gasprice oracle

* eth/gasprice: fix typo

* internal/ethapi: minor tweak in tx args

* internal/ethapi: calculate basefee for pending block

* internal/ethapi: fix panic

* internal/ethapi, eth/tracers: simplify txargs ToMessage

* internal/ethapi: remove unused param

* core, eth, internal: fix regressions wrt effective gas price in the evm

* eth/gasprice: drop weird debug println

* internal/jsre/deps: hack in 1559 gas conversions into embedded web3

* internal/jsre/deps: hack basFee to decimal conversion

* internal/ethapi: init feecap and tipcap for legacy txs too

* eth, graphql, internal, les: fix gas price suggestion on all combos

* internal/jsre/deps: handle decimal tipcap and feecap

* eth, internal: minor review fixes

* graphql, internal: export max fee cap RPC endpoint

* internal/ethapi: fix crash in transaction_args

* internal/ethapi: minor refactor to make the code safer

Co-authored-by: Ryan Schneider <ryanleeschneider@gmail.com>
Co-authored-by: lightclient@protonmail.com <lightclient@protonmail.com>
Co-authored-by: gary rong <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
This commit is contained in:
Martin Holst Swende
2021-06-02 15:13:10 +02:00
committed by GitHub
parent 2dee31930c
commit 5cff9754d7
19 changed files with 410 additions and 159 deletions

View File

@@ -55,7 +55,7 @@ func (b *testBackend) ChainConfig() *params.ChainConfig {
return b.chain.Config()
}
func newTestBackend(t *testing.T) *testBackend {
func newTestBackend(t *testing.T, londonBlock *big.Int) *testBackend {
var (
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr = crypto.PubkeyToAddress(key.PublicKey)
@@ -65,14 +65,42 @@ func newTestBackend(t *testing.T) *testBackend {
}
signer = types.LatestSigner(gspec.Config)
)
if londonBlock != nil {
gspec.Config.LondonBlock = londonBlock
signer = types.LatestSigner(gspec.Config)
}
engine := ethash.NewFaker()
db := rawdb.NewMemoryDatabase()
genesis, _ := gspec.Commit(db)
// Generate testing blocks
blocks, _ := core.GenerateChain(params.TestChainConfig, genesis, engine, db, 32, func(i int, b *core.BlockGen) {
blocks, _ := core.GenerateChain(gspec.Config, genesis, engine, db, 32, func(i int, b *core.BlockGen) {
b.SetCoinbase(common.Address{1})
tx, err := types.SignTx(types.NewTransaction(b.TxNonce(addr), common.HexToAddress("deadbeef"), big.NewInt(100), 21000, big.NewInt(int64(i+1)*params.GWei), nil), signer, key)
var tx *types.Transaction
if londonBlock != nil && b.Number().Cmp(londonBlock) >= 0 {
txdata := &types.DynamicFeeTx{
ChainID: gspec.Config.ChainID,
Nonce: b.TxNonce(addr),
To: &common.Address{},
Gas: 30000,
FeeCap: big.NewInt(100 * params.GWei),
Tip: big.NewInt(int64(i+1) * params.GWei),
Data: []byte{},
}
tx = types.NewTx(txdata)
} else {
txdata := &types.LegacyTx{
Nonce: b.TxNonce(addr),
To: &common.Address{},
Gas: 21000,
GasPrice: big.NewInt(int64(i+1) * params.GWei),
Value: big.NewInt(100),
Data: []byte{},
}
tx = types.NewTx(txdata)
}
tx, err := types.SignTx(tx, signer, key)
if err != nil {
t.Fatalf("failed to create tx: %v", err)
}
@@ -81,7 +109,7 @@ func newTestBackend(t *testing.T) *testBackend {
// Construct testing chain
diskdb := rawdb.NewMemoryDatabase()
gspec.Commit(diskdb)
chain, err := core.NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
chain, err := core.NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil)
if err != nil {
t.Fatalf("Failed to create local chain, %v", err)
}
@@ -97,22 +125,33 @@ func (b *testBackend) GetBlockByNumber(number uint64) *types.Block {
return b.chain.GetBlockByNumber(number)
}
func TestSuggestPrice(t *testing.T) {
func TestSuggestTipCap(t *testing.T) {
config := Config{
Blocks: 3,
Percentile: 60,
Default: big.NewInt(params.GWei),
}
backend := newTestBackend(t)
oracle := NewOracle(backend, config)
// The gas price sampled is: 32G, 31G, 30G, 29G, 28G, 27G
got, err := oracle.SuggestPrice(context.Background())
if err != nil {
t.Fatalf("Failed to retrieve recommended gas price: %v", err)
var cases = []struct {
fork *big.Int // London fork number
expect *big.Int // Expected gasprice suggestion
}{
{nil, big.NewInt(params.GWei * int64(30))},
{big.NewInt(0), big.NewInt(params.GWei * int64(30))}, // Fork point in genesis
{big.NewInt(1), big.NewInt(params.GWei * int64(30))}, // Fork point in first block
{big.NewInt(32), big.NewInt(params.GWei * int64(30))}, // Fork point in last block
{big.NewInt(33), big.NewInt(params.GWei * int64(30))}, // Fork point in the future
}
expect := big.NewInt(params.GWei * int64(30))
if got.Cmp(expect) != 0 {
t.Fatalf("Gas price mismatch, want %d, got %d", expect, got)
for _, c := range cases {
backend := newTestBackend(t, c.fork)
oracle := NewOracle(backend, config)
// The gas price sampled is: 32G, 31G, 30G, 29G, 28G, 27G
got, err := oracle.SuggestTipCap(context.Background())
if err != nil {
t.Fatalf("Failed to retrieve recommended gas price: %v", err)
}
if got.Cmp(c.expect) != 0 {
t.Fatalf("Gas price mismatch, want %d, got %d", c.expect, got)
}
}
}