diff --git a/CHANGELOG.md b/CHANGELOG.md index 978ceb4830..9687ad7c82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,190 @@ # Changelog +## v0.4.6 + +This is a minor release for opBNB Mainnet and Testnet. +Upgrading is optional. + +### What's Changed +* perf: add DialOptions function for Dial by @constwz in https://github.com/bnb-chain/op-geth/pull/140 +* Fix: clear difflayer cache when truncate not triggered by @krish-nr in https://github.com/bnb-chain/op-geth/pull/141 +* fix addBundle issue by @redhdx in https://github.com/bnb-chain/op-geth/pull/143 + +### New Contributors +* @constwz made their first contribution in https://github.com/bnb-chain/op-geth/pull/140 + +### Docker Images + +- ghcr.io/bnb-chain/op-geth:v0.4.6 + +**Full Changelog**: https://github.com/bnb-chain/op-geth/compare/v0.4.5...v0.4.6 + +## v0.4.5 + +This is a hard fork release for the opBNB Mainnet called **Wright**. It will be activated on August 27, 2024, at 6 AM UTC. +All **mainnet** op-geth nodes must upgrade to this release before the hard fork. + +The testnet hardfork will be activated on August 15, 2024, at 6 AM UTC. +If you have upgraded your testnet op-geth to version 0.4.4, you can skip this version for the testnet. Otherwise, you can directly upgrade your testnet op-geth to version 0.4.5. + +### User Facing Changes + +To support gasless transactions on opBNB, the following features have been introduced: + +* The base fee is set to 0. +* The bundle feature is supported. +* When the gas price is set to 0, the L1 fee will also be set to 0. + +Combined with these features and a sponsor (paymaster), users can send transactions without holding BNB to pay gas fees. + +### Changelogs +* perf: speedup pbss trienode read by @will-2012 in https://github.com/bnb-chain/op-geth/pull/122 +* pathdb: handle persistent id when using nodebufferlist by @sysvm in https://github.com/bnb-chain/op-geth/pull/121 +* feat: support auto recover when pbss meet unclean shutdown by @krish-nr in https://github.com/bnb-chain/op-geth/pull/125 +* fix: ignore truncation target range as flush not operated on time by @krish-nr in https://github.com/bnb-chain/op-geth/pull/131 +* feature(op-geth): add opbnb gasless solution by @redhdx in https://github.com/bnb-chain/op-geth/pull/130 + +### Docker Images + +- ghcr.io/bnb-chain/op-geth:v0.4.5 + +**Full Changelog**: https://github.com/bnb-chain/op-geth/compare/v0.4.3...v0.4.5 + +## v0.4.4 + +This is a hard fork release for the opBNB Testnet called **Wright**. It will be activated on August 15, 2024, at 6 AM UTC. +All **testnet** nodes must upgrade to this release before the hard fork. + +Upgrading for mainnet nodes is optional. + +### User Facing Changes + +To support gasless transactions on opBNB, the following features have been introduced: + +* The base fee is set to 0. +* The bundle feature is supported. +* When the gas price is set to 0, the L1 fee will also be set to 0. + +Combined with these features and a sponsor (paymaster), users can send transactions without holding BNB to pay gas fees. + +### Changelogs +* perf: speedup pbss trienode read by @will-2012 in https://github.com/bnb-chain/op-geth/pull/122 +* pathdb: handle persistent id when using nodebufferlist by @sysvm in https://github.com/bnb-chain/op-geth/pull/121 +* feat: support auto recover when pbss meet unclean shutdown by @krish-nr in https://github.com/bnb-chain/op-geth/pull/125 +* fix: ignore truncation target range as flush not operated on time by @krish-nr in https://github.com/bnb-chain/op-geth/pull/131 +* feature(op-geth): add opbnb gasless solution by @redhdx in https://github.com/bnb-chain/op-geth/pull/130 + +### Docker Images + +- ghcr.io/bnb-chain/op-geth:v0.4.4 + +**Full Changelog**: https://github.com/bnb-chain/op-geth/compare/v0.4.3...v0.4.4 + +## 0.4.3 + +This is a minor release for opBNB Mainnet and Testnet. +Upgrading is optional. + +### User Facing Changes + +* Conducted several performance improvements for txpool and block execution.(#89, #84, #85, #92) +* Added `--journalFile` flag to enable/disable the journal file feature. #95 + +### What's Changed +* feat(txpool): improve performance of Reheap by @andyzhang2023 in https://github.com/bnb-chain/op-geth/pull/89 +* feat(txpool): improve demotion unexecutable transactions by @andyzhang2023 in https://github.com/bnb-chain/op-geth/pull/84 +* opt: do verify and commit concurrently by @joeylichang in https://github.com/bnb-chain/op-geth/pull/92 +* improve Pending() of txpool to reduce the latency when miner worker committing transactions by @andyzhang2023 in https://github.com/bnb-chain/op-geth/pull/85 +* core/trie: persist TrieJournal to journal file instead of kv database by @sysvm in https://github.com/bnb-chain/op-geth/pull/95 +* add some metrics for txpool by @andyzhang2023 in https://github.com/bnb-chain/op-geth/pull/120 + +## Docker Images + +ghcr.io/bnb-chain/op-geth:v0.4.3 + +**Full Changelog**: https://github.com/bnb-chain/op-geth/compare/v0.4.2...v0.4.3 + +## 0.4.2 + +This is the mainnet hardfork release version. + +Four hard forks are scheduled to launch on the opBNB Mainnet: +Shanghai/Canyon Time: 2024-06-20 08:00:00 AM UTC +Delta Time: 2024-06-20 08:10:00 AM UTC +Cancun/Ecotone Time: 2024-06-20 08:20:00 AM UTC +Haber Time: 2024-06-20 08:30:00 AM UTC + +All mainnet `op-geth` have to be upgraded to this version before 2024-06-20 08:00:00 AM UTC. +The `op-node` also have to be upgraded to v0.4.2 accordingly, check [this](https://github.com/bnb-chain/opbnb/releases/tag/v0.4.2) for more details. + +### What's Changed +* fix: adjust flush condition to avoid not flush by @will-2012 in https://github.com/bnb-chain/op-geth/pull/114 +* config: Mainnet Shanghai/Canyon/Cancun/Ecotone/Haber fork time by @welkin22 in https://github.com/bnb-chain/op-geth/pull/116 + +### Docker Images + +ghcr.io/bnb-chain/op-geth:v0.4.2 + +**Full Changelog**: https://github.com/bnb-chain/op-geth/compare/v0.4.1...v0.4.2 + +## 0.4.1 + +This is the Haber Hardfork release for opBNB Testnet. + +The Haber hardfork will be activated on May 30, 2024, at 6:00 AM UTC. + +All testnet nodes must upgrade to this release before the hardfork. +Upgrading for other networks is optional. + +### User Facing Changes +* Introduced precompile for secp256r1 curve as [EIP 7212](https://eips.ethereum.org/EIPS/eip-7212). Please refer to this [PR](https://github.com/bnb-chain/op-geth/pull/112) for more details. + +### What's Changed +* cmd/dbcmd: add inspect trie tool by @sysvm in https://github.com/bnb-chain/op-geth/pull/103 +* fix: cherry-picked from upstream code by @welkin22 in https://github.com/bnb-chain/op-geth/pull/109 +* fix: add miss cache code after 4844 merge by @welkin22 in https://github.com/bnb-chain/op-geth/pull/110 +* feat: add proof keeper by @will-2012 in https://github.com/bnb-chain/op-geth/pull/90 +* feature(op-geth): add precompile for secp256r1 curve after haber hardfork by @redhdx in https://github.com/bnb-chain/op-geth/pull/112 + +### Docker Images +* ghcr.io/bnb-chain/op-geth:v0.4.1 + +**Full Changelog**: https://github.com/bnb-chain/op-geth/compare/v0.4.0...v0.4.1 + +## 0.4.0 +This release includes code merging from the upstream version v1.101308.2 to transition Testnet's DA data from calldata to blob format. +Four hard forks are scheduled to launch on the opBNB Testnet: +Snow Time: May-15-2024 06:00 AM +UTC +Shanghai/Canyon Time: May-15-2024 06:10 AM +UTC +Delta Time: May-15-2024 06:20 AM +UTC +Cancun/Ecotone Time: May-15-2024 06:30 AM +UTC + +The Shanghai/Canyon fork and Cancun/Ecotone fork involve changes to op-geth. + +### User Facing Changes +Nodes on the **Testnet** need to be upgraded to this version before the first hard fork time. +**Note: This is a version prepared for Testnet, Mainnet nodes do not need to upgrade to this version.** + +### Breaking Changes +Fast Node Mode (released in version [v0.3.1](https://github.com/bnb-chain/op-geth/releases/tag/v0.3.1)) has become unusable due to conflicts with upstream code. +We are working to resolve this issue and expect it to be fixed in the next version. + +### What's Changed +* feature(op-geth): update opBNB qanet config by @redhdx in https://github.com/bnb-chain/op-geth/pull/99 +* canyon fork: revert disable create2deployer in canyon fork by @bnoieh in https://github.com/bnb-chain/op-geth/pull/100 +* feature(op-geth): add opBNB qanet hard fork config by @redhdx in https://github.com/bnb-chain/op-geth/pull/101 +* add precompiled contracts for light client by @KeefeL in https://github.com/bnb-chain/op-geth/pull/102 +* feature: add opBNB V5 bootnodes by @redhdx in https://github.com/bnb-chain/op-geth/pull/104 +* add bls example by @KeefeL in https://github.com/bnb-chain/op-geth/pull/105 +* Merge upstream op-geth v1.101308.2 by @welkin22 in https://github.com/bnb-chain/op-geth/pull/87 +* fix: the TrieCommitInterval not taking effect on restart by @welkin22 in https://github.com/bnb-chain/op-geth/pull/106 +* config: Testnet 4844 fork time by @welkin22 in https://github.com/bnb-chain/op-geth/pull/107 + +### Docker Images +ghcr.io/bnb-chain/op-geth:v0.4.0 + +**Full Changelog**: https://github.com/bnb-chain/op-geth/compare/v0.3.1...v0.4.0 + ## v0.3.1 This is a minor release for opBNB Mainnet and Testnet. diff --git a/core/txpool/bundlepool/bundlepool.go b/core/txpool/bundlepool/bundlepool.go index 1f5589badd..b9b30dbc4a 100644 --- a/core/txpool/bundlepool/bundlepool.go +++ b/core/txpool/bundlepool/bundlepool.go @@ -171,20 +171,22 @@ func (p *BundlePool) AddBundle(bundle *types.Bundle, originBundle *types.SendBun if err != nil { return err } + bundle.Price = price p.mu.Lock() defer p.mu.Unlock() - if price.Cmp(p.minimalBundleGasPrice()) <= 0 && p.slots+numSlots(bundle) > p.config.GlobalSlots { - return ErrBundleGasPriceLow - } - bundle.Price = price - hash := bundle.Hash() if _, ok := p.bundles[hash]; ok { return ErrBundleAlreadyExist } + if p.slots+numSlots(bundle) > p.config.GlobalSlots { + if !p.drop(bundle) { + return ErrBundleGasPriceLow + } + } + for url, cli := range p.bundleReceiverClients { cli := cli url := url @@ -199,9 +201,6 @@ func (p *BundlePool) AddBundle(bundle *types.Bundle, originBundle *types.SendBun bundleDeliverAll.Inc(1) } - for p.slots+numSlots(bundle) > p.config.GlobalSlots { - p.drop() - } p.bundles[hash] = bundle heap.Push(&p.bundleHeap, bundle) p.slots += numSlots(bundle) @@ -397,16 +396,34 @@ func (p *BundlePool) deleteBundle(hash common.Hash) { } // drop removes the bundle with the lowest gas price from the pool. -func (p *BundlePool) drop() { +func (p *BundlePool) drop(bundle *types.Bundle) bool { + dropBundles := make([]*types.Bundle, 0, numSlots(bundle)) + dropSlots := uint64(0) for len(p.bundleHeap) > 0 { + if dropSlots >= numSlots(bundle) { + for _, dropBundle := range dropBundles { + p.deleteBundle(dropBundle.Hash()) + } + return true + } // Pop the bundle with the lowest gas price // the min element in the heap may not exist in the pool as it may be pruned leastPriceBundleHash := heap.Pop(&p.bundleHeap).(*types.Bundle).Hash() - if _, ok := p.bundles[leastPriceBundleHash]; ok { - p.deleteBundle(leastPriceBundleHash) - break + if leastPriceBundle, ok := p.bundles[leastPriceBundleHash]; ok { + if leastPriceBundle.Price.Cmp(bundle.Price) < 0 { + dropBundles = append(dropBundles, leastPriceBundle) + dropSlots = dropSlots + numSlots(leastPriceBundle) + continue + } else { + heap.Push(&p.bundleHeap, leastPriceBundle) + for _, dropBundle := range dropBundles { + heap.Push(&p.bundleHeap, dropBundle) + } + return false + } } } + return false } // minimalBundleGasPrice return the lowest gas price from the pool. diff --git a/core/txpool/bundlepool/bundlepool_test.go b/core/txpool/bundlepool/bundlepool_test.go new file mode 100644 index 0000000000..bc32499a62 --- /dev/null +++ b/core/txpool/bundlepool/bundlepool_test.go @@ -0,0 +1,136 @@ +package bundlepool + +import ( + "container/heap" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/miner" + "github.com/ethereum/go-ethereum/params" + "math/big" + "testing" +) + +type testBlockChain struct { + config *params.ChainConfig + gasLimit uint64 + statedb *state.StateDB +} + +func (bc *testBlockChain) Config() *params.ChainConfig { + return bc.config +} + +func (bc *testBlockChain) CurrentBlock() *types.Header { + return &types.Header{ + Number: new(big.Int), + } +} + +func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { + return nil +} + +func (bc *testBlockChain) StateAt(root common.Hash) (*state.StateDB, error) { + return bc.statedb, nil +} + +func setupBundlePool(config Config, mevConfig miner.MevConfig) *BundlePool { + return setupBundlePoolWithConfig(config, mevConfig) +} + +func setupBundlePoolWithConfig(config Config, mevConfig miner.MevConfig) *BundlePool { + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + blockchain := newTestBlockChain(params.TestChainConfig, 100000000, statedb) + + pool := New(config, mevConfig, blockchain) + return pool +} + +func newTestBlockChain(config *params.ChainConfig, gasLimit uint64, statedb *state.StateDB) *testBlockChain { + bc := testBlockChain{config: config, gasLimit: gasLimit, statedb: statedb} + return &bc +} + +func TestBundlePoolDrop(t *testing.T) { + bundleConfig := Config{GlobalSlots: 5} + mevConfig := miner.MevConfig{MevEnabled: true} + bundlepool := setupBundlePool(bundleConfig, mevConfig) + for i := 0; i < 5; i++ { + bundle := &types.Bundle{ + Price: big.NewInt(int64(i)), + } + hash := bundle.Hash() + bundlepool.bundles[hash] = bundle + heap.Push(&bundlepool.bundleHeap, bundle) + bundlepool.slots += numSlots(bundle) + } + + // now bundle pool order by price [0, 1, 2, 3, 4] + // test drop, one bundle with one slot replace success + bundle := &types.Bundle{ + Txs: nil, + Price: big.NewInt(5), + } + if !bundlepool.drop(bundle) { + t.Errorf("bundle pool drop expect success, but failed") + } + // check old least price bundle (bundle price is 0) not exist in bundle pool + leastPriceBundleHash := heap.Pop(&bundlepool.bundleHeap).(*types.Bundle).Hash() + if leastPriceBundle, ok := bundlepool.bundles[leastPriceBundleHash]; ok { + if leastPriceBundle.Price.Uint64() == 0 { + t.Errorf("old bundle expect not in bundlepool, but in") + } + heap.Push(&bundlepool.bundleHeap, leastPriceBundle) + } + hash := bundle.Hash() + bundlepool.bundles[hash] = bundle + heap.Push(&bundlepool.bundleHeap, bundle) + bundlepool.slots += numSlots(bundle) + + // now bundle pool as price [1, 2, 3, 4, 5] + // test drop, one bundle with 2 slot replace failed + data := make([]byte, bundleSlotSize+1) + for i := range data { + data[i] = 0xFF + } + txs := types.Transactions{ + types.NewTx(&types.LegacyTx{ + Data: data, + }), + } + bundle = &types.Bundle{ + Txs: txs, + Price: big.NewInt(2), + } + if bundlepool.drop(bundle) { + t.Errorf("bundle pool drop expect failed, but success") + } + // check old least price bundle (bundle price is 1) exist in bundle pool, not dropped + leastPriceBundleHash = heap.Pop(&bundlepool.bundleHeap).(*types.Bundle).Hash() + if leastPriceBundle, ok := bundlepool.bundles[leastPriceBundleHash]; ok { + if leastPriceBundle.Price.Uint64() != 1 { + t.Errorf("old bundle expect in bundlepool, but dropped") + } + heap.Push(&bundlepool.bundleHeap, leastPriceBundle) + } + + // now bundle pool as price [1, 2, 3, 4, 5] + // test drop, one bundle with 2 slot replace success + bundle = &types.Bundle{ + Txs: txs, + Price: big.NewInt(3), + } + if !bundlepool.drop(bundle) { + t.Errorf("bundle pool drop expect success, but failed") + } + // check old least bundle (bundle price is 1 and 2) not exist in bundle pool, dropped + leastPriceBundleHash = heap.Pop(&bundlepool.bundleHeap).(*types.Bundle).Hash() + if leastPriceBundle, ok := bundlepool.bundles[leastPriceBundleHash]; ok { + if leastPriceBundle.Price.Uint64() != 3 { + t.Errorf("old bundle expect not in bundlepool, but in") + } + heap.Push(&bundlepool.bundleHeap, leastPriceBundle) + } +} diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index d01aab51f1..87892b6450 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -50,6 +50,16 @@ func DialContext(ctx context.Context, rawurl string) (*Client, error) { return NewClient(c), nil } +// DialOptions creates a new RPC client for the given URL. You can supply any of the +// pre-defined client options to configure the underlying transport. +func DialOptions(ctx context.Context, rawurl string, opts ...rpc.ClientOption) (*Client, error) { + c, err := rpc.DialOptions(ctx, rawurl, opts...) + if err != nil { + return nil, err + } + return NewClient(c), nil +} + // NewClient creates a client that uses the given RPC client. func NewClient(c *rpc.Client) *Client { return &Client{c} diff --git a/trie/triedb/pathdb/disklayer.go b/trie/triedb/pathdb/disklayer.go index 60c891fd2c..a0cb6f25a9 100644 --- a/trie/triedb/pathdb/disklayer.go +++ b/trie/triedb/pathdb/disklayer.go @@ -22,6 +22,8 @@ import ( "sync" "github.com/VictoriaMetrics/fastcache" + "golang.org/x/crypto/sha3" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/crypto" @@ -29,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/trie/triestate" - "golang.org/x/crypto/sha3" ) // trienodebuffer is a collection of modified trie nodes to aggregate the disk @@ -333,6 +334,7 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) { persistentID := rawdb.ReadPersistentStateID(dl.db.diskdb) if limit >= persistentID { log.Debug("No prune ancient under nodebufferlist, less than db config state history limit", "persistent_id", persistentID, "limit", limit) + bottom.cache.Remove(bottom) return ndl, nil } targetOldest := persistentID - limit + 1 @@ -340,6 +342,7 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) { if err == nil && targetOldest <= realOldest { log.Info("No prune ancient under nodebufferlist due to truncate oldest less than real oldest, which maybe happened in abnormal restart", "tartget_oldest_id", targetOldest, "real_oldest_id", realOldest, "error", err) + bottom.cache.Remove(bottom) return ndl, nil } oldest = targetOldest