mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-08 07:58:40 +00:00
core, trie, triedb: group 2^N binary trie nodes in serialization
This commit is contained in:
parent
b0ead5e17b
commit
f99258ad36
10 changed files with 65 additions and 28 deletions
|
|
@ -455,7 +455,7 @@ func BinKeys(ctx *cli.Context) error {
|
|||
db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.UBTDefaults)
|
||||
defer db.Close()
|
||||
|
||||
bt, err := genBinTrieFromAlloc(alloc, db)
|
||||
bt, err := genBinTrieFromAlloc(alloc, db, triedb.UBTDefaults.BinTrieGroupDepth)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error generating bt: %w", err)
|
||||
}
|
||||
|
|
@ -499,7 +499,7 @@ func BinTrieRoot(ctx *cli.Context) error {
|
|||
db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.UBTDefaults)
|
||||
defer db.Close()
|
||||
|
||||
bt, err := genBinTrieFromAlloc(alloc, db)
|
||||
bt, err := genBinTrieFromAlloc(alloc, db, triedb.UBTDefaults.BinTrieGroupDepth)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error generating bt: %w", err)
|
||||
}
|
||||
|
|
@ -509,8 +509,8 @@ func BinTrieRoot(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
// TODO(@CPerezz): Should this go to `bintrie` module?
|
||||
func genBinTrieFromAlloc(alloc core.GenesisAlloc, db database.NodeDatabase) (*bintrie.BinaryTrie, error) {
|
||||
bt, err := bintrie.NewBinaryTrie(types.EmptyBinaryHash, db)
|
||||
func genBinTrieFromAlloc(alloc core.GenesisAlloc, db database.NodeDatabase, groupDepth int) (*bintrie.BinaryTrie, error) {
|
||||
bt, err := bintrie.NewBinaryTrie(types.EmptyBinaryHash, db, groupDepth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ var (
|
|||
utils.StateHistoryFlag,
|
||||
utils.TrienodeHistoryFlag,
|
||||
utils.TrienodeHistoryFullValueCheckpointFlag,
|
||||
utils.BinTrieGroupDepthFlag,
|
||||
utils.LightKDFFlag,
|
||||
utils.EthRequiredBlocksFlag,
|
||||
utils.LegacyWhitelistFlag, // deprecated
|
||||
|
|
|
|||
|
|
@ -297,6 +297,12 @@ var (
|
|||
Value: ethconfig.Defaults.EnableStateSizeTracking,
|
||||
Category: flags.StateCategory,
|
||||
}
|
||||
BinTrieGroupDepthFlag = &cli.IntFlag{
|
||||
Name: "bintrie.groupdepth",
|
||||
Usage: "Number of levels per serialized group in binary trie (1-8, default 8). Lower values create smaller groups with more nodes.",
|
||||
Value: 8,
|
||||
Category: flags.StateCategory,
|
||||
}
|
||||
StateHistoryFlag = &cli.Uint64Flag{
|
||||
Name: "history.state",
|
||||
Usage: "Number of recent blocks to retain state history for, only relevant in state.scheme=path (default = 90,000 blocks, 0 = entire chain)",
|
||||
|
|
@ -1815,7 +1821,10 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
|||
cfg.TrienodeHistory = ctx.Int64(TrienodeHistoryFlag.Name)
|
||||
}
|
||||
if ctx.IsSet(TrienodeHistoryFullValueCheckpointFlag.Name) {
|
||||
cfg.NodeFullValueCheckpoint = uint32(ctx.Uint(TrienodeHistoryFullValueCheckpointFlag.Name))
|
||||
cfg.TrienodeHistory = ctx.Int64(TrienodeHistoryFullValueCheckpointFlag.Name)
|
||||
}
|
||||
if ctx.IsSet(BinTrieGroupDepthFlag.Name) {
|
||||
cfg.BinTrieGroupDepth = ctx.Int(BinTrieGroupDepthFlag.Name)
|
||||
}
|
||||
if ctx.IsSet(StateSchemeFlag.Name) {
|
||||
cfg.StateScheme = ctx.String(StateSchemeFlag.Name)
|
||||
|
|
@ -2433,6 +2442,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
|
|||
StateHistory: ctx.Uint64(StateHistoryFlag.Name),
|
||||
TrienodeHistory: ctx.Int64(TrienodeHistoryFlag.Name),
|
||||
NodeFullValueCheckpoint: uint32(ctx.Uint(TrienodeHistoryFullValueCheckpointFlag.Name)),
|
||||
BinTrieGroupDepth: ctx.Int(BinTrieGroupDepthFlag.Name),
|
||||
|
||||
// Disable transaction indexing/unindexing.
|
||||
TxLookupLimit: -1,
|
||||
|
|
|
|||
|
|
@ -170,9 +170,10 @@ type BlockChainConfig struct {
|
|||
TrieNoAsyncFlush bool // Whether the asynchronous buffer flushing is disallowed
|
||||
TrieJournalDirectory string // Directory path to the journal used for persisting trie data across node restarts
|
||||
|
||||
Preimages bool // Whether to store preimage of trie key to the disk
|
||||
StateScheme string // Scheme used to store ethereum states and merkle tree nodes on top
|
||||
ArchiveMode bool // Whether to enable the archive mode
|
||||
Preimages bool // Whether to store preimage of trie key to the disk
|
||||
StateScheme string // Scheme used to store ethereum states and merkle tree nodes on top
|
||||
ArchiveMode bool // Whether to enable the archive mode
|
||||
BinTrieGroupDepth int // Number of levels per serialized group in binary trie (1-8)
|
||||
|
||||
// Number of blocks from the chain head for which state histories are retained.
|
||||
// If set to 0, all state histories across the entire chain will be retained;
|
||||
|
|
@ -258,10 +259,11 @@ func (cfg BlockChainConfig) WithNoAsyncFlush(on bool) *BlockChainConfig {
|
|||
}
|
||||
|
||||
// triedbConfig derives the configures for trie database.
|
||||
func (cfg *BlockChainConfig) triedbConfig(isUBT bool) *triedb.Config {
|
||||
func (cfg *BlockChainConfig) triedbConfig(isVerkle bool) *triedb.Config {
|
||||
config := &triedb.Config{
|
||||
Preimages: cfg.Preimages,
|
||||
IsUBT: isUBT,
|
||||
Preimages: cfg.Preimages,
|
||||
IsVerkle: isVerkle,
|
||||
BinTrieGroupDepth: cfg.BinTrieGroupDepth,
|
||||
}
|
||||
if cfg.StateScheme == rawdb.HashScheme {
|
||||
config.HashDB = &hashdb.Config{
|
||||
|
|
|
|||
|
|
@ -237,6 +237,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
|||
StateHistory: config.StateHistory,
|
||||
TrienodeHistory: config.TrienodeHistory,
|
||||
NodeFullValueCheckpoint: config.NodeFullValueCheckpoint,
|
||||
BinTrieGroupDepth: config.BinTrieGroupDepth,
|
||||
StateScheme: scheme,
|
||||
HistoryPolicy: histPolicy,
|
||||
TxLookupLimit: int64(min(config.TransactionHistory, math.MaxInt64)),
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ var Defaults = Config{
|
|||
StateHistory: pathdb.Defaults.StateHistory,
|
||||
TrienodeHistory: pathdb.Defaults.TrienodeHistory,
|
||||
NodeFullValueCheckpoint: pathdb.Defaults.FullValueCheckpoint,
|
||||
BinTrieGroupDepth: 8, // byte-aligned groups by default
|
||||
DatabaseCache: 2048,
|
||||
TrieCleanCache: 614,
|
||||
TrieDirtyCache: 1024,
|
||||
|
|
@ -125,6 +126,11 @@ type Config struct {
|
|||
// consistent with persistent state.
|
||||
StateScheme string `toml:",omitempty"`
|
||||
|
||||
// BinTrieGroupDepth is the number of levels per serialized group in binary trie.
|
||||
// Valid values are 1-8, with 8 being the default (byte-aligned groups).
|
||||
// Lower values create smaller groups with more nodes.
|
||||
BinTrieGroupDepth int `toml:",omitempty"`
|
||||
|
||||
// RequiredBlocks is a set of block number -> hash mappings which must be in the
|
||||
// canonical chain of all remote peers. Setting the option makes geth verify the
|
||||
// presence of these blocks for every new peer connection.
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
|||
TrienodeHistory int64 `toml:",omitempty"`
|
||||
NodeFullValueCheckpoint uint32 `toml:",omitempty"`
|
||||
StateScheme string `toml:",omitempty"`
|
||||
BinTrieGroupDepth int `toml:",omitempty"`
|
||||
RequiredBlocks map[uint64]common.Hash `toml:"-"`
|
||||
SlowBlockThreshold time.Duration `toml:",omitempty"`
|
||||
SkipBcVersionCheck bool `toml:"-"`
|
||||
|
|
@ -87,6 +88,7 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
|||
enc.TrienodeHistory = c.TrienodeHistory
|
||||
enc.NodeFullValueCheckpoint = c.NodeFullValueCheckpoint
|
||||
enc.StateScheme = c.StateScheme
|
||||
enc.BinTrieGroupDepth = c.BinTrieGroupDepth
|
||||
enc.RequiredBlocks = c.RequiredBlocks
|
||||
enc.SlowBlockThreshold = c.SlowBlockThreshold
|
||||
enc.SkipBcVersionCheck = c.SkipBcVersionCheck
|
||||
|
|
@ -144,6 +146,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
|||
TrienodeHistory *int64 `toml:",omitempty"`
|
||||
NodeFullValueCheckpoint *uint32 `toml:",omitempty"`
|
||||
StateScheme *string `toml:",omitempty"`
|
||||
BinTrieGroupDepth *int `toml:",omitempty"`
|
||||
RequiredBlocks map[uint64]common.Hash `toml:"-"`
|
||||
SlowBlockThreshold *time.Duration `toml:",omitempty"`
|
||||
SkipBcVersionCheck *bool `toml:"-"`
|
||||
|
|
@ -234,6 +237,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
|||
if dec.StateScheme != nil {
|
||||
c.StateScheme = *dec.StateScheme
|
||||
}
|
||||
if dec.BinTrieGroupDepth != nil {
|
||||
c.BinTrieGroupDepth = *dec.BinTrieGroupDepth
|
||||
}
|
||||
if dec.RequiredBlocks != nil {
|
||||
c.RequiredBlocks = dec.RequiredBlocks
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ const (
|
|||
NodeTypeBytes = 1 // Size of node type prefix in serialization
|
||||
HashSize = 32 // Size of a hash in bytes
|
||||
StemBitmapSize = 32 // Size of the bitmap in a stem node (256 values = 32 bytes)
|
||||
|
||||
MaxGroupDepth = 8
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
|||
|
|
@ -107,9 +107,10 @@ func ChunkifyCode(code []byte) ChunkedCode {
|
|||
|
||||
// BinaryTrie is the implementation of https://eips.ethereum.org/EIPS/eip-7864.
|
||||
type BinaryTrie struct {
|
||||
store *nodeStore
|
||||
reader *trie.Reader
|
||||
tracer *trie.PrevalueTracer
|
||||
root BinaryNode
|
||||
reader *trie.Reader
|
||||
tracer *trie.PrevalueTracer
|
||||
groupDepth int // Number of levels per serialized group (1-8, default 8)
|
||||
}
|
||||
|
||||
// ToDot converts the binary trie to a DOT language representation. Useful for debugging.
|
||||
|
|
@ -119,15 +120,20 @@ func (t *BinaryTrie) ToDot() string {
|
|||
}
|
||||
|
||||
// NewBinaryTrie creates a new binary trie.
|
||||
func NewBinaryTrie(root common.Hash, db database.NodeDatabase) (*BinaryTrie, error) {
|
||||
// groupDepth specifies the number of levels per serialized group (1-8).
|
||||
func NewBinaryTrie(root common.Hash, db database.NodeDatabase, groupDepth int) (*BinaryTrie, error) {
|
||||
if groupDepth < 1 || groupDepth > MaxGroupDepth {
|
||||
groupDepth = MaxGroupDepth // Default to 8
|
||||
}
|
||||
reader, err := trie.NewReader(root, common.Hash{}, db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t := &BinaryTrie{
|
||||
store: newNodeStore(),
|
||||
reader: reader,
|
||||
tracer: trie.NewPrevalueTracer(),
|
||||
root: NewBinaryNode(),
|
||||
reader: reader,
|
||||
tracer: trie.NewPrevalueTracer(),
|
||||
groupDepth: groupDepth,
|
||||
}
|
||||
// Parse the root node if it's not empty
|
||||
if root != types.EmptyBinaryHash && root != types.EmptyRootHash {
|
||||
|
|
@ -341,9 +347,10 @@ func (t *BinaryTrie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error {
|
|||
// Copy creates a deep copy of the trie.
|
||||
func (t *BinaryTrie) Copy() *BinaryTrie {
|
||||
return &BinaryTrie{
|
||||
store: t.store.Copy(),
|
||||
reader: t.reader,
|
||||
tracer: t.tracer.Copy(),
|
||||
root: t.root.Copy(),
|
||||
reader: t.reader,
|
||||
tracer: t.tracer.Copy(),
|
||||
groupDepth: t.groupDepth,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,10 +31,11 @@ import (
|
|||
|
||||
// Config defines all necessary options for database.
|
||||
type Config struct {
|
||||
Preimages bool // Flag whether the preimage of node key is recorded
|
||||
IsUBT bool // Flag whether the db is holding a verkle tree
|
||||
HashDB *hashdb.Config // Configs for hash-based scheme
|
||||
PathDB *pathdb.Config // Configs for experimental path-based scheme
|
||||
Preimages bool // Flag whether the preimage of node key is recorded
|
||||
IsVerkle bool // Flag whether the db is holding a verkle tree
|
||||
BinTrieGroupDepth int // Number of levels per serialized group in binary trie (1-8, default 8)
|
||||
HashDB *hashdb.Config // Configs for hash-based scheme
|
||||
PathDB *pathdb.Config // Configs for experimental path-based scheme
|
||||
}
|
||||
|
||||
// HashDefaults represents a config for using hash-based scheme with
|
||||
|
|
@ -48,9 +49,10 @@ var HashDefaults = &Config{
|
|||
// UBTDefaults represents a config for holding verkle trie data
|
||||
// using path-based scheme with default settings.
|
||||
var UBTDefaults = &Config{
|
||||
Preimages: false,
|
||||
IsUBT: true,
|
||||
PathDB: pathdb.Defaults,
|
||||
Preimages: false,
|
||||
IsUBT: true,
|
||||
BinTrieGroupDepth: 8, // Default to byte-aligned groups
|
||||
PathDB: pathdb.Defaults,
|
||||
}
|
||||
|
||||
// backend defines the methods needed to access/update trie nodes in different
|
||||
|
|
|
|||
Loading…
Reference in a new issue