Compare commits

..

15 Commits

Author SHA1 Message Date
emailtovamos
be71d41aa5 eth: formatting 2024-05-23 14:04:22 +01:00
emailtovamos
5b46fe13e7 eth: make transaction propagation paths in the network deterministic (#29034)
* eth: make transaction propagation paths in the network deterministic

* eth: avoid potential division by 0

* eth: make tx propagation dependent on local node id too

* eth: fix review comments
2024-05-23 14:00:29 +01:00
Péter Szilágyi
0b1438c3df eth: make transaction propagation paths in the network deterministic (#29034)
* eth: make transaction propagation paths in the network deterministic

* eth: avoid potential division by 0

* eth: make tx propagation dependent on local node id too

* eth: fix review comments
2024-03-02 22:39:22 +02:00
Sina Mahmoodi
0a2f33946b eth/catalyst: update simulated beacon for cancun (#28829)
* eth/catalyst: update simulated beacon for cancun

* validate blob hashes

* compute hashes from commitment

* fix beacon root and payload version

* check commitment conversion

* fix random attr

* flip dev to cancun
2024-02-29 14:17:32 +02:00
Péter Szilágyi
865e1e9f57 cmd/utils, core/rawdb, triedb/pathdb: flip hash to path scheme (#29108)
* cmd/utils, core/rawdb, triedb/pathdb: flip hash to path scheme

* graphql: run tests in hash mode as the chain maker needs it
2024-02-29 12:40:59 +02:00
yzb
db4cf69166 all: replace fmt.Errorf() with errors.New() if no param required (#29126)
replace-fmt-errorf

Co-authored-by: yzb@example.cn <yzb@example.cn>
2024-02-29 11:56:46 +02:00
Ng Wei Han
28d55218f7 cmd/geth: parseDumpConfig should not return closed db (#29100)
* cmd: parseDumpConfig should not return closed db

* fix lint
2024-02-29 11:56:17 +02:00
cui fliter
dbc27a199f all: fix function names in docs (#29128)
Signed-off-by: cui fliter <imcusg@gmail.com>
2024-02-29 11:29:06 +02:00
lightclient
1883438964 eth/catalyst: return invalid payload attributes instead of invalid parms for bad fcu payload (#29115) 2024-02-28 19:59:16 +01:00
buddho
9986a69c25 internal/ethapi: pass in accesslist in test (#29089)
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2024-02-28 18:38:21 +01:00
rjl493456442
5bae14f9df triedb/pathdb: fix panic in recoverable (#29107)
* triedb/pathdb: fix panic in recoverable

* triedb/pathdb: add todo

* triedb/pathdb: rename

* triedb/pathdb: rename
2024-02-28 14:40:28 +02:00
rjl493456442
49623bd469 core, triedb/pathdb: calculate the size for batch pre-allocation (#29106)
* core, triedb/pathdb: calculate the size for batch pre-allocation

* triedb/pathdb: address comment
2024-02-28 14:23:52 +02:00
Péter Szilágyi
170fcd80c6 params: being major version bump cycle 2024-02-28 10:01:52 +02:00
cui
02d77c98f9 core: using math.MaxUint64 instead of 0xffffffffffffffff (#29094) 2024-02-28 15:25:12 +08:00
Péter Szilágyi
57d2b552c7 params: begin v1.13.15 cycle 2024-02-27 13:53:30 +02:00
31 changed files with 143 additions and 333 deletions

View File

@@ -36,7 +36,7 @@ To combine DPoS and PoA for consensus, BNB Smart Chain implement a novel consens
2. Validators take turns to produce blocks in a PoA manner, similar to Ethereum's Clique consensus engine. 2. Validators take turns to produce blocks in a PoA manner, similar to Ethereum's Clique consensus engine.
3. Validator set are elected in and out based on a staking based governance on BNB Beacon Chain. 3. Validator set are elected in and out based on a staking based governance on BNB Beacon Chain.
4. The validator set change is relayed via a cross-chain communication mechanism. 4. The validator set change is relayed via a cross-chain communication mechanism.
5. Parlia consensus engine will interact with a set of [system contracts](https://docs.bnbchain.org/bnb-smart-chain/staking/overview/#system-contracts) to achieve liveness slash, revenue distributing and validator set renewing func. 5. Parlia consensus engine will interact with a set of [system contracts](https://docs.bnbchain.org/docs/learn/system-contract) to achieve liveness slash, revenue distributing and validator set renewing func.
### Light Client of BNB Beacon Chain ### Light Client of BNB Beacon Chain
@@ -183,7 +183,7 @@ This tool is optional and if you leave it out you can always attach to an alread
#### 7. More #### 7. More
More details about [running a node](https://docs.bnbchain.org/bnb-smart-chain/developers/node_operators/full_node/) and [becoming a validator](https://docs.bnbchain.org/bnb-smart-chain/validator/create-val/) More details about [running a node](https://docs.bnbchain.org/docs/validator/fullnode) and [becoming a validator](https://docs.bnbchain.org/docs/validator/create-val)
*Note: Although some internal protective measures prevent transactions from *Note: Although some internal protective measures prevent transactions from
crossing over between the main network and test network, you should always crossing over between the main network and test network, you should always

View File

@@ -64,7 +64,6 @@ var (
utils.CachePreimagesFlag, utils.CachePreimagesFlag,
utils.OverrideCancun, utils.OverrideCancun,
utils.OverrideHaber, utils.OverrideHaber,
utils.OverrideBohr,
utils.OverrideVerkle, utils.OverrideVerkle,
}, utils.DatabaseFlags), }, utils.DatabaseFlags),
Description: ` Description: `
@@ -262,10 +261,6 @@ func initGenesis(ctx *cli.Context) error {
v := ctx.Uint64(utils.OverrideHaber.Name) v := ctx.Uint64(utils.OverrideHaber.Name)
overrides.OverrideHaber = &v overrides.OverrideHaber = &v
} }
if ctx.IsSet(utils.OverrideBohr.Name) {
v := ctx.Uint64(utils.OverrideBohr.Name)
overrides.OverrideBohr = &v
}
if ctx.IsSet(utils.OverrideVerkle.Name) { if ctx.IsSet(utils.OverrideVerkle.Name) {
v := ctx.Uint64(utils.OverrideVerkle.Name) v := ctx.Uint64(utils.OverrideVerkle.Name)
overrides.OverrideVerkle = &v overrides.OverrideVerkle = &v

View File

@@ -193,10 +193,6 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
v := ctx.Uint64(utils.OverrideHaber.Name) v := ctx.Uint64(utils.OverrideHaber.Name)
cfg.Eth.OverrideHaber = &v cfg.Eth.OverrideHaber = &v
} }
if ctx.IsSet(utils.OverrideBohr.Name) {
v := ctx.Uint64(utils.OverrideBohr.Name)
cfg.Eth.OverrideBohr = &v
}
if ctx.IsSet(utils.OverrideVerkle.Name) { if ctx.IsSet(utils.OverrideVerkle.Name) {
v := ctx.Uint64(utils.OverrideVerkle.Name) v := ctx.Uint64(utils.OverrideVerkle.Name)
cfg.Eth.OverrideVerkle = &v cfg.Eth.OverrideVerkle = &v

View File

@@ -74,7 +74,6 @@ var (
utils.RialtoHash, utils.RialtoHash,
utils.OverrideCancun, utils.OverrideCancun,
utils.OverrideHaber, utils.OverrideHaber,
utils.OverrideBohr,
utils.OverrideVerkle, utils.OverrideVerkle,
utils.OverrideFullImmutabilityThreshold, utils.OverrideFullImmutabilityThreshold,
utils.OverrideMinBlocksForBlobRequests, utils.OverrideMinBlocksForBlobRequests,

View File

@@ -75,7 +75,7 @@ func NewLevelDBDatabaseWithFreezer(file string, cache int, handles int, ancient
if err != nil { if err != nil {
return nil, err return nil, err
} }
frdb, err := rawdb.NewDatabaseWithFreezer(kvdb, ancient, namespace, readonly, disableFreeze, isLastOffset, pruneAncientData, false) frdb, err := rawdb.NewDatabaseWithFreezer(kvdb, ancient, namespace, readonly, disableFreeze, isLastOffset, pruneAncientData)
if err != nil { if err != nil {
kvdb.Close() kvdb.Close()
return nil, err return nil, err
@@ -178,10 +178,11 @@ func BlockchainCreator(t *testing.T, chaindbPath, AncientPath string, blockRemai
// Force run a freeze cycle // Force run a freeze cycle
type freezer interface { type freezer interface {
Freeze(threshold uint64) error Freeze() error
Ancients() (uint64, error) Ancients() (uint64, error)
} }
db.(freezer).Freeze(10) blockchain.SetFinalized(blocks[len(blocks)-1].Header())
db.(freezer).Freeze()
frozen, err := db.Ancients() frozen, err := db.Ancients()
//make sure there're frozen items //make sure there're frozen items

View File

@@ -43,11 +43,9 @@ import (
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb"
"github.com/ethereum/go-ethereum/triedb/pathdb"
cli "github.com/urfave/cli/v2" cli "github.com/urfave/cli/v2"
) )
@@ -247,16 +245,7 @@ func accessDb(ctx *cli.Context, stack *node.Node) (ethdb.Database, error) {
NoBuild: true, NoBuild: true,
AsyncBuild: false, AsyncBuild: false,
} }
dbScheme := rawdb.ReadStateScheme(chaindb) snaptree, err := snapshot.New(snapconfig, chaindb, triedb.NewDatabase(chaindb, nil), headBlock.Root(), TriesInMemory, false)
var config *triedb.Config
if dbScheme == rawdb.PathScheme {
config = &triedb.Config{
PathDB: utils.PathDBConfigAddJournalFilePath(stack, pathdb.ReadOnly),
}
} else if dbScheme == rawdb.HashScheme {
config = triedb.HashDefaults
}
snaptree, err := snapshot.New(snapconfig, chaindb, triedb.NewDatabase(chaindb, config), headBlock.Root(), TriesInMemory, false)
if err != nil { if err != nil {
log.Error("snaptree error", "err", err) log.Error("snaptree error", "err", err)
return nil, err // The relevant snapshot(s) might not exist return nil, err // The relevant snapshot(s) might not exist
@@ -344,9 +333,6 @@ func pruneBlock(ctx *cli.Context) error {
stack, config = makeConfigNode(ctx) stack, config = makeConfigNode(ctx)
defer stack.Close() defer stack.Close()
blockAmountReserved = ctx.Uint64(utils.BlockAmountReserved.Name) blockAmountReserved = ctx.Uint64(utils.BlockAmountReserved.Name)
if blockAmountReserved < params.FullImmutabilityThreshold {
return fmt.Errorf("block-amount-reserved must be greater than or equal to %d", params.FullImmutabilityThreshold)
}
chaindb, err = accessDb(ctx, stack) chaindb, err = accessDb(ctx, stack)
if err != nil { if err != nil {
return err return err

View File

@@ -315,11 +315,6 @@ var (
Usage: "Manually specify the Haber fork timestamp, overriding the bundled setting", Usage: "Manually specify the Haber fork timestamp, overriding the bundled setting",
Category: flags.EthCategory, Category: flags.EthCategory,
} }
OverrideBohr = &cli.Uint64Flag{
Name: "override.bohr",
Usage: "Manually specify the Bohr fork timestamp, overriding the bundled setting",
Category: flags.EthCategory,
}
OverrideVerkle = &cli.Uint64Flag{ OverrideVerkle = &cli.Uint64Flag{
Name: "override.verkle", Name: "override.verkle",
Usage: "Manually specify the Verkle fork timestamp, overriding the bundled setting", Usage: "Manually specify the Verkle fork timestamp, overriding the bundled setting",
@@ -1087,7 +1082,6 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.
Name: "block-amount-reserved", Name: "block-amount-reserved",
Usage: "Sets the expected remained amount of blocks for offline block prune", Usage: "Sets the expected remained amount of blocks for offline block prune",
Category: flags.BlockHistoryCategory, Category: flags.BlockHistoryCategory,
Value: params.FullImmutabilityThreshold,
} }
CheckSnapshotWithMPT = &cli.BoolFlag{ CheckSnapshotWithMPT = &cli.BoolFlag{

View File

@@ -163,7 +163,7 @@ func TestHistoryImportAndExport(t *testing.T) {
// Now import Era. // Now import Era.
freezer := t.TempDir() freezer := t.TempDir()
db2, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), freezer, "", false, false, false, false, false) db2, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), freezer, "", false, false, false, false)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@@ -1832,10 +1832,14 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s
} }
// Force run a freeze cycle // Force run a freeze cycle
type freezer interface { type freezer interface {
Freeze(threshold uint64) error Freeze() error
Ancients() (uint64, error) Ancients() (uint64, error)
} }
db.(freezer).Freeze(tt.freezeThreshold) if tt.freezeThreshold < uint64(tt.canonicalBlocks) {
final := uint64(tt.canonicalBlocks) - tt.freezeThreshold
chain.SetFinalized(canonblocks[int(final)-1].Header())
}
db.(freezer).Freeze()
// Set the simulated pivot block // Set the simulated pivot block
if tt.pivotBlock != nil { if tt.pivotBlock != nil {

View File

@@ -2045,10 +2045,14 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme
// Force run a freeze cycle // Force run a freeze cycle
type freezer interface { type freezer interface {
Freeze(threshold uint64) error Freeze() error
Ancients() (uint64, error) Ancients() (uint64, error)
} }
db.(freezer).Freeze(tt.freezeThreshold) if tt.freezeThreshold < uint64(tt.canonicalBlocks) {
final := uint64(tt.canonicalBlocks) - tt.freezeThreshold
chain.SetFinalized(canonblocks[int(final)-1].Header())
}
db.(freezer).Freeze()
// Set the simulated pivot block // Set the simulated pivot block
if tt.pivotBlock != nil { if tt.pivotBlock != nil {

View File

@@ -974,7 +974,7 @@ func testFastVsFullChains(t *testing.T, scheme string) {
t.Fatalf("failed to insert receipt %d: %v", n, err) t.Fatalf("failed to insert receipt %d: %v", n, err)
} }
// Freezer style fast import the chain. // Freezer style fast import the chain.
ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false)
if err != nil { if err != nil {
t.Fatalf("failed to create temp freezer db: %v", err) t.Fatalf("failed to create temp freezer db: %v", err)
} }
@@ -1069,7 +1069,7 @@ func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) {
// makeDb creates a db instance for testing. // makeDb creates a db instance for testing.
makeDb := func() ethdb.Database { makeDb := func() ethdb.Database {
db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false)
if err != nil { if err != nil {
t.Fatalf("failed to create temp freezer db: %v", err) t.Fatalf("failed to create temp freezer db: %v", err)
} }
@@ -1957,7 +1957,7 @@ func testLargeReorgTrieGC(t *testing.T, scheme string) {
competitor, _ := GenerateChain(genesis.Config, shared[len(shared)-1], engine, genDb, 2*TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) }) competitor, _ := GenerateChain(genesis.Config, shared[len(shared)-1], engine, genDb, 2*TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
// Import the shared chain and the original canonical one // Import the shared chain and the original canonical one
db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false)
defer db.Close() defer db.Close()
chain, err := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil) chain, err := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil)
@@ -2026,7 +2026,7 @@ func testBlockchainRecovery(t *testing.T, scheme string) {
_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), int(height), nil) _, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), int(height), nil)
// Import the chain as a ancient-first node and ensure all pointers are updated // Import the chain as a ancient-first node and ensure all pointers are updated
ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false)
if err != nil { if err != nil {
t.Fatalf("failed to create temp freezer db: %v", err) t.Fatalf("failed to create temp freezer db: %v", err)
} }
@@ -2097,7 +2097,7 @@ func testInsertReceiptChainRollback(t *testing.T, scheme string) {
} }
// Set up a BlockChain that uses the ancient store. // Set up a BlockChain that uses the ancient store.
ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false)
if err != nil { if err != nil {
t.Fatalf("failed to create temp freezer db: %v", err) t.Fatalf("failed to create temp freezer db: %v", err)
} }
@@ -2167,7 +2167,7 @@ func testLowDiffLongChain(t *testing.T, scheme string) {
}) })
// Import the canonical chain // Import the canonical chain
diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false)
defer diskdb.Close() defer diskdb.Close()
chain, err := NewBlockChain(diskdb, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil) chain, err := NewBlockChain(diskdb, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil)
@@ -2384,7 +2384,7 @@ func testInsertKnownChainData(t *testing.T, typ string, scheme string) {
b.OffsetTime(-9) // A higher difficulty b.OffsetTime(-9) // A higher difficulty
}) })
// Import the shared chain and the original canonical one // Import the shared chain and the original canonical one
chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false)
if err != nil { if err != nil {
t.Fatalf("failed to create temp freezer db: %v", err) t.Fatalf("failed to create temp freezer db: %v", err)
} }
@@ -2555,7 +2555,7 @@ func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight i
} }
}) })
// Import the shared chain and the original canonical one // Import the shared chain and the original canonical one
chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false)
if err != nil { if err != nil {
t.Fatalf("failed to create temp freezer db: %v", err) t.Fatalf("failed to create temp freezer db: %v", err)
} }
@@ -3858,7 +3858,7 @@ func testSetCanonical(t *testing.T, scheme string) {
} }
gen.AddTx(tx) gen.AddTx(tx)
}) })
diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false)
defer diskdb.Close() defer diskdb.Close()
chain, err := NewBlockChain(diskdb, DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil, nil) chain, err := NewBlockChain(diskdb, DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil, nil)
@@ -4483,7 +4483,7 @@ func (c *mockParlia) CalcDifficulty(chain consensus.ChainHeaderReader, time uint
func TestParliaBlobFeeReward(t *testing.T) { func TestParliaBlobFeeReward(t *testing.T) {
// Have N headers in the freezer // Have N headers in the freezer
frdir := t.TempDir() frdir := t.TempDir()
db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false, false) db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false)
if err != nil { if err != nil {
t.Fatalf("failed to create database with ancient backend") t.Fatalf("failed to create database with ancient backend")
} }

View File

@@ -218,7 +218,6 @@ func (e *GenesisMismatchError) Error() string {
type ChainOverrides struct { type ChainOverrides struct {
OverrideCancun *uint64 OverrideCancun *uint64
OverrideHaber *uint64 OverrideHaber *uint64
OverrideBohr *uint64
OverrideVerkle *uint64 OverrideVerkle *uint64
} }
@@ -251,9 +250,6 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
if overrides != nil && overrides.OverrideHaber != nil { if overrides != nil && overrides.OverrideHaber != nil {
config.HaberTime = overrides.OverrideHaber config.HaberTime = overrides.OverrideHaber
} }
if overrides != nil && overrides.OverrideBohr != nil {
config.BohrTime = overrides.OverrideBohr
}
if overrides != nil && overrides.OverrideVerkle != nil { if overrides != nil && overrides.OverrideVerkle != nil {
config.VerkleTime = overrides.OverrideVerkle config.VerkleTime = overrides.OverrideVerkle
} }

View File

@@ -518,7 +518,7 @@ func checkBlobSidecarsRLP(have, want types.BlobSidecars) error {
func TestAncientStorage(t *testing.T) { func TestAncientStorage(t *testing.T) {
// Freezer style fast import the chain. // Freezer style fast import the chain.
frdir := t.TempDir() frdir := t.TempDir()
db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false, false, false, false, false) db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false, false, false, false)
if err != nil { if err != nil {
t.Fatalf("failed to create database with ancient backend") t.Fatalf("failed to create database with ancient backend")
} }
@@ -657,7 +657,7 @@ func TestHashesInRange(t *testing.T) {
func BenchmarkWriteAncientBlocks(b *testing.B) { func BenchmarkWriteAncientBlocks(b *testing.B) {
// Open freezer database. // Open freezer database.
frdir := b.TempDir() frdir := b.TempDir()
db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false, false, false, false, false) db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false, false, false, false)
if err != nil { if err != nil {
b.Fatalf("failed to create database with ancient backend") b.Fatalf("failed to create database with ancient backend")
} }
@@ -1001,7 +1001,7 @@ func TestHeadersRLPStorage(t *testing.T) {
// Have N headers in the freezer // Have N headers in the freezer
frdir := t.TempDir() frdir := t.TempDir()
db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false, false, false, false, false) db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false, false, false, false)
if err != nil { if err != nil {
t.Fatalf("failed to create database with ancient backend") t.Fatalf("failed to create database with ancient backend")
} }

View File

@@ -24,12 +24,12 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
) )
const ( const (
@@ -51,31 +51,25 @@ var (
// The background thread will keep moving ancient chain segments from key-value // The background thread will keep moving ancient chain segments from key-value
// database to flat files for saving space on live database. // database to flat files for saving space on live database.
type chainFreezer struct { type chainFreezer struct {
threshold atomic.Uint64 // Number of recent blocks not to freeze (params.FullImmutabilityThreshold apart from tests)
*Freezer *Freezer
quit chan struct{} quit chan struct{}
wg sync.WaitGroup wg sync.WaitGroup
trigger chan chan struct{} // Manual blocking freeze trigger, test determinism trigger chan chan struct{} // Manual blocking freeze trigger, test determinism
freezeEnv atomic.Value freezeEnv atomic.Value
multiDatabase bool
} }
// newChainFreezer initializes the freezer for ancient chain data. // newChainFreezer initializes the freezer for ancient chain data.
func newChainFreezer(datadir string, namespace string, readonly bool, offset uint64, multiDatabase bool) (*chainFreezer, error) { func newChainFreezer(datadir string, namespace string, readonly bool, offset uint64) (*chainFreezer, error) {
freezer, err := NewChainFreezer(datadir, namespace, readonly, offset) freezer, err := NewChainFreezer(datadir, namespace, readonly, offset)
if err != nil { if err != nil {
return nil, err return nil, err
} }
cf := chainFreezer{ return &chainFreezer{
Freezer: freezer, Freezer: freezer,
quit: make(chan struct{}), quit: make(chan struct{}),
trigger: make(chan chan struct{}), trigger: make(chan chan struct{}),
} }, nil
cf.threshold.Store(params.FullImmutabilityThreshold)
return &cf, nil
} }
// Close closes the chain freezer instance and terminates the background thread. // Close closes the chain freezer instance and terminates the background thread.
@@ -191,101 +185,29 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) {
continue continue
} }
var ( threshold, err := f.freezeThreshold(nfdb)
frozen uint64 if err != nil {
threshold uint64 backoff = true
first uint64 // the first block to freeze log.Debug("Current full block not old enough to freeze", "err", err)
last uint64 // the last block to freeze continue
}
frozen := f.frozen.Load()
hash common.Hash // Short circuit if the blocks below threshold are already frozen.
number *uint64 if frozen != 0 && frozen-1 >= threshold {
head *types.Header backoff = true
) log.Debug("Ancient blocks frozen already", "threshold", threshold, "frozen", frozen)
continue
// use finalized block as the chain freeze indicator was used for multiDatabase feature, if multiDatabase is false, keep 9W blocks in db
if f.multiDatabase {
threshold, err = f.freezeThreshold(nfdb)
if err != nil {
backoff = true
log.Debug("Current full block not old enough to freeze", "err", err)
continue
}
frozen = f.frozen.Load()
// Short circuit if the blocks below threshold are already frozen.
if frozen != 0 && frozen-1 >= threshold {
backoff = true
log.Debug("Ancient blocks frozen already", "threshold", threshold, "frozen", frozen)
continue
}
hash = ReadHeadBlockHash(nfdb)
if hash == (common.Hash{}) {
log.Debug("Current full block hash unavailable") // new chain, empty database
backoff = true
continue
}
number = ReadHeaderNumber(nfdb, hash)
if number == nil {
log.Error("Current full block number unavailable", "hash", hash)
backoff = true
continue
}
head = ReadHeader(nfdb, hash, *number)
if head == nil {
log.Error("Current full block unavailable", "number", *number, "hash", hash)
backoff = true
continue
}
first = frozen
last = threshold
if last-first+1 > freezerBatchLimit {
last = freezerBatchLimit + first - 1
}
} else {
// Retrieve the freezing threshold.
hash = ReadHeadBlockHash(nfdb)
if hash == (common.Hash{}) {
log.Debug("Current full block hash unavailable") // new chain, empty database
backoff = true
continue
}
number = ReadHeaderNumber(nfdb, hash)
threshold = f.threshold.Load()
frozen = f.frozen.Load()
switch {
case number == nil:
log.Error("Current full block number unavailable", "hash", hash)
backoff = true
continue
case *number < threshold:
log.Debug("Current full block not old enough to freeze", "number", *number, "hash", hash, "delay", threshold)
backoff = true
continue
case *number-threshold <= frozen:
log.Debug("Ancient blocks frozen already", "number", *number, "hash", hash, "frozen", frozen)
backoff = true
continue
}
head = ReadHeader(nfdb, hash, *number)
if head == nil {
log.Error("Current full block unavailable", "number", *number, "hash", hash)
backoff = true
continue
}
first, _ = f.Ancients()
last = *number - threshold
if last-first > freezerBatchLimit {
last = first + freezerBatchLimit
}
} }
// Seems we have data ready to be frozen, process in usable batches // Seems we have data ready to be frozen, process in usable batches
var ( var (
start = time.Now() start = time.Now()
first = frozen // the first block to freeze
last = threshold // the last block to freeze
) )
if last-first+1 > freezerBatchLimit {
last = freezerBatchLimit + first - 1
}
ancients, err := f.freezeRangeWithBlobs(nfdb, first, last) ancients, err := f.freezeRangeWithBlobs(nfdb, first, last)
if err != nil { if err != nil {
@@ -373,6 +295,24 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) {
log.Debug("Deep froze chain segment", context...) log.Debug("Deep froze chain segment", context...)
env, _ := f.freezeEnv.Load().(*ethdb.FreezerEnv) env, _ := f.freezeEnv.Load().(*ethdb.FreezerEnv)
hash := ReadHeadBlockHash(nfdb)
if hash == (common.Hash{}) {
log.Debug("Current full block hash unavailable") // new chain, empty database
backoff = true
continue
}
number := ReadHeaderNumber(nfdb, hash)
if number == nil {
log.Error("Current full block number unavailable", "hash", hash)
backoff = true
continue
}
head := ReadHeader(nfdb, hash, *number)
if head == nil {
log.Error("Current full block unavailable", "number", *number, "hash", hash)
backoff = true
continue
}
// try prune blob data after cancun fork // try prune blob data after cancun fork
if isCancun(env, head.Number, head.Time) { if isCancun(env, head.Number, head.Time) {
f.tryPruneBlobAncientTable(env, *number) f.tryPruneBlobAncientTable(env, *number)

View File

@@ -138,22 +138,13 @@ func (frdb *freezerdb) SetBlockStore(block ethdb.Database) {
frdb.blockStore = block frdb.blockStore = block
} }
func (frdb *freezerdb) HasSeparateBlockStore() bool {
return frdb.blockStore != nil
}
// Freeze is a helper method used for external testing to trigger and block until // Freeze is a helper method used for external testing to trigger and block until
// a freeze cycle completes, without having to sleep for a minute to trigger the // a freeze cycle completes, without having to sleep for a minute to trigger the
// automatic background run. // automatic background run.
func (frdb *freezerdb) Freeze(threshold uint64) error { func (frdb *freezerdb) Freeze() error {
if frdb.AncientStore.(*chainFreezer).readonly { if frdb.AncientStore.(*chainFreezer).readonly {
return errReadOnly return errReadOnly
} }
// Set the freezer threshold to a temporary value
defer func(old uint64) {
frdb.AncientStore.(*chainFreezer).threshold.Store(old)
}(frdb.AncientStore.(*chainFreezer).threshold.Load())
frdb.AncientStore.(*chainFreezer).threshold.Store(threshold)
// Trigger a freeze cycle and block until it's done // Trigger a freeze cycle and block until it's done
trigger := make(chan struct{}, 1) trigger := make(chan struct{}, 1)
frdb.AncientStore.(*chainFreezer).trigger <- trigger frdb.AncientStore.(*chainFreezer).trigger <- trigger
@@ -272,10 +263,6 @@ func (db *nofreezedb) SetBlockStore(block ethdb.Database) {
db.blockStore = block db.blockStore = block
} }
func (db *nofreezedb) HasSeparateBlockStore() bool {
return db.blockStore != nil
}
func (db *nofreezedb) BlockStoreReader() ethdb.Reader { func (db *nofreezedb) BlockStoreReader() ethdb.Reader {
if db.blockStore != nil { if db.blockStore != nil {
return db.blockStore return db.blockStore
@@ -371,7 +358,7 @@ func resolveChainFreezerDir(ancient string) string {
// value data store with a freezer moving immutable chain segments into cold // value data store with a freezer moving immutable chain segments into cold
// storage. The passed ancient indicates the path of root ancient directory // storage. The passed ancient indicates the path of root ancient directory
// where the chain freezer can be opened. // where the chain freezer can be opened.
func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace string, readonly, disableFreeze, isLastOffset, pruneAncientData, multiDatabase bool) (ethdb.Database, error) { func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace string, readonly, disableFreeze, isLastOffset, pruneAncientData bool) (ethdb.Database, error) {
var offset uint64 var offset uint64
// The offset of ancientDB should be handled differently in different scenarios. // The offset of ancientDB should be handled differently in different scenarios.
if isLastOffset { if isLastOffset {
@@ -407,7 +394,7 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace st
} }
// Create the idle freezer instance // Create the idle freezer instance
frdb, err := newChainFreezer(resolveChainFreezerDir(ancient), namespace, readonly, offset, multiDatabase) frdb, err := newChainFreezer(resolveChainFreezerDir(ancient), namespace, readonly, offset)
if err != nil { if err != nil {
printChainMetadata(db) printChainMetadata(db)
return nil, err return nil, err
@@ -588,8 +575,6 @@ type OpenOptions struct {
// Ephemeral means that filesystem sync operations should be avoided: data integrity in the face of // Ephemeral means that filesystem sync operations should be avoided: data integrity in the face of
// a crash is not important. This option should typically be used in tests. // a crash is not important. This option should typically be used in tests.
Ephemeral bool Ephemeral bool
MultiDataBase bool
} }
// openKeyValueDatabase opens a disk-based key-value database, e.g. leveldb or pebble. // openKeyValueDatabase opens a disk-based key-value database, e.g. leveldb or pebble.
@@ -640,7 +625,7 @@ func Open(o OpenOptions) (ethdb.Database, error) {
if len(o.AncientsDirectory) == 0 { if len(o.AncientsDirectory) == 0 {
return kvdb, nil return kvdb, nil
} }
frdb, err := NewDatabaseWithFreezer(kvdb, o.AncientsDirectory, o.Namespace, o.ReadOnly, o.DisableFreeze, o.IsLastOffset, o.PruneAncientData, o.MultiDataBase) frdb, err := NewDatabaseWithFreezer(kvdb, o.AncientsDirectory, o.Namespace, o.ReadOnly, o.DisableFreeze, o.IsLastOffset, o.PruneAncientData)
if err != nil { if err != nil {
kvdb.Close() kvdb.Close()
return nil, err return nil, err
@@ -784,7 +769,7 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error {
trieIter = db.StateStore().NewIterator(keyPrefix, nil) trieIter = db.StateStore().NewIterator(keyPrefix, nil)
defer trieIter.Release() defer trieIter.Release()
} }
if db.HasSeparateBlockStore() { if db.BlockStore() != db {
blockIter = db.BlockStore().NewIterator(keyPrefix, nil) blockIter = db.BlockStore().NewIterator(keyPrefix, nil)
defer blockIter.Release() defer blockIter.Release()
} }

View File

@@ -43,10 +43,6 @@ func (t *table) SetBlockStore(block ethdb.Database) {
panic("not implement") panic("not implement")
} }
func (t *table) HasSeparateBlockStore() bool {
panic("not implement")
}
// NewTable returns a database object that prefixes all keys with a given string. // NewTable returns a database object that prefixes all keys with a given string.
func NewTable(db ethdb.Database, prefix string) ethdb.Database { func NewTable(db ethdb.Database, prefix string) ethdb.Database {
return &table{ return &table{

View File

@@ -382,7 +382,7 @@ func (p *BlockPruner) backUpOldDb(name string, cache, handles int, namespace str
log.Info("chainDB opened successfully") log.Info("chainDB opened successfully")
// Get the number of items in old ancient db. // Get the number of items in old ancient db.
itemsOfAncient, err := chainDb.BlockStore().ItemAmountInAncient() itemsOfAncient, err := chainDb.ItemAmountInAncient()
log.Info("the number of items in ancientDB is ", "itemsOfAncient", itemsOfAncient) log.Info("the number of items in ancientDB is ", "itemsOfAncient", itemsOfAncient)
// If we can't access the freezer or it's empty, abort. // If we can't access the freezer or it's empty, abort.

View File

@@ -212,7 +212,7 @@ func TestTxIndexer(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
frdir := t.TempDir() frdir := t.TempDir()
db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false, false) db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false)
rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...), big.NewInt(0)) rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...), big.NewInt(0))
// Index the initial blocks from ancient store // Index the initial blocks from ancient store

View File

@@ -55,8 +55,6 @@ const (
// txReannoMaxNum is the maximum number of transactions a reannounce action can include. // txReannoMaxNum is the maximum number of transactions a reannounce action can include.
txReannoMaxNum = 1024 txReannoMaxNum = 1024
maxBufferSize = 1000 // maximum size of tx buffer
) )
var ( var (
@@ -246,10 +244,6 @@ type LegacyPool struct {
initDoneCh chan struct{} // is closed once the pool is initialized (for tests) initDoneCh chan struct{} // is closed once the pool is initialized (for tests)
changesSinceReorg int // A counter for how many drops we've performed in-between reorg. changesSinceReorg int // A counter for how many drops we've performed in-between reorg.
// A buffer to store transactions that would otherwise be discarded
buffer []*types.Transaction
bufferLock sync.Mutex
} }
type txpoolResetRequest struct { type txpoolResetRequest struct {
@@ -361,13 +355,11 @@ func (pool *LegacyPool) loop() {
evict = time.NewTicker(evictionInterval) evict = time.NewTicker(evictionInterval)
reannounce = time.NewTicker(reannounceInterval) reannounce = time.NewTicker(reannounceInterval)
journal = time.NewTicker(pool.config.Rejournal) journal = time.NewTicker(pool.config.Rejournal)
readd = time.NewTicker(time.Minute) // ticker to re-add buffered transactions periodically
) )
defer report.Stop() defer report.Stop()
defer evict.Stop() defer evict.Stop()
defer reannounce.Stop() defer reannounce.Stop()
defer journal.Stop() defer journal.Stop()
defer readd.Stop() // Stop the ticker when the loop exits
// Notify tests that the init phase is done // Notify tests that the init phase is done
close(pool.initDoneCh) close(pool.initDoneCh)
@@ -444,9 +436,6 @@ func (pool *LegacyPool) loop() {
} }
pool.mu.Unlock() pool.mu.Unlock()
} }
// Handle re-adding buffered transactions
case <-readd.C:
pool.readdBufferedTransactions()
} }
} }
} }
@@ -792,21 +781,12 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e
} }
}() }()
} }
// If the transaction pool is full, buffer underpriced transactions // If the transaction pool is full, discard underpriced transactions
if uint64(pool.all.Slots()+numSlots(tx)) > pool.config.GlobalSlots+pool.config.GlobalQueue { if uint64(pool.all.Slots()+numSlots(tx)) > pool.config.GlobalSlots+pool.config.GlobalQueue {
// If the new transaction is underpriced, buffer it // If the new transaction is underpriced, don't accept it
if !isLocal && pool.priced.Underpriced(tx) { if !isLocal && pool.priced.Underpriced(tx) {
log.Trace("Buffering underpriced transaction", "hash", hash, "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap()) log.Trace("Discarding underpriced transaction", "hash", hash, "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
underpricedTxMeter.Mark(1) underpricedTxMeter.Mark(1)
pool.bufferLock.Lock()
if len(pool.buffer) < maxBufferSize {
pool.buffer = append(pool.buffer, tx)
} else {
log.Warn("Buffer is full, discarding transaction", "hash", hash)
}
pool.bufferLock.Unlock()
return false, txpool.ErrUnderpriced return false, txpool.ErrUnderpriced
} }
@@ -824,16 +804,6 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e
// Otherwise if we can't make enough room for new one, abort the operation. // Otherwise if we can't make enough room for new one, abort the operation.
drop, success := pool.priced.Discard(pool.all.Slots()-int(pool.config.GlobalSlots+pool.config.GlobalQueue)+numSlots(tx), isLocal) drop, success := pool.priced.Discard(pool.all.Slots()-int(pool.config.GlobalSlots+pool.config.GlobalQueue)+numSlots(tx), isLocal)
// Add dropped transactions to the buffer
pool.bufferLock.Lock()
availableSpace := maxBufferSize - len(pool.buffer)
// Determine how many elements to take from drop
if availableSpace > len(drop) {
availableSpace = len(drop)
}
pool.buffer = append(pool.buffer, drop[:availableSpace]...)
pool.bufferLock.Unlock()
// Special case, we still can't make the room for the new remote one. // Special case, we still can't make the room for the new remote one.
if !isLocal && !success { if !isLocal && !success {
log.Trace("Discarding overflown transaction", "hash", hash) log.Trace("Discarding overflown transaction", "hash", hash)
@@ -1809,51 +1779,6 @@ func (pool *LegacyPool) SetMaxGas(maxGas uint64) {
pool.maxGas.Store(maxGas) pool.maxGas.Store(maxGas)
} }
func (pool *LegacyPool) readdBufferedTransactions() {
pool.mu.Lock()
defer pool.mu.Unlock()
// Check if there is space in the pool
if uint64(pool.all.Slots()) >= pool.config.GlobalSlots+pool.config.GlobalQueue {
return // No space available, skip re-adding
}
var readded []*types.Transaction
pool.bufferLock.Lock()
for _, tx := range pool.buffer {
// Check if adding this transaction will exceed the pool capacity
if uint64(pool.all.Slots()+numSlots(tx)) > pool.config.GlobalSlots+pool.config.GlobalQueue {
break // Stop if adding the transaction will exceed the pool capacity
}
if _, err := pool.add(tx, false); err == nil {
readded = append(readded, tx)
}
}
pool.bufferLock.Unlock()
// Remove successfully re-added transactions from the buffer
if len(readded) > 0 {
remaining := pool.buffer[:0]
for _, tx := range pool.buffer {
if !containsTransaction(readded, tx) {
remaining = append(remaining, tx)
}
}
pool.buffer = remaining
}
}
func containsTransaction(txs []*types.Transaction, tx *types.Transaction) bool {
for _, t := range txs {
if t.Hash() == tx.Hash() {
return true
}
}
return false
}
// addressByHeartbeat is an account address tagged with its last activity timestamp. // addressByHeartbeat is an account address tagged with its last activity timestamp.
type addressByHeartbeat struct { type addressByHeartbeat struct {
address common.Address address common.Address

View File

@@ -187,10 +187,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
chainConfig.HaberTime = config.OverrideHaber chainConfig.HaberTime = config.OverrideHaber
overrides.OverrideHaber = config.OverrideHaber overrides.OverrideHaber = config.OverrideHaber
} }
if config.OverrideBohr != nil {
chainConfig.BohrTime = config.OverrideBohr
overrides.OverrideBohr = config.OverrideBohr
}
if config.OverrideVerkle != nil { if config.OverrideVerkle != nil {
chainConfig.VerkleTime = config.OverrideVerkle chainConfig.VerkleTime = config.OverrideVerkle
overrides.OverrideVerkle = config.OverrideVerkle overrides.OverrideVerkle = config.OverrideVerkle
@@ -318,6 +314,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
// Permit the downloader to use the trie cache allowance during fast sync // Permit the downloader to use the trie cache allowance during fast sync
cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + cacheConfig.SnapshotLimit cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + cacheConfig.SnapshotLimit
if eth.handler, err = newHandler(&handlerConfig{ if eth.handler, err = newHandler(&handlerConfig{
NodeID: eth.p2pServer.Self().ID(),
Database: chainDb, Database: chainDb,
Chain: eth.blockchain, Chain: eth.blockchain,
TxPool: eth.txPool, TxPool: eth.txPool,

View File

@@ -60,7 +60,7 @@ func newTester(t *testing.T) *downloadTester {
// newTester creates a new downloader test mocker. // newTester creates a new downloader test mocker.
func newTesterWithNotification(t *testing.T, success func()) *downloadTester { func newTesterWithNotification(t *testing.T, success func()) *downloadTester {
freezer := t.TempDir() freezer := t.TempDir()
db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), freezer, "", false, false, false, false, false) db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), freezer, "", false, false, false, false)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@@ -194,9 +194,6 @@ type Config struct {
// OverrideHaber (TODO: remove after the fork) // OverrideHaber (TODO: remove after the fork)
OverrideHaber *uint64 `toml:",omitempty"` OverrideHaber *uint64 `toml:",omitempty"`
// OverrideBohr (TODO: remove after the fork)
OverrideBohr *uint64 `toml:",omitempty"`
// OverrideVerkle (TODO: remove after the fork) // OverrideVerkle (TODO: remove after the fork)
OverrideVerkle *uint64 `toml:",omitempty"` OverrideVerkle *uint64 `toml:",omitempty"`

View File

@@ -72,7 +72,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
RPCTxFeeCap float64 RPCTxFeeCap float64
OverrideCancun *uint64 `toml:",omitempty"` OverrideCancun *uint64 `toml:",omitempty"`
OverrideHaber *uint64 `toml:",omitempty"` OverrideHaber *uint64 `toml:",omitempty"`
OverrideBohr *uint64 `toml:",omitempty"`
OverrideVerkle *uint64 `toml:",omitempty"` OverrideVerkle *uint64 `toml:",omitempty"`
BlobExtraReserve uint64 BlobExtraReserve uint64
} }
@@ -132,7 +131,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
enc.RPCTxFeeCap = c.RPCTxFeeCap enc.RPCTxFeeCap = c.RPCTxFeeCap
enc.OverrideCancun = c.OverrideCancun enc.OverrideCancun = c.OverrideCancun
enc.OverrideHaber = c.OverrideHaber enc.OverrideHaber = c.OverrideHaber
enc.OverrideBohr = c.OverrideBohr
enc.OverrideVerkle = c.OverrideVerkle enc.OverrideVerkle = c.OverrideVerkle
enc.BlobExtraReserve = c.BlobExtraReserve enc.BlobExtraReserve = c.BlobExtraReserve
return &enc, nil return &enc, nil
@@ -196,7 +194,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
RPCTxFeeCap *float64 RPCTxFeeCap *float64
OverrideCancun *uint64 `toml:",omitempty"` OverrideCancun *uint64 `toml:",omitempty"`
OverrideHaber *uint64 `toml:",omitempty"` OverrideHaber *uint64 `toml:",omitempty"`
OverrideBohr *uint64 `toml:",omitempty"`
OverrideVerkle *uint64 `toml:",omitempty"` OverrideVerkle *uint64 `toml:",omitempty"`
BlobExtraReserve *uint64 BlobExtraReserve *uint64
} }
@@ -369,9 +366,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
if dec.OverrideHaber != nil { if dec.OverrideHaber != nil {
c.OverrideHaber = dec.OverrideHaber c.OverrideHaber = dec.OverrideHaber
} }
if dec.OverrideBohr != nil {
c.OverrideBohr = dec.OverrideBohr
}
if dec.OverrideVerkle != nil { if dec.OverrideVerkle != nil {
c.OverrideVerkle = dec.OverrideVerkle c.OverrideVerkle = dec.OverrideVerkle
} }

View File

@@ -34,6 +34,7 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/eth/fetcher" "github.com/ethereum/go-ethereum/eth/fetcher"
"github.com/ethereum/go-ethereum/eth/protocols/bsc" "github.com/ethereum/go-ethereum/eth/protocols/bsc"
@@ -45,6 +46,8 @@ import (
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/enode"
"golang.org/x/crypto/sha3"
) )
const ( const (
@@ -111,6 +114,7 @@ type votePool interface {
// handlerConfig is the collection of initialization parameters to create a full // handlerConfig is the collection of initialization parameters to create a full
// node network handler. // node network handler.
type handlerConfig struct { type handlerConfig struct {
NodeID enode.ID // P2P node ID used for tx propagation topology
Database ethdb.Database // Database for direct sync insertions Database ethdb.Database // Database for direct sync insertions
Chain *core.BlockChain // Blockchain to serve data from Chain *core.BlockChain // Blockchain to serve data from
TxPool txPool // Transaction pool to propagate from TxPool txPool // Transaction pool to propagate from
@@ -127,6 +131,7 @@ type handlerConfig struct {
} }
type handler struct { type handler struct {
nodeID enode.ID
networkID uint64 networkID uint64
forkFilter forkid.Filter // Fork ID filter, constant across the lifetime of the node forkFilter forkid.Filter // Fork ID filter, constant across the lifetime of the node
disablePeerTxBroadcast bool disablePeerTxBroadcast bool
@@ -184,6 +189,7 @@ func newHandler(config *handlerConfig) (*handler, error) {
config.PeerSet = newPeerSet() // Nicety initialization for tests config.PeerSet = newPeerSet() // Nicety initialization for tests
} }
h := &handler{ h := &handler{
nodeID: config.NodeID,
networkID: config.Network, networkID: config.Network,
forkFilter: forkid.NewFilter(config.Chain), forkFilter: forkid.NewFilter(config.Chain),
disablePeerTxBroadcast: config.DisablePeerTxBroadcast, disablePeerTxBroadcast: config.DisablePeerTxBroadcast,
@@ -852,25 +858,54 @@ func (h *handler) BroadcastTransactions(txs types.Transactions) {
annos = make(map[*ethPeer][]common.Hash) // Set peer->hash to announce annos = make(map[*ethPeer][]common.Hash) // Set peer->hash to announce
) )
// Broadcast transactions to a batch of peers not knowing about it // Broadcast transactions to a batch of peers not knowing about it
for _, tx := range txs { direct := big.NewInt(int64(math.Sqrt(float64(h.peers.len())))) // Approximate number of peers to broadcast to
peers := h.peers.peersWithoutTransaction(tx.Hash()) if direct.BitLen() == 0 {
direct = big.NewInt(1)
}
total := new(big.Int).Exp(direct, big.NewInt(2), nil) // Stabilise total peer count a bit based on sqrt peers
var numDirect int var (
signer = types.LatestSignerForChainID(h.chain.Config().ChainID) // Don't care about chain status, we just need *a* sender
hasher = sha3.NewLegacyKeccak256().(crypto.KeccakState)
hash = make([]byte, 32)
)
for _, tx := range txs {
var maybeDirect bool
switch { switch {
case tx.Type() == types.BlobTxType: case tx.Type() == types.BlobTxType:
blobTxs++ blobTxs++
case tx.Size() > txMaxBroadcastSize: case tx.Size() > txMaxBroadcastSize:
largeTxs++ largeTxs++
default: default:
numDirect = int(math.Sqrt(float64(len(peers)))) maybeDirect = true
} }
// Send the tx unconditionally to a subset of our peers // Send the transaction (if it's small enough) directly to a subset of
for _, peer := range peers[:numDirect] { // the peers that have not received it yet, ensuring that the flow of
txset[peer] = append(txset[peer], tx.Hash()) // transactions is groupped by account to (try and) avoid nonce gaps.
} //
// For the remaining peers, send announcement only // To do this, we hash the local enode IW with together with a peer's
for _, peer := range peers[numDirect:] { // enode ID together with the transaction sender and broadcast if
annos[peer] = append(annos[peer], tx.Hash()) // `sha(self, peer, sender) mod peers < sqrt(peers)`.
for _, peer := range h.peers.peersWithoutTransaction(tx.Hash()) {
var broadcast bool
if maybeDirect {
hasher.Reset()
hasher.Write(h.nodeID.Bytes())
hasher.Write(peer.Node().ID().Bytes())
from, _ := types.Sender(signer, tx) // Ignore error, we only use the addr as a propagation target splitter
hasher.Write(from.Bytes())
hasher.Read(hash)
if new(big.Int).Mod(new(big.Int).SetBytes(hash), total).Cmp(direct) < 0 {
broadcast = true
}
}
if broadcast {
txset[peer] = append(txset[peer], tx.Hash())
} else {
annos[peer] = append(annos[peer], tx.Hash())
}
} }
} }
for peer, hashes := range txset { for peer, hashes := range txset {

View File

@@ -258,7 +258,7 @@ func (c *mockParlia) CalcDifficulty(chain consensus.ChainHeaderReader, time uint
func newTestParliaHandlerAfterCancun(t *testing.T, config *params.ChainConfig, mode downloader.SyncMode, preCancunBlks, postCancunBlks uint64) *testHandler { func newTestParliaHandlerAfterCancun(t *testing.T, config *params.ChainConfig, mode downloader.SyncMode, preCancunBlks, postCancunBlks uint64) *testHandler {
// Have N headers in the freezer // Have N headers in the freezer
frdir := t.TempDir() frdir := t.TempDir()
db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false, false) db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false)
if err != nil { if err != nil {
t.Fatalf("failed to create database with ancient backend") t.Fatalf("failed to create database with ancient backend")
} }

View File

@@ -183,7 +183,6 @@ type StateStoreReader interface {
type BlockStore interface { type BlockStore interface {
BlockStore() Database BlockStore() Database
SetBlockStore(block Database) SetBlockStore(block Database)
HasSeparateBlockStore() bool
} }
type BlockStoreReader interface { type BlockStoreReader interface {

View File

@@ -44,10 +44,6 @@ func (db *Database) BlockStore() ethdb.Database {
return db return db
} }
func (db *Database) HasSeparateBlockStore() bool {
return false
}
func (db *Database) SetBlockStore(block ethdb.Database) { func (db *Database) SetBlockStore(block ethdb.Database) {
panic("not supported") panic("not supported")
} }

View File

@@ -773,13 +773,12 @@ func (n *Node) OpenDatabase(name string, cache, handles int, namespace string, r
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
} else { } else {
db, err = rawdb.Open(rawdb.OpenOptions{ db, err = rawdb.Open(rawdb.OpenOptions{
Type: n.config.DBEngine, Type: n.config.DBEngine,
Directory: n.ResolvePath(name), Directory: n.ResolvePath(name),
Namespace: namespace, Namespace: namespace,
Cache: cache, Cache: cache,
Handles: handles, Handles: handles,
ReadOnly: readonly, ReadOnly: readonly,
MultiDataBase: n.CheckIfMultiDataBase(),
}) })
} }

View File

@@ -153,7 +153,6 @@ var (
FeynmanFixTime: newUint64(1713419340), // 2024-04-18 05:49:00 AM UTC FeynmanFixTime: newUint64(1713419340), // 2024-04-18 05:49:00 AM UTC
CancunTime: newUint64(1718863500), // 2024-06-20 06:05:00 AM UTC CancunTime: newUint64(1718863500), // 2024-06-20 06:05:00 AM UTC
HaberTime: newUint64(1718863500), // 2024-06-20 06:05:00 AM UTC HaberTime: newUint64(1718863500), // 2024-06-20 06:05:00 AM UTC
BohrTime: nil,
Parlia: &ParliaConfig{ Parlia: &ParliaConfig{
Period: 3, Period: 3,
@@ -193,7 +192,6 @@ var (
FeynmanFixTime: newUint64(1711342800), // 2024-03-25 5:00:00 AM UTC FeynmanFixTime: newUint64(1711342800), // 2024-03-25 5:00:00 AM UTC
CancunTime: newUint64(1713330442), // 2024-04-17 05:07:22 AM UTC CancunTime: newUint64(1713330442), // 2024-04-17 05:07:22 AM UTC
HaberTime: newUint64(1716962820), // 2024-05-29 06:07:00 AM UTC HaberTime: newUint64(1716962820), // 2024-05-29 06:07:00 AM UTC
BohrTime: nil,
Parlia: &ParliaConfig{ Parlia: &ParliaConfig{
Period: 3, Period: 3,
@@ -234,7 +232,6 @@ var (
FeynmanFixTime: newUint64(0), FeynmanFixTime: newUint64(0),
CancunTime: newUint64(0), CancunTime: newUint64(0),
HaberTime: newUint64(0), HaberTime: newUint64(0),
BohrTime: newUint64(0),
Parlia: &ParliaConfig{ Parlia: &ParliaConfig{
Period: 3, Period: 3,
@@ -512,7 +509,6 @@ type ChainConfig struct {
FeynmanFixTime *uint64 `json:"feynmanFixTime,omitempty"` // FeynmanFix switch time (nil = no fork, 0 = already activated) FeynmanFixTime *uint64 `json:"feynmanFixTime,omitempty"` // FeynmanFix switch time (nil = no fork, 0 = already activated)
CancunTime *uint64 `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun) CancunTime *uint64 `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun)
HaberTime *uint64 `json:"haberTime,omitempty"` // Haber switch time (nil = no fork, 0 = already on haber) HaberTime *uint64 `json:"haberTime,omitempty"` // Haber switch time (nil = no fork, 0 = already on haber)
BohrTime *uint64 `json:"bohrTime,omitempty"` // Bohr switch time (nil = no fork, 0 = already on bohr)
PragueTime *uint64 `json:"pragueTime,omitempty"` // Prague switch time (nil = no fork, 0 = already on prague) PragueTime *uint64 `json:"pragueTime,omitempty"` // Prague switch time (nil = no fork, 0 = already on prague)
VerkleTime *uint64 `json:"verkleTime,omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle) VerkleTime *uint64 `json:"verkleTime,omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle)
@@ -623,12 +619,7 @@ func (c *ChainConfig) String() string {
HaberTime = big.NewInt(0).SetUint64(*c.HaberTime) HaberTime = big.NewInt(0).SetUint64(*c.HaberTime)
} }
var BohrTime *big.Int return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v,Luban: %v, Plato: %v, Hertz: %v, Hertzfix: %v, ShanghaiTime: %v, KeplerTime: %v, FeynmanTime: %v, FeynmanFixTime: %v, CancunTime: %v, HaberTime: %v, Engine: %v}",
if c.BohrTime != nil {
BohrTime = big.NewInt(0).SetUint64(*c.BohrTime)
}
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v,Luban: %v, Plato: %v, Hertz: %v, Hertzfix: %v, ShanghaiTime: %v, KeplerTime: %v, FeynmanTime: %v, FeynmanFixTime: %v, CancunTime: %v, HaberTime: %v, BohrTime: %v, Engine: %v}",
c.ChainID, c.ChainID,
c.HomesteadBlock, c.HomesteadBlock,
c.DAOForkBlock, c.DAOForkBlock,
@@ -666,7 +657,6 @@ func (c *ChainConfig) String() string {
FeynmanFixTime, FeynmanFixTime,
CancunTime, CancunTime,
HaberTime, HaberTime,
BohrTime,
engine, engine,
) )
} }
@@ -939,20 +929,6 @@ func (c *ChainConfig) IsHaber(num *big.Int, time uint64) bool {
return c.IsLondon(num) && isTimestampForked(c.HaberTime, time) return c.IsLondon(num) && isTimestampForked(c.HaberTime, time)
} }
// IsBohr returns whether time is either equal to the Bohr fork time or greater.
func (c *ChainConfig) IsBohr(num *big.Int, time uint64) bool {
return c.IsLondon(num) && isTimestampForked(c.BohrTime, time)
}
// IsOnBohr returns whether currentBlockTime is either equal to the Bohr fork time or greater firstly.
func (c *ChainConfig) IsOnBohr(currentBlockNumber *big.Int, lastBlockTime uint64, currentBlockTime uint64) bool {
lastBlockNumber := new(big.Int)
if currentBlockNumber.Cmp(big.NewInt(1)) >= 0 {
lastBlockNumber.Sub(currentBlockNumber, big.NewInt(1))
}
return !c.IsBohr(lastBlockNumber, lastBlockTime) && c.IsBohr(currentBlockNumber, currentBlockTime)
}
// IsPrague returns whether num is either equal to the Prague fork time or greater. // IsPrague returns whether num is either equal to the Prague fork time or greater.
func (c *ChainConfig) IsPrague(num *big.Int, time uint64) bool { func (c *ChainConfig) IsPrague(num *big.Int, time uint64) bool {
return c.IsLondon(num) && isTimestampForked(c.PragueTime, time) return c.IsLondon(num) && isTimestampForked(c.PragueTime, time)
@@ -1017,7 +993,6 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
{name: "feynmanFixTime", timestamp: c.FeynmanFixTime}, {name: "feynmanFixTime", timestamp: c.FeynmanFixTime},
{name: "cancunTime", timestamp: c.CancunTime}, {name: "cancunTime", timestamp: c.CancunTime},
{name: "haberTime", timestamp: c.HaberTime}, {name: "haberTime", timestamp: c.HaberTime},
{name: "bohrTime", timestamp: c.BohrTime},
{name: "pragueTime", timestamp: c.PragueTime, optional: true}, {name: "pragueTime", timestamp: c.PragueTime, optional: true},
{name: "verkleTime", timestamp: c.VerkleTime, optional: true}, {name: "verkleTime", timestamp: c.VerkleTime, optional: true},
} { } {
@@ -1348,7 +1323,7 @@ type Rules struct {
IsHertz bool IsHertz bool
IsHertzfix bool IsHertzfix bool
IsShanghai, IsKepler, IsFeynman, IsCancun, IsHaber bool IsShanghai, IsKepler, IsFeynman, IsCancun, IsHaber bool
IsBohr, IsPrague, IsVerkle bool IsPrague, IsVerkle bool
} }
// Rules ensures c's ChainID is not nil. // Rules ensures c's ChainID is not nil.
@@ -1384,7 +1359,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules
IsFeynman: c.IsFeynman(num, timestamp), IsFeynman: c.IsFeynman(num, timestamp),
IsCancun: c.IsCancun(num, timestamp), IsCancun: c.IsCancun(num, timestamp),
IsHaber: c.IsHaber(num, timestamp), IsHaber: c.IsHaber(num, timestamp),
IsBohr: c.IsBohr(num, timestamp),
IsPrague: c.IsPrague(num, timestamp), IsPrague: c.IsPrague(num, timestamp),
IsVerkle: c.IsVerkle(num, timestamp), IsVerkle: c.IsVerkle(num, timestamp),
} }

View File

@@ -98,7 +98,7 @@ type tester struct {
func newTester(t *testing.T, historyLimit uint64) *tester { func newTester(t *testing.T, historyLimit uint64) *tester {
var ( var (
disk, _ = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false, false) disk, _ = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false, false, false, false)
db = New(disk, &Config{ db = New(disk, &Config{
StateHistory: historyLimit, StateHistory: historyLimit,
CleanCacheSize: 256 * 1024, CleanCacheSize: 256 * 1024,

View File

@@ -152,13 +152,12 @@ func (kr *JournalKVReader) Close() {
} }
func newJournalWriter(file string, db ethdb.Database, journalType JournalType) JournalWriter { func newJournalWriter(file string, db ethdb.Database, journalType JournalType) JournalWriter {
log.Info("New journal writer", "path", file, "journalType", journalType)
if journalType == JournalKVType { if journalType == JournalKVType {
log.Info("New journal writer for journal kv")
return &JournalKVWriter{ return &JournalKVWriter{
diskdb: db, diskdb: db,
} }
} else { } else {
log.Info("New journal writer for journal file", "path", file)
fd, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) fd, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil { if err != nil {
return nil return nil
@@ -170,8 +169,8 @@ func newJournalWriter(file string, db ethdb.Database, journalType JournalType) J
} }
func newJournalReader(file string, db ethdb.Database, journalType JournalType) (JournalReader, error) { func newJournalReader(file string, db ethdb.Database, journalType JournalType) (JournalReader, error) {
log.Info("New journal reader", "path", file, "journalType", journalType)
if journalType == JournalKVType { if journalType == JournalKVType {
log.Info("New journal reader for journal kv")
journal := rawdb.ReadTrieJournal(db) journal := rawdb.ReadTrieJournal(db)
if len(journal) == 0 { if len(journal) == 0 {
return nil, errMissJournal return nil, errMissJournal
@@ -180,7 +179,6 @@ func newJournalReader(file string, db ethdb.Database, journalType JournalType) (
journalBuf: bytes.NewBuffer(journal), journalBuf: bytes.NewBuffer(journal),
}, nil }, nil
} else { } else {
log.Info("New journal reader for journal file", "path", file)
fd, err := os.Open(file) fd, err := os.Open(file)
if errors.Is(err, fs.ErrNotExist) { if errors.Is(err, fs.ErrNotExist) {
return nil, errMissJournal return nil, errMissJournal