From 3cc95c8c01ea4e9fb5fe7a363395501258bc9aeb Mon Sep 17 00:00:00 2001 From: b1m0n Date: Sun, 3 Dec 2023 15:02:04 +0700 Subject: [PATCH 1/2] [WIP] Remove ETH's clique and ethash consensuses --- consensus/clique/clique.go | 76 ------------------------------------- consensus/ethash/ethash.go | 52 ------------------------- core/genesis.go | 4 +- core/vm/gas_table_test.go | 2 +- eth/ethconfig/config.go | 29 +------------- eth/ethconfig/gen_config.go | 7 ---- evmcore/chain_makers.go | 2 +- params/config.go | 4 +- params/config_test.go | 8 ++-- u2u/rules.go | 2 +- 10 files changed, 12 insertions(+), 174 deletions(-) delete mode 100644 consensus/clique/clique.go delete mode 100644 consensus/ethash/ethash.go diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go deleted file mode 100644 index d4a8e555..00000000 --- a/consensus/clique/clique.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package clique implements the proof-of-authority consensus engine. -package clique - -import ( - "bytes" - "io" - - "github.com/unicornultrafoundation/go-u2u/common" - "github.com/unicornultrafoundation/go-u2u/core/types" - "github.com/unicornultrafoundation/go-u2u/crypto" - "github.com/unicornultrafoundation/go-u2u/rlp" - "golang.org/x/crypto/sha3" -) - -// SealHash returns the hash of a block prior to it being sealed. -func SealHash(header *types.Header) (hash common.Hash) { - hasher := sha3.NewLegacyKeccak256() - encodeSigHeader(hasher, header) - hasher.(crypto.KeccakState).Read(hash[:]) - return hash -} - -// CliqueRLP returns the rlp bytes which needs to be signed for the proof-of-authority -// sealing. The RLP to sign consists of the entire header apart from the 65 byte signature -// contained at the end of the extra data. -// -// Note, the method requires the extra data to be at least 65 bytes, otherwise it -// panics. This is done to avoid accidentally using both forms (signature present -// or not), which could be abused to produce different hashes for the same header. -func CliqueRLP(header *types.Header) []byte { - b := new(bytes.Buffer) - encodeSigHeader(b, header) - return b.Bytes() -} - -func encodeSigHeader(w io.Writer, header *types.Header) { - enc := []interface{}{ - header.ParentHash, - header.UncleHash, - header.Coinbase, - header.Root, - header.TxHash, - header.ReceiptHash, - header.Bloom, - header.Difficulty, - header.Number, - header.GasLimit, - header.GasUsed, - header.Time, - header.Extra[:len(header.Extra)-crypto.SignatureLength], // Yes, this will panic if extra is too short - header.MixDigest, - header.Nonce, - } - if header.BaseFee != nil { - enc = append(enc, header.BaseFee) - } - if err := rlp.Encode(w, enc); err != nil { - panic("can't encode: " + err.Error()) - } -} diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go deleted file mode 100644 index bbebfad8..00000000 --- a/consensus/ethash/ethash.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package ethash implements the ethash proof-of-work consensus engine. -package ethash - -import ( - "github.com/unicornultrafoundation/go-u2u/log" -) - -// Mode defines the type and amount of PoW verification an ethash engine makes. -type Mode uint - -const ( - ModeNormal Mode = iota - ModeShared - ModeTest - ModeFake - ModeFullFake -) - -// Config are the configuration parameters of the ethash. -type Config struct { - CacheDir string - CachesInMem int - CachesOnDisk int - CachesLockMmap bool - DatasetDir string - DatasetsInMem int - DatasetsOnDisk int - DatasetsLockMmap bool - PowMode Mode - - // When set, notifications sent by the remote sealer will - // be block header JSON objects instead of work package arrays. - NotifyFull bool - - Log log.Logger `toml:"-"` -} diff --git a/core/genesis.go b/core/genesis.go index 31cd0259..dda53ca9 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -102,7 +102,7 @@ func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) { } config := g.Config if config == nil { - config = params.AllEthashProtocolChanges + config = params.AllProtocolChanges } if err := config.CheckConfigForkOrder(); err != nil { return nil, err @@ -141,7 +141,7 @@ func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big func DeveloperGenesisBlock(faucet common.Address) *Genesis { // Assemble and return the genesis with the precompiles and faucet pre-funded return &Genesis{ - Config: params.AllEthashProtocolChanges, + Config: params.AllProtocolChanges, ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...), GasLimit: 11500000, BaseFee: big.NewInt(params.InitialBaseFee), diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go index ec5d0f3d..310fe5f5 100644 --- a/core/vm/gas_table_test.go +++ b/core/vm/gas_table_test.go @@ -91,7 +91,7 @@ func TestEIP2200(t *testing.T) { CanTransfer: func(StateDB, common.Address, *big.Int) bool { return true }, Transfer: func(StateDB, common.Address, common.Address, *big.Int) {}, } - vmenv := NewEVM(vmctx, TxContext{}, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}}) + vmenv := NewEVM(vmctx, TxContext{}, statedb, params.AllProtocolChanges, Config{ExtraEips: []int{2200}}) _, gas, err := vmenv.Call(AccountRef(common.Address{}), address, nil, tt.gaspool, new(big.Int)) if err != tt.failure { diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index e337f98f..c369b958 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -21,12 +21,9 @@ import ( "math/big" "os" "os/user" - "path/filepath" - "runtime" "time" "github.com/unicornultrafoundation/go-u2u/common" - "github.com/unicornultrafoundation/go-u2u/consensus/ethash" "github.com/unicornultrafoundation/go-u2u/core" "github.com/unicornultrafoundation/go-u2u/eth/downloader" "github.com/unicornultrafoundation/go-u2u/eth/gasprice" @@ -47,16 +44,7 @@ var FullNodeGPO = gasprice.Config{ // Defaults contains default settings for use on the Ethereum main net. var Defaults = Config{ - SyncMode: downloader.SnapSync, - Ethash: ethash.Config{ - CacheDir: "ethash", - CachesInMem: 2, - CachesOnDisk: 3, - CachesLockMmap: false, - DatasetsInMem: 1, - DatasetsOnDisk: 2, - DatasetsLockMmap: false, - }, + SyncMode: downloader.SnapSync, NetworkId: 1, TxLookupLimit: 2350000, LightPeers: 100, @@ -86,18 +74,6 @@ func init() { home = user.HomeDir } } - if runtime.GOOS == "darwin" { - Defaults.Ethash.DatasetDir = filepath.Join(home, "Library", "Ethash") - } else if runtime.GOOS == "windows" { - localappdata := os.Getenv("LOCALAPPDATA") - if localappdata != "" { - Defaults.Ethash.DatasetDir = filepath.Join(localappdata, "Ethash") - } else { - Defaults.Ethash.DatasetDir = filepath.Join(home, "AppData", "Local", "Ethash") - } - } else { - Defaults.Ethash.DatasetDir = filepath.Join(home, ".ethash") - } } //go:generate gencodec -type Config -formats toml -out gen_config.go @@ -156,9 +132,6 @@ type Config struct { // Mining options Miner miner.Config - // Ethash options - Ethash ethash.Config - // Transaction pool options TxPool evmcore.TxPoolConfig diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index f2692ced..dbc33105 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -8,7 +8,6 @@ import ( "github.com/unicornultrafoundation/go-u2u/evmcore" "github.com/unicornultrafoundation/go-u2u/common" - "github.com/unicornultrafoundation/go-u2u/consensus/ethash" "github.com/unicornultrafoundation/go-u2u/eth/downloader" "github.com/unicornultrafoundation/go-u2u/eth/gasprice" "github.com/unicornultrafoundation/go-u2u/miner" @@ -47,7 +46,6 @@ func (c Config) MarshalTOML() (interface{}, error) { SnapshotCache int Preimages bool Miner miner.Config - Ethash ethash.Config TxPool evmcore.TxPoolConfig GPO gasprice.Config EnablePreimageRecording bool @@ -87,7 +85,6 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.SnapshotCache = c.SnapshotCache enc.Preimages = c.Preimages enc.Miner = c.Miner - enc.Ethash = c.Ethash enc.TxPool = c.TxPool enc.GPO = c.GPO enc.EnablePreimageRecording = c.EnablePreimageRecording @@ -131,7 +128,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { SnapshotCache *int Preimages *bool Miner *miner.Config - Ethash *ethash.Config TxPool *evmcore.TxPoolConfig GPO *gasprice.Config EnablePreimageRecording *bool @@ -234,9 +230,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.Miner != nil { c.Miner = *dec.Miner } - if dec.Ethash != nil { - c.Ethash = *dec.Ethash - } if dec.TxPool != nil { c.TxPool = *dec.TxPool } diff --git a/evmcore/chain_makers.go b/evmcore/chain_makers.go index a8ae0bfc..8eef7e7d 100644 --- a/evmcore/chain_makers.go +++ b/evmcore/chain_makers.go @@ -187,7 +187,7 @@ func (b *BlockGen) OffsetTime(seconds int64) { // a similar non-validating proof of work implementation. func GenerateChain(config *params.ChainConfig, parent *EvmBlock, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*EvmBlock, []types.Receipts, DummyChain) { if config == nil { - config = params.AllEthashProtocolChanges + config = params.AllProtocolChanges } chain := &TestChain{ diff --git a/params/config.go b/params/config.go index 747a64c0..b099b1a8 100644 --- a/params/config.go +++ b/params/config.go @@ -24,12 +24,12 @@ import ( ) var ( - // AllEthashProtocolChanges contains every protocol change (EIPs) introduced + // AllProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Ethash consensus. // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil} + AllProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil} TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil} ) diff --git a/params/config_test.go b/params/config_test.go index 3c8ebaf4..a0b6098f 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -29,8 +29,8 @@ func TestCheckCompatible(t *testing.T) { wantErr *ConfigCompatError } tests := []test{ - {stored: AllEthashProtocolChanges, new: AllEthashProtocolChanges, head: 0, wantErr: nil}, - {stored: AllEthashProtocolChanges, new: AllEthashProtocolChanges, head: 100, wantErr: nil}, + {stored: AllProtocolChanges, new: AllProtocolChanges, head: 0, wantErr: nil}, + {stored: AllProtocolChanges, new: AllProtocolChanges, head: 100, wantErr: nil}, { stored: &ChainConfig{EIP150Block: big.NewInt(10)}, new: &ChainConfig{EIP150Block: big.NewInt(20)}, @@ -38,7 +38,7 @@ func TestCheckCompatible(t *testing.T) { wantErr: nil, }, { - stored: AllEthashProtocolChanges, + stored: AllProtocolChanges, new: &ChainConfig{HomesteadBlock: nil}, head: 3, wantErr: &ConfigCompatError{ @@ -49,7 +49,7 @@ func TestCheckCompatible(t *testing.T) { }, }, { - stored: AllEthashProtocolChanges, + stored: AllProtocolChanges, new: &ChainConfig{HomesteadBlock: big.NewInt(1)}, head: 3, wantErr: &ConfigCompatError{ diff --git a/u2u/rules.go b/u2u/rules.go index ed4ecfd6..547d8c39 100644 --- a/u2u/rules.go +++ b/u2u/rules.go @@ -124,7 +124,7 @@ type UpgradeHeight struct { // EvmChainConfig returns ChainConfig for transactions signing and execution func (r Rules) EvmChainConfig(hh []UpgradeHeight) *ethparams.ChainConfig { - cfg := *ethparams.AllEthashProtocolChanges + cfg := *ethparams.AllProtocolChanges cfg.ChainID = new(big.Int).SetUint64(r.NetworkID) cfg.BerlinBlock = nil cfg.LondonBlock = nil From ae840e639cd648d4f8044c6b0037501023ef637d Mon Sep 17 00:00:00 2001 From: b1m0n Date: Sun, 10 Dec 2023 18:41:47 +0700 Subject: [PATCH 2/2] Remove ETH consensus interfaces --- consensus/consensus.go | 119 ------------------------------ consensus/misc/eip1559.go | 93 ----------------------- consensus/misc/eip1559_test.go | 130 --------------------------------- consensus/misc/gaslimit.go | 42 ----------- evmcore/tx_pool.go | 3 +- evmcore/tx_pool_helper.go | 51 +++++++++++++ 6 files changed, 52 insertions(+), 386 deletions(-) delete mode 100644 consensus/consensus.go delete mode 100644 consensus/misc/eip1559.go delete mode 100644 consensus/misc/eip1559_test.go delete mode 100644 consensus/misc/gaslimit.go create mode 100644 evmcore/tx_pool_helper.go diff --git a/consensus/consensus.go b/consensus/consensus.go deleted file mode 100644 index 3b653f19..00000000 --- a/consensus/consensus.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package consensus implements different Ethereum consensus engines. -package consensus - -import ( - "math/big" - - "github.com/unicornultrafoundation/go-u2u/common" - "github.com/unicornultrafoundation/go-u2u/core/state" - "github.com/unicornultrafoundation/go-u2u/core/types" - "github.com/unicornultrafoundation/go-u2u/params" - "github.com/unicornultrafoundation/go-u2u/rpc" -) - -// ChainHeaderReader defines a small collection of methods needed to access the local -// blockchain during header verification. -type ChainHeaderReader interface { - // Config retrieves the blockchain's chain configuration. - Config() *params.ChainConfig - - // CurrentHeader retrieves the current header from the local chain. - CurrentHeader() *types.Header - - // GetHeader retrieves a block header from the database by hash and number. - GetHeader(hash common.Hash, number uint64) *types.Header - - // GetHeaderByNumber retrieves a block header from the database by number. - GetHeaderByNumber(number uint64) *types.Header - - // GetHeaderByHash retrieves a block header from the database by its hash. - GetHeaderByHash(hash common.Hash) *types.Header -} - -// ChainReader defines a small collection of methods needed to access the local -// blockchain during header and/or uncle verification. -type ChainReader interface { - ChainHeaderReader - - // GetBlock retrieves a block from the database by hash and number. - GetBlock(hash common.Hash, number uint64) *types.Block -} - -// Engine is an algorithm agnostic consensus engine. -type Engine interface { - // Author retrieves the Ethereum address of the account that minted the given - // block, which may be different from the header's coinbase if a consensus - // engine is based on signatures. - Author(header *types.Header) (common.Address, error) - - // VerifyHeader checks whether a header conforms to the consensus rules of a - // given engine. Verifying the seal may be done optionally here, or explicitly - // via the VerifySeal method. - VerifyHeader(chain ChainHeaderReader, header *types.Header, seal bool) error - - // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers - // concurrently. The method returns a quit channel to abort the operations and - // a results channel to retrieve the async verifications (the order is that of - // the input slice). - VerifyHeaders(chain ChainHeaderReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) - - // VerifyUncles verifies that the given block's uncles conform to the consensus - // rules of a given engine. - VerifyUncles(chain ChainReader, block *types.Block) error - - // Prepare initializes the consensus fields of a block header according to the - // rules of a particular engine. The changes are executed inline. - Prepare(chain ChainHeaderReader, header *types.Header) error - - // Finalize runs any post-transaction state modifications (e.g. block rewards) - // but does not assemble the block. - // - // Note: The block header and state database might be updated to reflect any - // consensus rules that happen at finalization (e.g. block rewards). - Finalize(chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, - uncles []*types.Header) - - // FinalizeAndAssemble runs any post-transaction state modifications (e.g. block - // rewards) and assembles the final block. - // - // Note: The block header and state database might be updated to reflect any - // consensus rules that happen at finalization (e.g. block rewards). - FinalizeAndAssemble(chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, - uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) - - // Seal generates a new sealing request for the given input block and pushes - // the result into the given channel. - // - // Note, the method returns immediately and will send the result async. More - // than one result may also be returned depending on the consensus algorithm. - Seal(chain ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error - - // SealHash returns the hash of a block prior to it being sealed. - SealHash(header *types.Header) common.Hash - - // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty - // that a new block should have. - CalcDifficulty(chain ChainHeaderReader, time uint64, parent *types.Header) *big.Int - - // APIs returns the RPC APIs this consensus engine provides. - APIs(chain ChainHeaderReader) []rpc.API - - // Close terminates any background threads maintained by the consensus engine. - Close() error -} \ No newline at end of file diff --git a/consensus/misc/eip1559.go b/consensus/misc/eip1559.go deleted file mode 100644 index b3d5f146..00000000 --- a/consensus/misc/eip1559.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package misc - -import ( - "fmt" - "math/big" - - "github.com/unicornultrafoundation/go-u2u/common" - "github.com/unicornultrafoundation/go-u2u/common/math" - "github.com/unicornultrafoundation/go-u2u/core/types" - "github.com/unicornultrafoundation/go-u2u/params" -) - -// VerifyEip1559Header verifies some header attributes which were changed in EIP-1559, -// - gas limit check -// - basefee check -func VerifyEip1559Header(config *params.ChainConfig, parent, header *types.Header) error { - // Verify that the gas limit remains within allowed bounds - parentGasLimit := parent.GasLimit - if !config.IsLondon(parent.Number) { - parentGasLimit = parent.GasLimit * params.ElasticityMultiplier - } - if err := VerifyGaslimit(parentGasLimit, header.GasLimit); err != nil { - return err - } - // Verify the header is not malformed - if header.BaseFee == nil { - return fmt.Errorf("header is missing baseFee") - } - // Verify the baseFee is correct based on the parent header. - expectedBaseFee := CalcBaseFee(config, parent) - if header.BaseFee.Cmp(expectedBaseFee) != 0 { - return fmt.Errorf("invalid baseFee: have %s, want %s, parentBaseFee %s, parentGasUsed %d", - expectedBaseFee, header.BaseFee, parent.BaseFee, parent.GasUsed) - } - return nil -} - -// CalcBaseFee calculates the basefee of the header. -func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int { - // If the current block is the first EIP-1559 block, return the InitialBaseFee. - if !config.IsLondon(parent.Number) { - return new(big.Int).SetUint64(params.InitialBaseFee) - } - - var ( - parentGasTarget = parent.GasLimit / params.ElasticityMultiplier - parentGasTargetBig = new(big.Int).SetUint64(parentGasTarget) - baseFeeChangeDenominator = new(big.Int).SetUint64(params.BaseFeeChangeDenominator) - ) - // If the parent gasUsed is the same as the target, the baseFee remains unchanged. - if parent.GasUsed == parentGasTarget { - return new(big.Int).Set(parent.BaseFee) - } - if parent.GasUsed > parentGasTarget { - // If the parent block used more gas than its target, the baseFee should increase. - gasUsedDelta := new(big.Int).SetUint64(parent.GasUsed - parentGasTarget) - x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta) - y := x.Div(x, parentGasTargetBig) - baseFeeDelta := math.BigMax( - x.Div(y, baseFeeChangeDenominator), - common.Big1, - ) - - return x.Add(parent.BaseFee, baseFeeDelta) - } else { - // Otherwise if the parent block used less gas than its target, the baseFee should decrease. - gasUsedDelta := new(big.Int).SetUint64(parentGasTarget - parent.GasUsed) - x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta) - y := x.Div(x, parentGasTargetBig) - baseFeeDelta := x.Div(y, baseFeeChangeDenominator) - - return math.BigMax( - x.Sub(parent.BaseFee, baseFeeDelta), - common.Big0, - ) - } -} diff --git a/consensus/misc/eip1559_test.go b/consensus/misc/eip1559_test.go deleted file mode 100644 index c9c04773..00000000 --- a/consensus/misc/eip1559_test.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package misc - -import ( - "math/big" - "testing" - - "github.com/unicornultrafoundation/go-u2u/common" - "github.com/unicornultrafoundation/go-u2u/core/types" - "github.com/unicornultrafoundation/go-u2u/params" -) - -// copyConfig does a _shallow_ copy of a given config. Safe to set new values, but -// do not use e.g. SetInt() on the numbers. For testing only -func copyConfig(original *params.ChainConfig) *params.ChainConfig { - return ¶ms.ChainConfig{ - ChainID: original.ChainID, - HomesteadBlock: original.HomesteadBlock, - DAOForkBlock: original.DAOForkBlock, - DAOForkSupport: original.DAOForkSupport, - EIP150Block: original.EIP150Block, - EIP150Hash: original.EIP150Hash, - EIP155Block: original.EIP155Block, - EIP158Block: original.EIP158Block, - ByzantiumBlock: original.ByzantiumBlock, - ConstantinopleBlock: original.ConstantinopleBlock, - PetersburgBlock: original.PetersburgBlock, - IstanbulBlock: original.IstanbulBlock, - MuirGlacierBlock: original.MuirGlacierBlock, - BerlinBlock: original.BerlinBlock, - LondonBlock: original.LondonBlock, - CatalystBlock: original.CatalystBlock, - } -} - -func config() *params.ChainConfig { - config := copyConfig(params.TestChainConfig) - config.LondonBlock = big.NewInt(5) - return config -} - -// TestBlockGasLimits tests the gasLimit checks for blocks both across -// the EIP-1559 boundary and post-1559 blocks -func TestBlockGasLimits(t *testing.T) { - initial := new(big.Int).SetUint64(params.InitialBaseFee) - - for i, tc := range []struct { - pGasLimit uint64 - pNum int64 - gasLimit uint64 - ok bool - }{ - // Transitions from non-london to london - {10000000, 4, 20000000, true}, // No change - {10000000, 4, 20019530, true}, // Upper limit - {10000000, 4, 20019531, false}, // Upper +1 - {10000000, 4, 19980470, true}, // Lower limit - {10000000, 4, 19980469, false}, // Lower limit -1 - // London to London - {20000000, 5, 20000000, true}, - {20000000, 5, 20019530, true}, // Upper limit - {20000000, 5, 20019531, false}, // Upper limit +1 - {20000000, 5, 19980470, true}, // Lower limit - {20000000, 5, 19980469, false}, // Lower limit -1 - {40000000, 5, 40039061, true}, // Upper limit - {40000000, 5, 40039062, false}, // Upper limit +1 - {40000000, 5, 39960939, true}, // lower limit - {40000000, 5, 39960938, false}, // Lower limit -1 - } { - parent := &types.Header{ - GasUsed: tc.pGasLimit / 2, - GasLimit: tc.pGasLimit, - BaseFee: initial, - Number: big.NewInt(tc.pNum), - } - header := &types.Header{ - GasUsed: tc.gasLimit / 2, - GasLimit: tc.gasLimit, - BaseFee: initial, - Number: big.NewInt(tc.pNum + 1), - } - err := VerifyEip1559Header(config(), parent, header) - if tc.ok && err != nil { - t.Errorf("test %d: Expected valid header: %s", i, err) - } - if !tc.ok && err == nil { - t.Errorf("test %d: Expected invalid header", i) - } - } -} - -// TestCalcBaseFee assumes all blocks are 1559-blocks -func TestCalcBaseFee(t *testing.T) { - tests := []struct { - parentBaseFee int64 - parentGasLimit uint64 - parentGasUsed uint64 - expectedBaseFee int64 - }{ - {params.InitialBaseFee, 20000000, 10000000, params.InitialBaseFee}, // usage == target - {params.InitialBaseFee, 20000000, 9000000, 987500000}, // usage below target - {params.InitialBaseFee, 20000000, 11000000, 1012500000}, // usage above target - } - for i, test := range tests { - parent := &types.Header{ - Number: common.Big32, - GasLimit: test.parentGasLimit, - GasUsed: test.parentGasUsed, - BaseFee: big.NewInt(test.parentBaseFee), - } - if have, want := CalcBaseFee(config(), parent), big.NewInt(test.expectedBaseFee); have.Cmp(want) != 0 { - t.Errorf("test %d: have %d want %d, ", i, have, want) - } - } -} diff --git a/consensus/misc/gaslimit.go b/consensus/misc/gaslimit.go deleted file mode 100644 index 8a117fe1..00000000 --- a/consensus/misc/gaslimit.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package misc - -import ( - "errors" - "fmt" - - "github.com/unicornultrafoundation/go-u2u/params" -) - -// VerifyGaslimit verifies the header gas limit according increase/decrease -// in relation to the parent gas limit. -func VerifyGaslimit(parentGasLimit, headerGasLimit uint64) error { - // Verify that the gas limit remains within allowed bounds - diff := int64(parentGasLimit) - int64(headerGasLimit) - if diff < 0 { - diff *= -1 - } - limit := parentGasLimit / params.GasLimitBoundDivisor - if uint64(diff) >= limit { - return fmt.Errorf("invalid gas limit: have %d, want %d +-= %d", headerGasLimit, parentGasLimit, limit-1) - } - if headerGasLimit < params.MinGasLimit { - return errors.New("invalid gas limit below 5000") - } - return nil -} diff --git a/evmcore/tx_pool.go b/evmcore/tx_pool.go index 7e6bdeb5..8f6a4ea2 100644 --- a/evmcore/tx_pool.go +++ b/evmcore/tx_pool.go @@ -27,7 +27,6 @@ import ( "github.com/unicornultrafoundation/go-u2u/common" "github.com/unicornultrafoundation/go-u2u/common/prque" - "github.com/unicornultrafoundation/go-u2u/consensus/misc" "github.com/unicornultrafoundation/go-u2u/core/state" "github.com/unicornultrafoundation/go-u2u/core/types" notify "github.com/unicornultrafoundation/go-u2u/event" @@ -1191,7 +1190,7 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt } else { // for tests only if reset.newHead != nil && pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) { - pendingBaseFee := misc.CalcBaseFee(pool.chainconfig, reset.newHead.EthHeader()) + pendingBaseFee := calcBaseFee(pool.chainconfig, reset.newHead.EthHeader()) pool.priced.SetBaseFee(pendingBaseFee) } } diff --git a/evmcore/tx_pool_helper.go b/evmcore/tx_pool_helper.go new file mode 100644 index 00000000..d2dd772b --- /dev/null +++ b/evmcore/tx_pool_helper.go @@ -0,0 +1,51 @@ +package evmcore + +import ( + "math/big" + + "github.com/unicornultrafoundation/go-u2u/common" + "github.com/unicornultrafoundation/go-u2u/common/math" + "github.com/unicornultrafoundation/go-u2u/core/types" + "github.com/unicornultrafoundation/go-u2u/params" +) + +// calcBaseFee calculates the BaseFee of the header. +func calcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int { + // If the current block is the first EIP-1559 block, return the InitialBaseFee. + if !config.IsLondon(parent.Number) { + return new(big.Int).SetUint64(params.InitialBaseFee) + } + + var ( + parentGasTarget = parent.GasLimit / params.ElasticityMultiplier + parentGasTargetBig = new(big.Int).SetUint64(parentGasTarget) + baseFeeChangeDenominator = new(big.Int).SetUint64(params.BaseFeeChangeDenominator) + ) + // If the parent gasUsed is the same as the target, the baseFee remains unchanged. + if parent.GasUsed == parentGasTarget { + return new(big.Int).Set(parent.BaseFee) + } + if parent.GasUsed > parentGasTarget { + // If the parent block used more gas than its target, the baseFee should increase. + gasUsedDelta := new(big.Int).SetUint64(parent.GasUsed - parentGasTarget) + x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta) + y := x.Div(x, parentGasTargetBig) + baseFeeDelta := math.BigMax( + x.Div(y, baseFeeChangeDenominator), + common.Big1, + ) + + return x.Add(parent.BaseFee, baseFeeDelta) + } else { + // Otherwise if the parent block used less gas than its target, the baseFee should decrease. + gasUsedDelta := new(big.Int).SetUint64(parentGasTarget - parent.GasUsed) + x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta) + y := x.Div(x, parentGasTargetBig) + baseFeeDelta := x.Div(y, baseFeeChangeDenominator) + + return math.BigMax( + x.Sub(parent.BaseFee, baseFeeDelta), + common.Big0, + ) + } +}