mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-12 01:41:36 +00:00
cmd, core, trie, triedb: split CachingDB into merkle + binary dbs.
This commit is contained in:
parent
58557cb463
commit
f0f1752249
42 changed files with 369 additions and 190 deletions
|
|
@ -146,7 +146,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
isEIP4762 = chainConfig.IsVerkle(big.NewInt(int64(pre.Env.Number)), pre.Env.Timestamp)
|
isEIP4762 = chainConfig.IsUBT(big.NewInt(int64(pre.Env.Number)), pre.Env.Timestamp)
|
||||||
statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre, isEIP4762)
|
statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre, isEIP4762)
|
||||||
signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp)
|
signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp)
|
||||||
gaspool = core.NewGasPool(pre.Env.GasLimit)
|
gaspool = core.NewGasPool(pre.Env.GasLimit)
|
||||||
|
|
@ -378,7 +378,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, isBintrie bool) *state.StateDB {
|
func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, isBintrie bool) *state.StateDB {
|
||||||
tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true, IsVerkle: isBintrie})
|
tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true, IsUBT: isBintrie})
|
||||||
sdb := state.NewDatabase(tdb, nil)
|
sdb := state.NewDatabase(tdb, nil)
|
||||||
|
|
||||||
root := types.EmptyRootHash
|
root := types.EmptyRootHash
|
||||||
|
|
|
||||||
|
|
@ -228,7 +228,7 @@ func Transition(ctx *cli.Context) error {
|
||||||
collector = make(Alloc)
|
collector = make(Alloc)
|
||||||
btleaves map[common.Hash]hexutil.Bytes
|
btleaves map[common.Hash]hexutil.Bytes
|
||||||
)
|
)
|
||||||
isBinary := chainConfig.IsVerkle(big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp)
|
isBinary := chainConfig.IsUBT(big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp)
|
||||||
if !isBinary {
|
if !isBinary {
|
||||||
s.DumpToCollector(collector, nil)
|
s.DumpToCollector(collector, nil)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -452,7 +452,7 @@ func BinKeys(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.VerkleDefaults)
|
db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.UBTDefaults)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
bt, err := genBinTrieFromAlloc(alloc, db)
|
bt, err := genBinTrieFromAlloc(alloc, db)
|
||||||
|
|
@ -496,7 +496,7 @@ func BinTrieRoot(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.VerkleDefaults)
|
db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.UBTDefaults)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
bt, err := genBinTrieFromAlloc(alloc, db)
|
bt, err := genBinTrieFromAlloc(alloc, db)
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ func convertToBinaryTrie(ctx *cli.Context) error {
|
||||||
defer srcTriedb.Close()
|
defer srcTriedb.Close()
|
||||||
|
|
||||||
destTriedb := triedb.NewDatabase(chaindb, &triedb.Config{
|
destTriedb := triedb.NewDatabase(chaindb, &triedb.Config{
|
||||||
IsVerkle: true,
|
IsUBT: true,
|
||||||
PathDB: &pathdb.Config{
|
PathDB: &pathdb.Config{
|
||||||
JournalDirectory: stack.ResolvePath("triedb-bintrie"),
|
JournalDirectory: stack.ResolvePath("triedb-bintrie"),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ func TestBintrieConvert(t *testing.T) {
|
||||||
defer srcTriedb2.Close()
|
defer srcTriedb2.Close()
|
||||||
|
|
||||||
destTriedb := triedb.NewDatabase(chaindb, &triedb.Config{
|
destTriedb := triedb.NewDatabase(chaindb, &triedb.Config{
|
||||||
IsVerkle: true,
|
IsUBT: true,
|
||||||
PathDB: pathdb.Defaults,
|
PathDB: pathdb.Defaults,
|
||||||
})
|
})
|
||||||
defer destTriedb.Close()
|
defer destTriedb.Close()
|
||||||
|
|
@ -190,7 +190,7 @@ func TestBintrieConvertDeleteSource(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
destTriedb := triedb.NewDatabase(chaindb, &triedb.Config{
|
destTriedb := triedb.NewDatabase(chaindb, &triedb.Config{
|
||||||
IsVerkle: true,
|
IsUBT: true,
|
||||||
PathDB: pathdb.Defaults,
|
PathDB: pathdb.Defaults,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ var (
|
||||||
utils.OverrideOsaka,
|
utils.OverrideOsaka,
|
||||||
utils.OverrideBPO1,
|
utils.OverrideBPO1,
|
||||||
utils.OverrideBPO2,
|
utils.OverrideBPO2,
|
||||||
utils.OverrideVerkle,
|
utils.OverrideUBT,
|
||||||
}, utils.DatabaseFlags),
|
}, utils.DatabaseFlags),
|
||||||
Description: `
|
Description: `
|
||||||
The init command initializes a new genesis block and definition for the network.
|
The init command initializes a new genesis block and definition for the network.
|
||||||
|
|
@ -297,15 +297,15 @@ func initGenesis(ctx *cli.Context) error {
|
||||||
v := ctx.Uint64(utils.OverrideBPO2.Name)
|
v := ctx.Uint64(utils.OverrideBPO2.Name)
|
||||||
overrides.OverrideBPO2 = &v
|
overrides.OverrideBPO2 = &v
|
||||||
}
|
}
|
||||||
if ctx.IsSet(utils.OverrideVerkle.Name) {
|
if ctx.IsSet(utils.OverrideUBT.Name) {
|
||||||
v := ctx.Uint64(utils.OverrideVerkle.Name)
|
v := ctx.Uint64(utils.OverrideUBT.Name)
|
||||||
overrides.OverrideVerkle = &v
|
overrides.OverrideUBT = &v
|
||||||
}
|
}
|
||||||
|
|
||||||
chaindb := utils.MakeChainDatabase(ctx, stack, false)
|
chaindb := utils.MakeChainDatabase(ctx, stack, false)
|
||||||
defer chaindb.Close()
|
defer chaindb.Close()
|
||||||
|
|
||||||
triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle())
|
triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsUBT())
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
_, hash, compatErr, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides, nil)
|
_, hash, compatErr, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides, nil)
|
||||||
|
|
|
||||||
|
|
@ -235,9 +235,9 @@ func makeFullNode(ctx *cli.Context) *node.Node {
|
||||||
v := ctx.Uint64(utils.OverrideBPO2.Name)
|
v := ctx.Uint64(utils.OverrideBPO2.Name)
|
||||||
cfg.Eth.OverrideBPO2 = &v
|
cfg.Eth.OverrideBPO2 = &v
|
||||||
}
|
}
|
||||||
if ctx.IsSet(utils.OverrideVerkle.Name) {
|
if ctx.IsSet(utils.OverrideUBT.Name) {
|
||||||
v := ctx.Uint64(utils.OverrideVerkle.Name)
|
v := ctx.Uint64(utils.OverrideUBT.Name)
|
||||||
cfg.Eth.OverrideVerkle = &v
|
cfg.Eth.OverrideUBT = &v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start metrics export if enabled.
|
// Start metrics export if enabled.
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ var (
|
||||||
utils.OverrideOsaka,
|
utils.OverrideOsaka,
|
||||||
utils.OverrideBPO1,
|
utils.OverrideBPO1,
|
||||||
utils.OverrideBPO2,
|
utils.OverrideBPO2,
|
||||||
utils.OverrideVerkle,
|
utils.OverrideUBT,
|
||||||
utils.OverrideGenesisFlag,
|
utils.OverrideGenesisFlag,
|
||||||
utils.EnablePersonal, // deprecated
|
utils.EnablePersonal, // deprecated
|
||||||
utils.TxPoolLocalsFlag,
|
utils.TxPoolLocalsFlag,
|
||||||
|
|
|
||||||
|
|
@ -264,9 +264,9 @@ var (
|
||||||
Usage: "Manually specify the bpo2 fork timestamp, overriding the bundled setting",
|
Usage: "Manually specify the bpo2 fork timestamp, overriding the bundled setting",
|
||||||
Category: flags.EthCategory,
|
Category: flags.EthCategory,
|
||||||
}
|
}
|
||||||
OverrideVerkle = &cli.Uint64Flag{
|
OverrideUBT = &cli.Uint64Flag{
|
||||||
Name: "override.verkle",
|
Name: "override.ubt",
|
||||||
Usage: "Manually specify the Verkle fork timestamp, overriding the bundled setting",
|
Usage: "Manually specify the UBT fork timestamp, overriding the bundled setting",
|
||||||
Category: flags.EthCategory,
|
Category: flags.EthCategory,
|
||||||
}
|
}
|
||||||
OverrideGenesisFlag = &cli.StringFlag{
|
OverrideGenesisFlag = &cli.StringFlag{
|
||||||
|
|
@ -2516,10 +2516,10 @@ func MakeConsolePreloads(ctx *cli.Context) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeTrieDatabase constructs a trie database based on the configured scheme.
|
// MakeTrieDatabase constructs a trie database based on the configured scheme.
|
||||||
func MakeTrieDatabase(ctx *cli.Context, stack *node.Node, disk ethdb.Database, preimage bool, readOnly bool, isVerkle bool) *triedb.Database {
|
func MakeTrieDatabase(ctx *cli.Context, stack *node.Node, disk ethdb.Database, preimage bool, readOnly bool, isUBT bool) *triedb.Database {
|
||||||
config := &triedb.Config{
|
config := &triedb.Config{
|
||||||
Preimages: preimage,
|
Preimages: preimage,
|
||||||
IsVerkle: isVerkle,
|
IsUBT: isUBT,
|
||||||
}
|
}
|
||||||
scheme, err := rawdb.ParseStateScheme(ctx.String(StateSchemeFlag.Name), disk)
|
scheme, err := rawdb.ParseStateScheme(ctx.String(StateSchemeFlag.Name), disk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,9 @@ var (
|
||||||
LondonBlock: big.NewInt(0),
|
LondonBlock: big.NewInt(0),
|
||||||
Ethash: new(params.EthashConfig),
|
Ethash: new(params.EthashConfig),
|
||||||
ShanghaiTime: u64(0),
|
ShanghaiTime: u64(0),
|
||||||
VerkleTime: u64(0),
|
UBTTime: u64(0),
|
||||||
TerminalTotalDifficulty: common.Big0,
|
TerminalTotalDifficulty: common.Big0,
|
||||||
EnableVerkleAtGenesis: true,
|
EnableUBTAtGenesis: true,
|
||||||
BlobScheduleConfig: ¶ms.BlobScheduleConfig{
|
BlobScheduleConfig: ¶ms.BlobScheduleConfig{
|
||||||
Verkle: params.DefaultPragueBlobConfig,
|
Verkle: params.DefaultPragueBlobConfig,
|
||||||
},
|
},
|
||||||
|
|
@ -188,7 +188,7 @@ func TestProcessParentBlockHash(t *testing.T) {
|
||||||
// block 1 parent hash is 0x0100....
|
// block 1 parent hash is 0x0100....
|
||||||
// block 2 parent hash is 0x0200....
|
// block 2 parent hash is 0x0200....
|
||||||
// etc
|
// etc
|
||||||
checkBlockHashes := func(statedb *state.StateDB, isVerkle bool) {
|
checkBlockHashes := func(statedb *state.StateDB, isUBT bool) {
|
||||||
statedb.SetNonce(params.HistoryStorageAddress, 1, tracing.NonceChangeUnspecified)
|
statedb.SetNonce(params.HistoryStorageAddress, 1, tracing.NonceChangeUnspecified)
|
||||||
statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode, tracing.CodeChangeUnspecified)
|
statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode, tracing.CodeChangeUnspecified)
|
||||||
// Process n blocks, from 1 .. num
|
// Process n blocks, from 1 .. num
|
||||||
|
|
@ -196,7 +196,7 @@ func TestProcessParentBlockHash(t *testing.T) {
|
||||||
for i := 1; i <= num; i++ {
|
for i := 1; i <= num; i++ {
|
||||||
header := &types.Header{ParentHash: common.Hash{byte(i)}, Number: big.NewInt(int64(i)), Difficulty: new(big.Int)}
|
header := &types.Header{ParentHash: common.Hash{byte(i)}, Number: big.NewInt(int64(i)), Difficulty: new(big.Int)}
|
||||||
chainConfig := params.MergedTestChainConfig
|
chainConfig := params.MergedTestChainConfig
|
||||||
if isVerkle {
|
if isUBT {
|
||||||
chainConfig = testVerkleChainConfig
|
chainConfig = testVerkleChainConfig
|
||||||
}
|
}
|
||||||
vmContext := NewEVMBlockContext(header, nil, new(common.Address))
|
vmContext := NewEVMBlockContext(header, nil, new(common.Address))
|
||||||
|
|
@ -205,9 +205,9 @@ func TestProcessParentBlockHash(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Read block hashes for block 0 .. num-1
|
// Read block hashes for block 0 .. num-1
|
||||||
for i := 0; i < num; i++ {
|
for i := 0; i < num; i++ {
|
||||||
have, want := getContractStoredBlockHash(statedb, uint64(i), isVerkle), common.Hash{byte(i + 1)}
|
have, want := getContractStoredBlockHash(statedb, uint64(i), isUBT), common.Hash{byte(i + 1)}
|
||||||
if have != want {
|
if have != want {
|
||||||
t.Errorf("block %d, verkle=%v, have parent hash %v, want %v", i, isVerkle, have, want)
|
t.Errorf("block %d, verkle=%v, have parent hash %v, want %v", i, isUBT, have, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -226,11 +226,11 @@ func TestProcessParentBlockHash(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// getContractStoredBlockHash is a utility method which reads the stored parent blockhash for block 'number'
|
// getContractStoredBlockHash is a utility method which reads the stored parent blockhash for block 'number'
|
||||||
func getContractStoredBlockHash(statedb *state.StateDB, number uint64, isVerkle bool) common.Hash {
|
func getContractStoredBlockHash(statedb *state.StateDB, number uint64, isUBT bool) common.Hash {
|
||||||
ringIndex := number % params.HistoryServeWindow
|
ringIndex := number % params.HistoryServeWindow
|
||||||
var key common.Hash
|
var key common.Hash
|
||||||
binary.BigEndian.PutUint64(key[24:], ringIndex)
|
binary.BigEndian.PutUint64(key[24:], ringIndex)
|
||||||
if isVerkle {
|
if isUBT {
|
||||||
return statedb.GetState(params.HistoryStorageAddress, key)
|
return statedb.GetState(params.HistoryStorageAddress, key)
|
||||||
}
|
}
|
||||||
return statedb.GetState(params.HistoryStorageAddress, key)
|
return statedb.GetState(params.HistoryStorageAddress, key)
|
||||||
|
|
|
||||||
|
|
@ -258,10 +258,10 @@ func (cfg BlockChainConfig) WithNoAsyncFlush(on bool) *BlockChainConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
// triedbConfig derives the configures for trie database.
|
// triedbConfig derives the configures for trie database.
|
||||||
func (cfg *BlockChainConfig) triedbConfig(isVerkle bool) *triedb.Config {
|
func (cfg *BlockChainConfig) triedbConfig(isUBT bool) *triedb.Config {
|
||||||
config := &triedb.Config{
|
config := &triedb.Config{
|
||||||
Preimages: cfg.Preimages,
|
Preimages: cfg.Preimages,
|
||||||
IsVerkle: isVerkle,
|
IsUBT: isUBT,
|
||||||
}
|
}
|
||||||
if cfg.StateScheme == rawdb.HashScheme {
|
if cfg.StateScheme == rawdb.HashScheme {
|
||||||
config.HashDB = &hashdb.Config{
|
config.HashDB = &hashdb.Config{
|
||||||
|
|
@ -378,7 +378,7 @@ func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open trie database with provided config
|
// Open trie database with provided config
|
||||||
enableVerkle, err := EnableVerkleAtGenesis(db, genesis)
|
enableVerkle, err := EnableUBTAtGenesis(db, genesis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti
|
||||||
|
|
||||||
// Merge the tx-local access event into the "block-local" one, in order to collect
|
// Merge the tx-local access event into the "block-local" one, in order to collect
|
||||||
// all values, so that the witness can be built.
|
// all values, so that the witness can be built.
|
||||||
if b.statedb.Database().TrieDB().IsVerkle() {
|
if b.statedb.Database().TrieDB().IsUBT() {
|
||||||
b.statedb.AccessEvents().Merge(evm.AccessEvents)
|
b.statedb.AccessEvents().Merge(evm.AccessEvents)
|
||||||
}
|
}
|
||||||
b.txs = append(b.txs, tx)
|
b.txs = append(b.txs, tx)
|
||||||
|
|
@ -392,7 +392,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
||||||
misc.ApplyDAOHardFork(statedb)
|
misc.ApplyDAOHardFork(statedb)
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.IsPrague(b.header.Number, b.header.Time) || config.IsVerkle(b.header.Number, b.header.Time) {
|
if config.IsPrague(b.header.Number, b.header.Time) || config.IsUBT(b.header.Number, b.header.Time) {
|
||||||
// EIP-2935
|
// EIP-2935
|
||||||
blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase)
|
blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase)
|
||||||
blockContext.Random = &common.Hash{} // enable post-merge instruction set
|
blockContext.Random = &common.Hash{} // enable post-merge instruction set
|
||||||
|
|
@ -430,8 +430,8 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
||||||
|
|
||||||
// Forcibly use hash-based state scheme for retaining all nodes in disk.
|
// Forcibly use hash-based state scheme for retaining all nodes in disk.
|
||||||
var triedbConfig *triedb.Config = triedb.HashDefaults
|
var triedbConfig *triedb.Config = triedb.HashDefaults
|
||||||
if config.IsVerkle(config.ChainID, 0) {
|
if config.IsUBT(config.ChainID, 0) {
|
||||||
triedbConfig = triedb.VerkleDefaults
|
triedbConfig = triedb.UBTDefaults
|
||||||
}
|
}
|
||||||
triedb := triedb.NewDatabase(db, triedbConfig)
|
triedb := triedb.NewDatabase(db, triedbConfig)
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
@ -479,8 +479,8 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
||||||
func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (ethdb.Database, []*types.Block, []types.Receipts) {
|
func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (ethdb.Database, []*types.Block, []types.Receipts) {
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
var triedbConfig *triedb.Config = triedb.HashDefaults
|
var triedbConfig *triedb.Config = triedb.HashDefaults
|
||||||
if genesis.Config != nil && genesis.Config.IsVerkle(genesis.Config.ChainID, 0) {
|
if genesis.Config != nil && genesis.Config.IsUBT(genesis.Config.ChainID, 0) {
|
||||||
triedbConfig = triedb.VerkleDefaults
|
triedbConfig = triedb.UBTDefaults
|
||||||
}
|
}
|
||||||
genesisTriedb := triedb.NewDatabase(db, triedbConfig)
|
genesisTriedb := triedb.NewDatabase(db, triedbConfig)
|
||||||
block, err := genesis.Commit(db, genesisTriedb, nil)
|
block, err := genesis.Commit(db, genesisTriedb, nil)
|
||||||
|
|
|
||||||
|
|
@ -129,21 +129,21 @@ func ReadGenesis(db ethdb.Database) (*Genesis, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// hashAlloc computes the state root according to the genesis specification.
|
// hashAlloc computes the state root according to the genesis specification.
|
||||||
func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {
|
func hashAlloc(ga *types.GenesisAlloc, isUBT bool) (common.Hash, error) {
|
||||||
// If a genesis-time verkle trie is requested, create a trie config
|
// If a genesis-time verkle trie is requested, create a trie config
|
||||||
// with the verkle trie enabled so that the tree can be initialized
|
// with the verkle trie enabled so that the tree can be initialized
|
||||||
// as such.
|
// as such.
|
||||||
var config *triedb.Config
|
var config *triedb.Config
|
||||||
if isVerkle {
|
if isUBT {
|
||||||
config = &triedb.Config{
|
config = &triedb.Config{
|
||||||
PathDB: pathdb.Defaults,
|
PathDB: pathdb.Defaults,
|
||||||
IsVerkle: true,
|
IsUBT: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Create an ephemeral in-memory database for computing hash,
|
// Create an ephemeral in-memory database for computing hash,
|
||||||
// all the derived states will be discarded to not pollute disk.
|
// all the derived states will be discarded to not pollute disk.
|
||||||
emptyRoot := types.EmptyRootHash
|
emptyRoot := types.EmptyRootHash
|
||||||
if isVerkle {
|
if isUBT {
|
||||||
emptyRoot = types.EmptyVerkleHash
|
emptyRoot = types.EmptyVerkleHash
|
||||||
}
|
}
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
|
|
@ -168,7 +168,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {
|
||||||
// generated states will be persisted into the given database.
|
// generated states will be persisted into the given database.
|
||||||
func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database, tracer *tracing.Hooks) (common.Hash, error) {
|
func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database, tracer *tracing.Hooks) (common.Hash, error) {
|
||||||
emptyRoot := types.EmptyRootHash
|
emptyRoot := types.EmptyRootHash
|
||||||
if triedb.IsVerkle() {
|
if triedb.IsUBT() {
|
||||||
emptyRoot = types.EmptyVerkleHash
|
emptyRoot = types.EmptyVerkleHash
|
||||||
}
|
}
|
||||||
statedb, err := state.New(emptyRoot, state.NewDatabase(triedb, nil))
|
statedb, err := state.New(emptyRoot, state.NewDatabase(triedb, nil))
|
||||||
|
|
@ -279,7 +279,7 @@ type ChainOverrides struct {
|
||||||
OverrideOsaka *uint64
|
OverrideOsaka *uint64
|
||||||
OverrideBPO1 *uint64
|
OverrideBPO1 *uint64
|
||||||
OverrideBPO2 *uint64
|
OverrideBPO2 *uint64
|
||||||
OverrideVerkle *uint64
|
OverrideUBT *uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply applies the chain overrides on the supplied chain config.
|
// apply applies the chain overrides on the supplied chain config.
|
||||||
|
|
@ -296,8 +296,8 @@ func (o *ChainOverrides) apply(cfg *params.ChainConfig) error {
|
||||||
if o.OverrideBPO2 != nil {
|
if o.OverrideBPO2 != nil {
|
||||||
cfg.BPO2Time = o.OverrideBPO2
|
cfg.BPO2Time = o.OverrideBPO2
|
||||||
}
|
}
|
||||||
if o.OverrideVerkle != nil {
|
if o.OverrideUBT != nil {
|
||||||
cfg.VerkleTime = o.OverrideVerkle
|
cfg.UBTTime = o.OverrideUBT
|
||||||
}
|
}
|
||||||
return cfg.CheckConfigForkOrder()
|
return cfg.CheckConfigForkOrder()
|
||||||
}
|
}
|
||||||
|
|
@ -469,15 +469,15 @@ func (g *Genesis) chainConfigOrDefault(ghash common.Hash, stored *params.ChainCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsVerkle indicates whether the state is already stored in a verkle
|
// IsUBT indicates whether the state is already stored in a verkle
|
||||||
// tree at genesis time.
|
// tree at genesis time.
|
||||||
func (g *Genesis) IsVerkle() bool {
|
func (g *Genesis) IsUBT() bool {
|
||||||
return g.Config.IsVerkleGenesis()
|
return g.Config.IsUBTGenesis()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToBlock returns the genesis block according to genesis specification.
|
// ToBlock returns the genesis block according to genesis specification.
|
||||||
func (g *Genesis) ToBlock() *types.Block {
|
func (g *Genesis) ToBlock() *types.Block {
|
||||||
root, err := hashAlloc(&g.Alloc, g.IsVerkle())
|
root, err := hashAlloc(&g.Alloc, g.IsUBT())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
@ -609,24 +609,24 @@ func (g *Genesis) MustCommit(db ethdb.Database, triedb *triedb.Database) *types.
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableVerkleAtGenesis indicates whether the verkle fork should be activated
|
// EnableUBTAtGenesis indicates whether the verkle fork should be activated
|
||||||
// at genesis. This is a temporary solution only for verkle devnet testing, where
|
// at genesis. This is a temporary solution only for verkle devnet testing, where
|
||||||
// verkle fork is activated at genesis, and the configured activation date has
|
// verkle fork is activated at genesis, and the configured activation date has
|
||||||
// already passed.
|
// already passed.
|
||||||
//
|
//
|
||||||
// In production networks (mainnet and public testnets), verkle activation always
|
// In production networks (mainnet and public testnets), verkle activation always
|
||||||
// occurs after the genesis block, making this function irrelevant in those cases.
|
// occurs after the genesis block, making this function irrelevant in those cases.
|
||||||
func EnableVerkleAtGenesis(db ethdb.Database, genesis *Genesis) (bool, error) {
|
func EnableUBTAtGenesis(db ethdb.Database, genesis *Genesis) (bool, error) {
|
||||||
if genesis != nil {
|
if genesis != nil {
|
||||||
if genesis.Config == nil {
|
if genesis.Config == nil {
|
||||||
return false, errGenesisNoConfig
|
return false, errGenesisNoConfig
|
||||||
}
|
}
|
||||||
return genesis.Config.EnableVerkleAtGenesis, nil
|
return genesis.Config.EnableUBTAtGenesis, nil
|
||||||
}
|
}
|
||||||
if ghash := rawdb.ReadCanonicalHash(db, 0); ghash != (common.Hash{}) {
|
if ghash := rawdb.ReadCanonicalHash(db, 0); ghash != (common.Hash{}) {
|
||||||
chainCfg := rawdb.ReadChainConfig(db, ghash)
|
chainCfg := rawdb.ReadChainConfig(db, ghash)
|
||||||
if chainCfg != nil {
|
if chainCfg != nil {
|
||||||
return chainCfg.EnableVerkleAtGenesis, nil
|
return chainCfg.EnableUBTAtGenesis, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
|
|
|
||||||
|
|
@ -285,9 +285,9 @@ func TestVerkleGenesisCommit(t *testing.T) {
|
||||||
CancunTime: &verkleTime,
|
CancunTime: &verkleTime,
|
||||||
PragueTime: &verkleTime,
|
PragueTime: &verkleTime,
|
||||||
OsakaTime: &verkleTime,
|
OsakaTime: &verkleTime,
|
||||||
VerkleTime: &verkleTime,
|
UBTTime: &verkleTime,
|
||||||
TerminalTotalDifficulty: big.NewInt(0),
|
TerminalTotalDifficulty: big.NewInt(0),
|
||||||
EnableVerkleAtGenesis: true,
|
EnableUBTAtGenesis: true,
|
||||||
Ethash: nil,
|
Ethash: nil,
|
||||||
Clique: nil,
|
Clique: nil,
|
||||||
BlobScheduleConfig: ¶ms.BlobScheduleConfig{
|
BlobScheduleConfig: ¶ms.BlobScheduleConfig{
|
||||||
|
|
@ -320,7 +320,7 @@ func TestVerkleGenesisCommit(t *testing.T) {
|
||||||
config.NoAsyncFlush = true
|
config.NoAsyncFlush = true
|
||||||
|
|
||||||
triedb := triedb.NewDatabase(db, &triedb.Config{
|
triedb := triedb.NewDatabase(db, &triedb.Config{
|
||||||
IsVerkle: true,
|
IsUBT: true,
|
||||||
PathDB: &config,
|
PathDB: &config,
|
||||||
})
|
})
|
||||||
block := genesis.MustCommit(db, triedb)
|
block := genesis.MustCommit(db, triedb)
|
||||||
|
|
@ -329,7 +329,7 @@ func TestVerkleGenesisCommit(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that the trie is verkle
|
// Test that the trie is verkle
|
||||||
if !triedb.IsVerkle() {
|
if !triedb.IsUBT() {
|
||||||
t.Fatalf("expected trie to be verkle")
|
t.Fatalf("expected trie to be verkle")
|
||||||
}
|
}
|
||||||
vdb := rawdb.NewTable(db, string(rawdb.VerklePrefix))
|
vdb := rawdb.NewTable(db, string(rawdb.VerklePrefix))
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ func (ts *TransitionState) Copy() *TransitionState {
|
||||||
|
|
||||||
// LoadTransitionState retrieves the Verkle transition state associated with
|
// LoadTransitionState retrieves the Verkle transition state associated with
|
||||||
// the given state root hash from the database.
|
// the given state root hash from the database.
|
||||||
func LoadTransitionState(db ethdb.KeyValueReader, root common.Hash, isVerkle bool) *TransitionState {
|
func LoadTransitionState(db ethdb.KeyValueReader, root common.Hash, isUBT bool) *TransitionState {
|
||||||
var ts *TransitionState
|
var ts *TransitionState
|
||||||
|
|
||||||
data, _ := rawdb.ReadVerkleTransitionState(db, root)
|
data, _ := rawdb.ReadVerkleTransitionState(db, root)
|
||||||
|
|
@ -97,10 +97,10 @@ func LoadTransitionState(db ethdb.KeyValueReader, root common.Hash, isVerkle boo
|
||||||
// Initialize the first transition state, with the "ended"
|
// Initialize the first transition state, with the "ended"
|
||||||
// field set to true if the database was created
|
// field set to true if the database was created
|
||||||
// as a verkle database.
|
// as a verkle database.
|
||||||
log.Debug("no transition state found, starting fresh", "verkle", isVerkle)
|
log.Debug("no transition state found, starting fresh", "verkle", isUBT)
|
||||||
|
|
||||||
// Start with a fresh state
|
// Start with a fresh state
|
||||||
ts = &TransitionState{Ended: isVerkle}
|
ts = &TransitionState{Ended: isUBT}
|
||||||
}
|
}
|
||||||
return ts
|
return ts
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/overlay"
|
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
@ -28,7 +27,6 @@ import (
|
||||||
"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/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"github.com/ethereum/go-ethereum/trie/bintrie"
|
|
||||||
"github.com/ethereum/go-ethereum/trie/transitiontrie"
|
"github.com/ethereum/go-ethereum/trie/transitiontrie"
|
||||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||||
"github.com/ethereum/go-ethereum/triedb"
|
"github.com/ethereum/go-ethereum/triedb"
|
||||||
|
|
@ -56,6 +54,21 @@ type Database interface {
|
||||||
// committing the changes to the underlying storage. It returns an error
|
// committing the changes to the underlying storage. It returns an error
|
||||||
// if the commit fails.
|
// if the commit fails.
|
||||||
Commit(update *stateUpdate) error
|
Commit(update *stateUpdate) error
|
||||||
|
|
||||||
|
// WithSnapshot configures the snapshot tree. This registration must be
|
||||||
|
// performed before the database is used.
|
||||||
|
WithSnapshot(snap *snapshot.Tree) Database
|
||||||
|
|
||||||
|
// Snapshot returns the underlying state snapshot.
|
||||||
|
Snapshot() *snapshot.Tree
|
||||||
|
|
||||||
|
// StateReader returns a state reader associated with the specified state root.
|
||||||
|
StateReader(stateRoot common.Hash) (StateReader, error)
|
||||||
|
|
||||||
|
// ReadersWithCacheStats creates a pair of state readers that share the same
|
||||||
|
// underlying state reader and internal state cache, while maintaining separate
|
||||||
|
// statistics respectively.
|
||||||
|
ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trie is a Ethereum Merkle Patricia trie.
|
// Trie is a Ethereum Merkle Patricia trie.
|
||||||
|
|
@ -139,46 +152,53 @@ type Trie interface {
|
||||||
// with the node that proves the absence of the key.
|
// with the node that proves the absence of the key.
|
||||||
Prove(key []byte, proofDb ethdb.KeyValueWriter) error
|
Prove(key []byte, proofDb ethdb.KeyValueWriter) error
|
||||||
|
|
||||||
// IsVerkle returns true if the trie is verkle-tree based
|
// IsUBT returns true if the trie is verkle-tree based
|
||||||
IsVerkle() bool
|
IsUBT() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CachingDB is an implementation of Database interface. It leverages both trie and
|
// MPTDB is an implementation of Database interface for Merkle Patricia Tries.
|
||||||
// state snapshot to provide functionalities for state access. It's meant to be a
|
// It leverages both trie and state snapshot to provide functionalities for state
|
||||||
// long-live object and has a few caches inside for sharing between blocks.
|
// access. It's meant to be a long-live object and has a few caches inside for
|
||||||
type CachingDB struct {
|
// sharing between blocks.
|
||||||
|
type MPTDB struct {
|
||||||
triedb *triedb.Database
|
triedb *triedb.Database
|
||||||
codedb *CodeDB
|
codedb *CodeDB
|
||||||
snap *snapshot.Tree
|
snap *snapshot.Tree
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDatabase creates a state database with the provided data sources.
|
// NewDatabase creates a state database with the provided data sources.
|
||||||
func NewDatabase(triedb *triedb.Database, codedb *CodeDB) *CachingDB {
|
func NewDatabase(tdb *triedb.Database, codedb *CodeDB) Database {
|
||||||
if codedb == nil {
|
if codedb == nil {
|
||||||
codedb = NewCodeDB(triedb.Disk())
|
codedb = NewCodeDB(tdb.Disk())
|
||||||
}
|
}
|
||||||
return &CachingDB{
|
if tdb.IsUBT() {
|
||||||
triedb: triedb,
|
return &UBTDB{
|
||||||
|
triedb: tdb,
|
||||||
|
codedb: codedb,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &MPTDB{
|
||||||
|
triedb: tdb,
|
||||||
codedb: codedb,
|
codedb: codedb,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDatabaseForTesting is similar to NewDatabase, but it initializes the caching
|
// NewDatabaseForTesting is similar to NewDatabase, but it initializes the caching
|
||||||
// db by using an ephemeral memory db with default config for testing.
|
// db by using an ephemeral memory db with default config for testing.
|
||||||
func NewDatabaseForTesting() *CachingDB {
|
func NewDatabaseForTesting() Database {
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
return NewDatabase(triedb.NewDatabase(db, nil), NewCodeDB(db))
|
return NewDatabase(triedb.NewDatabase(db, nil), NewCodeDB(db))
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithSnapshot configures the provided contract code cache. Note that this
|
// WithSnapshot configures the provided contract code cache. Note that this
|
||||||
// registration must be performed before the cachingDB is used.
|
// registration must be performed before the MPTDB is used.
|
||||||
func (db *CachingDB) WithSnapshot(snapshot *snapshot.Tree) *CachingDB {
|
func (db *MPTDB) WithSnapshot(snapshot *snapshot.Tree) Database {
|
||||||
db.snap = snapshot
|
db.snap = snapshot
|
||||||
return db
|
return db
|
||||||
}
|
}
|
||||||
|
|
||||||
// StateReader returns a state reader associated with the specified state root.
|
// StateReader returns a state reader associated with the specified state root.
|
||||||
func (db *CachingDB) StateReader(stateRoot common.Hash) (StateReader, error) {
|
func (db *MPTDB) StateReader(stateRoot common.Hash) (StateReader, error) {
|
||||||
var readers []StateReader
|
var readers []StateReader
|
||||||
|
|
||||||
// Configure the state reader using the standalone snapshot in hash mode.
|
// Configure the state reader using the standalone snapshot in hash mode.
|
||||||
|
|
@ -213,7 +233,7 @@ func (db *CachingDB) StateReader(stateRoot common.Hash) (StateReader, error) {
|
||||||
|
|
||||||
// Reader implements Database, returning a reader associated with the specified
|
// Reader implements Database, returning a reader associated with the specified
|
||||||
// state root.
|
// state root.
|
||||||
func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) {
|
func (db *MPTDB) Reader(stateRoot common.Hash) (Reader, error) {
|
||||||
sr, err := db.StateReader(stateRoot)
|
sr, err := db.StateReader(stateRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -224,7 +244,7 @@ func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) {
|
||||||
// ReadersWithCacheStats creates a pair of state readers that share the same
|
// ReadersWithCacheStats creates a pair of state readers that share the same
|
||||||
// underlying state reader and internal state cache, while maintaining separate
|
// underlying state reader and internal state cache, while maintaining separate
|
||||||
// statistics respectively.
|
// statistics respectively.
|
||||||
func (db *CachingDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, error) {
|
func (db *MPTDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, error) {
|
||||||
r, err := db.StateReader(stateRoot)
|
r, err := db.StateReader(stateRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
|
@ -236,18 +256,7 @@ func (db *CachingDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reade
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenTrie opens the main account trie at a specific root hash.
|
// OpenTrie opens the main account trie at a specific root hash.
|
||||||
func (db *CachingDB) OpenTrie(root common.Hash) (Trie, error) {
|
func (db *MPTDB) OpenTrie(root common.Hash) (Trie, error) {
|
||||||
if db.triedb.IsVerkle() {
|
|
||||||
ts := overlay.LoadTransitionState(db.TrieDB().Disk(), root, db.triedb.IsVerkle())
|
|
||||||
if ts.InTransition() {
|
|
||||||
panic("state tree transition isn't supported yet")
|
|
||||||
}
|
|
||||||
if ts.Transitioned() {
|
|
||||||
// Use BinaryTrie instead of VerkleTrie when IsVerkle is set
|
|
||||||
// (IsVerkle actually means Binary Trie mode in this codebase)
|
|
||||||
return bintrie.NewBinaryTrie(root, db.triedb)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
|
tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -256,10 +265,7 @@ func (db *CachingDB) OpenTrie(root common.Hash) (Trie, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenStorageTrie opens the storage trie of an account.
|
// OpenStorageTrie opens the storage trie of an account.
|
||||||
func (db *CachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) {
|
func (db *MPTDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) {
|
||||||
if db.triedb.IsVerkle() {
|
|
||||||
return self, nil
|
|
||||||
}
|
|
||||||
tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, crypto.Keccak256Hash(address.Bytes()), root), db.triedb)
|
tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, crypto.Keccak256Hash(address.Bytes()), root), db.triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -268,19 +274,19 @@ func (db *CachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Addre
|
||||||
}
|
}
|
||||||
|
|
||||||
// TrieDB retrieves any intermediate trie-node caching layer.
|
// TrieDB retrieves any intermediate trie-node caching layer.
|
||||||
func (db *CachingDB) TrieDB() *triedb.Database {
|
func (db *MPTDB) TrieDB() *triedb.Database {
|
||||||
return db.triedb
|
return db.triedb
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snapshot returns the underlying state snapshot.
|
// Snapshot returns the underlying state snapshot.
|
||||||
func (db *CachingDB) Snapshot() *snapshot.Tree {
|
func (db *MPTDB) Snapshot() *snapshot.Tree {
|
||||||
return db.snap
|
return db.snap
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit flushes all pending writes and finalizes the state transition,
|
// Commit flushes all pending writes and finalizes the state transition,
|
||||||
// committing the changes to the underlying storage. It returns an error
|
// committing the changes to the underlying storage. It returns an error
|
||||||
// if the commit fails.
|
// if the commit fails.
|
||||||
func (db *CachingDB) Commit(update *stateUpdate) error {
|
func (db *MPTDB) Commit(update *stateUpdate) error {
|
||||||
// Short circuit if nothing to commit
|
// Short circuit if nothing to commit
|
||||||
if update.empty() {
|
if update.empty() {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -313,8 +319,8 @@ func (db *CachingDB) Commit(update *stateUpdate) error {
|
||||||
|
|
||||||
// Iteratee returns a state iteratee associated with the specified state root,
|
// Iteratee returns a state iteratee associated with the specified state root,
|
||||||
// through which the account iterator and storage iterator can be created.
|
// through which the account iterator and storage iterator can be created.
|
||||||
func (db *CachingDB) Iteratee(root common.Hash) (Iteratee, error) {
|
func (db *MPTDB) Iteratee(root common.Hash) (Iteratee, error) {
|
||||||
return newStateIteratee(!db.triedb.IsVerkle(), root, db.triedb, db.snap)
|
return newStateIteratee(true, root, db.triedb, db.snap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// mustCopyTrie returns a deep-copied trie.
|
// mustCopyTrie returns a deep-copied trie.
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
||||||
"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/crypto"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
|
@ -300,3 +301,23 @@ func (db *HistoricDB) Commit(update *stateUpdate) error {
|
||||||
func (db *HistoricDB) Iteratee(root common.Hash) (Iteratee, error) {
|
func (db *HistoricDB) Iteratee(root common.Hash) (Iteratee, error) {
|
||||||
return nil, errors.New("not implemented")
|
return nil, errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithSnapshot is not supported by historic database.
|
||||||
|
func (db *HistoricDB) WithSnapshot(snap *snapshot.Tree) Database {
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
|
||||||
|
// Snapshot returns nil as historic database does not support snapshots.
|
||||||
|
func (db *HistoricDB) Snapshot() *snapshot.Tree {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StateReader is not supported by historic database; use Reader instead.
|
||||||
|
func (db *HistoricDB) StateReader(stateRoot common.Hash) (StateReader, error) {
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadersWithCacheStats is not supported by historic database.
|
||||||
|
func (db *HistoricDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, error) {
|
||||||
|
return nil, nil, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
|
||||||
152
core/state/database_ubt.go
Normal file
152
core/state/database_ubt.go
Normal file
|
|
@ -0,0 +1,152 @@
|
||||||
|
// Copyright 2017 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package state
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/trie/bintrie"
|
||||||
|
"github.com/ethereum/go-ethereum/triedb"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UBTDB is an implementation of Database interface for Universal Binary Tries.
|
||||||
|
// It provides the same functionality as MPTDB but uses binary tries for state
|
||||||
|
// storage instead of Merkle Patricia Tries.
|
||||||
|
type UBTDB struct {
|
||||||
|
triedb *triedb.Database
|
||||||
|
codedb *CodeDB
|
||||||
|
snap *snapshot.Tree
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSnapshot configures the snapshot tree. Note that this registration must
|
||||||
|
// be performed before the UBTDB is used.
|
||||||
|
func (db *UBTDB) WithSnapshot(snapshot *snapshot.Tree) Database {
|
||||||
|
db.snap = snapshot
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
|
||||||
|
// StateReader returns a state reader associated with the specified state root.
|
||||||
|
func (db *UBTDB) StateReader(stateRoot common.Hash) (StateReader, error) {
|
||||||
|
var readers []StateReader
|
||||||
|
|
||||||
|
// Configure the state reader using the path database in path mode.
|
||||||
|
// This reader offers improved performance but is optional and only
|
||||||
|
// partially useful if the snapshot data in path database is not
|
||||||
|
// fully generated.
|
||||||
|
if db.TrieDB().Scheme() == rawdb.PathScheme {
|
||||||
|
reader, err := db.triedb.StateReader(stateRoot)
|
||||||
|
if err == nil {
|
||||||
|
readers = append(readers, newFlatReader(reader))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Configure the trie reader, which is expected to be available as the
|
||||||
|
// gatekeeper unless the state is corrupted.
|
||||||
|
tr, err := newTrieReader(stateRoot, db.triedb)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
readers = append(readers, tr)
|
||||||
|
|
||||||
|
return newMultiStateReader(readers...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reader implements Database, returning a reader associated with the specified
|
||||||
|
// state root.
|
||||||
|
func (db *UBTDB) Reader(stateRoot common.Hash) (Reader, error) {
|
||||||
|
sr, err := db.StateReader(stateRoot)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return newReader(db.codedb.Reader(), sr), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadersWithCacheStats creates a pair of state readers that share the same
|
||||||
|
// underlying state reader and internal state cache, while maintaining separate
|
||||||
|
// statistics respectively.
|
||||||
|
func (db *UBTDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, error) {
|
||||||
|
r, err := db.StateReader(stateRoot)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
sr := newStateReaderWithCache(r)
|
||||||
|
ra := newReader(db.codedb.Reader(), newStateReaderWithStats(sr))
|
||||||
|
rb := newReader(db.codedb.Reader(), newStateReaderWithStats(sr))
|
||||||
|
return ra, rb, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenTrie opens the main account trie at a specific root hash.
|
||||||
|
func (db *UBTDB) OpenTrie(root common.Hash) (Trie, error) {
|
||||||
|
return bintrie.NewBinaryTrie(root, db.triedb)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenStorageTrie opens the storage trie of an account. In binary trie mode,
|
||||||
|
// all state objects share one unified trie, so the main trie is returned.
|
||||||
|
func (db *UBTDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) {
|
||||||
|
return self, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TrieDB retrieves any intermediate trie-node caching layer.
|
||||||
|
func (db *UBTDB) TrieDB() *triedb.Database {
|
||||||
|
return db.triedb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Snapshot returns the underlying state snapshot.
|
||||||
|
func (db *UBTDB) Snapshot() *snapshot.Tree {
|
||||||
|
return db.snap
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit flushes all pending writes and finalizes the state transition,
|
||||||
|
// committing the changes to the underlying storage. It returns an error
|
||||||
|
// if the commit fails.
|
||||||
|
func (db *UBTDB) Commit(update *stateUpdate) error {
|
||||||
|
// Short circuit if nothing to commit
|
||||||
|
if update.empty() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Commit dirty contract code if any exists
|
||||||
|
if len(update.codes) > 0 {
|
||||||
|
batch := db.codedb.NewBatchWithSize(len(update.codes))
|
||||||
|
for _, code := range update.codes {
|
||||||
|
batch.Put(code.hash, code.blob)
|
||||||
|
}
|
||||||
|
if err := batch.Commit(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If snapshotting is enabled, update the snapshot tree with this new version
|
||||||
|
if db.snap != nil && db.snap.Snapshot(update.originRoot) != nil {
|
||||||
|
if err := db.snap.Update(update.root, update.originRoot, update.accounts, update.storages); err != nil {
|
||||||
|
log.Warn("Failed to update snapshot tree", "from", update.originRoot, "to", update.root, "err", err)
|
||||||
|
}
|
||||||
|
// Keep 128 diff layers in the memory, persistent layer is 129th.
|
||||||
|
// - head layer is paired with HEAD state
|
||||||
|
// - head-1 layer is paired with HEAD-1 state
|
||||||
|
// - head-127 layer(bottom-most diff layer) is paired with HEAD-127 state
|
||||||
|
if err := db.snap.Cap(update.root, TriesInMemory); err != nil {
|
||||||
|
log.Warn("Failed to cap snapshot tree", "root", update.root, "layers", TriesInMemory, "err", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return db.triedb.Update(update.root, update.originRoot, update.blockNumber, update.nodes, update.stateSet())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iteratee returns a state iteratee associated with the specified state root,
|
||||||
|
// through which the account iterator and storage iterator can be created.
|
||||||
|
func (db *UBTDB) Iteratee(root common.Hash) (Iteratee, error) {
|
||||||
|
return newStateIteratee(false, root, db.triedb, db.snap)
|
||||||
|
}
|
||||||
|
|
@ -172,10 +172,10 @@ func newTrieReader(root common.Hash, db *triedb.Database) (*trieReader, error) {
|
||||||
tr Trie
|
tr Trie
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if !db.IsVerkle() {
|
if !db.IsUBT() {
|
||||||
tr, err = trie.NewStateTrie(trie.StateTrieID(root), db)
|
tr, err = trie.NewStateTrie(trie.StateTrieID(root), db)
|
||||||
} else {
|
} else {
|
||||||
// When IsVerkle() is true, create a BinaryTrie wrapped in TransitionTrie
|
// When IsUBT() is true, create a BinaryTrie wrapped in TransitionTrie
|
||||||
binTrie, binErr := bintrie.NewBinaryTrie(root, db)
|
binTrie, binErr := bintrie.NewBinaryTrie(root, db)
|
||||||
if binErr != nil {
|
if binErr != nil {
|
||||||
return nil, binErr
|
return nil, binErr
|
||||||
|
|
@ -259,7 +259,7 @@ func (r *trieReader) Storage(addr common.Address, key common.Hash) (common.Hash,
|
||||||
found bool
|
found bool
|
||||||
value common.Hash
|
value common.Hash
|
||||||
)
|
)
|
||||||
if r.db.IsVerkle() {
|
if r.db.IsUBT() {
|
||||||
tr = r.mainTrie
|
tr = r.mainTrie
|
||||||
} else {
|
} else {
|
||||||
tr, found = r.subTries[addr]
|
tr, found = r.subTries[addr]
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ func (s *stateObject) getTrie() (Trie, error) {
|
||||||
func (s *stateObject) getPrefetchedTrie() Trie {
|
func (s *stateObject) getPrefetchedTrie() Trie {
|
||||||
// If there's nothing to meaningfully return, let the user figure it out by
|
// If there's nothing to meaningfully return, let the user figure it out by
|
||||||
// pulling the trie from disk.
|
// pulling the trie from disk.
|
||||||
if (s.data.Root == types.EmptyRootHash && !s.db.db.TrieDB().IsVerkle()) || s.db.prefetcher == nil {
|
if (s.data.Root == types.EmptyRootHash && !s.db.db.TrieDB().IsUBT()) || s.db.prefetcher == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Attempt to retrieve the trie from the prefetcher
|
// Attempt to retrieve the trie from the prefetcher
|
||||||
|
|
@ -478,7 +478,7 @@ func (s *stateObject) commit() (*accountUpdate, *trienode.NodeSet, error) {
|
||||||
// The main account trie commit in stateDB.commit() already calls
|
// The main account trie commit in stateDB.commit() already calls
|
||||||
// CollectNodes on this trie, so calling Commit here again would
|
// CollectNodes on this trie, so calling Commit here again would
|
||||||
// redundantly traverse and serialize the entire tree per dirty account.
|
// redundantly traverse and serialize the entire tree per dirty account.
|
||||||
if s.db.GetTrie().IsVerkle() {
|
if s.db.GetTrie().IsUBT() {
|
||||||
s.origin = s.data.Copy()
|
s.origin = s.data.Copy()
|
||||||
return op, nil, nil
|
return op, nil, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ func NewWithReader(root common.Hash, db Database, reader Reader) (*StateDB, erro
|
||||||
accessList: newAccessList(),
|
accessList: newAccessList(),
|
||||||
transientStorage: newTransientStorage(),
|
transientStorage: newTransientStorage(),
|
||||||
}
|
}
|
||||||
if db.TrieDB().IsVerkle() {
|
if db.TrieDB().IsUBT() {
|
||||||
sdb.accessEvents = NewAccessEvents()
|
sdb.accessEvents = NewAccessEvents()
|
||||||
}
|
}
|
||||||
return sdb, nil
|
return sdb, nil
|
||||||
|
|
@ -858,7 +858,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
start = time.Now()
|
start = time.Now()
|
||||||
workers errgroup.Group
|
workers errgroup.Group
|
||||||
)
|
)
|
||||||
if s.db.TrieDB().IsVerkle() {
|
if s.db.TrieDB().IsUBT() {
|
||||||
// Bypass per-account updateTrie() for binary trie. In binary trie mode
|
// Bypass per-account updateTrie() for binary trie. In binary trie mode
|
||||||
// there is only one unified trie (OpenStorageTrie returns self), so the
|
// there is only one unified trie (OpenStorageTrie returns self), so the
|
||||||
// per-account trie setup in updateTrie() (getPrefetchedTrie, getTrie,
|
// per-account trie setup in updateTrie() (getPrefetchedTrie, getTrie,
|
||||||
|
|
@ -924,7 +924,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
// If witness building is enabled, gather all the read-only accesses.
|
// If witness building is enabled, gather all the read-only accesses.
|
||||||
// Skip witness collection in Verkle mode, they will be gathered
|
// Skip witness collection in Verkle mode, they will be gathered
|
||||||
// together at the end.
|
// together at the end.
|
||||||
if s.witness != nil && !s.db.TrieDB().IsVerkle() {
|
if s.witness != nil && !s.db.TrieDB().IsUBT() {
|
||||||
// Pull in anything that has been accessed before destruction
|
// Pull in anything that has been accessed before destruction
|
||||||
for _, obj := range s.stateObjectsDestruct {
|
for _, obj := range s.stateObjectsDestruct {
|
||||||
// Skip any objects that haven't touched their storage
|
// Skip any objects that haven't touched their storage
|
||||||
|
|
@ -965,7 +965,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
// only a single trie is used for state hashing. Replacing a non-nil verkle tree
|
// only a single trie is used for state hashing. Replacing a non-nil verkle tree
|
||||||
// here could result in losing uncommitted changes from storage.
|
// here could result in losing uncommitted changes from storage.
|
||||||
start = time.Now()
|
start = time.Now()
|
||||||
if s.prefetcher != nil && !s.db.TrieDB().IsVerkle() {
|
if s.prefetcher != nil && !s.db.TrieDB().IsUBT() {
|
||||||
if trie := s.prefetcher.trie(common.Hash{}, s.originalRoot); trie == nil {
|
if trie := s.prefetcher.trie(common.Hash{}, s.originalRoot); trie == nil {
|
||||||
log.Error("Failed to retrieve account pre-fetcher trie")
|
log.Error("Failed to retrieve account pre-fetcher trie")
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1126,7 +1126,7 @@ func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*acco
|
||||||
deletes[addrHash] = op
|
deletes[addrHash] = op
|
||||||
|
|
||||||
// Short circuit if the origin storage was empty.
|
// Short circuit if the origin storage was empty.
|
||||||
if prev.Root == types.EmptyRootHash || s.db.TrieDB().IsVerkle() {
|
if prev.Root == types.EmptyRootHash || s.db.TrieDB().IsUBT() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if noStorageWiping {
|
if noStorageWiping {
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ type triePrefetcher struct {
|
||||||
func newTriePrefetcher(db Database, root common.Hash, namespace string, noreads bool) *triePrefetcher {
|
func newTriePrefetcher(db Database, root common.Hash, namespace string, noreads bool) *triePrefetcher {
|
||||||
prefix := triePrefetchMetricsPrefix + namespace
|
prefix := triePrefetchMetricsPrefix + namespace
|
||||||
return &triePrefetcher{
|
return &triePrefetcher{
|
||||||
verkle: db.TrieDB().IsVerkle(),
|
verkle: db.TrieDB().IsUBT(),
|
||||||
db: db,
|
db: db,
|
||||||
root: root,
|
root: root,
|
||||||
fetchers: make(map[string]*subfetcher), // Active prefetchers use the fetchers map
|
fetchers: make(map[string]*subfetcher), // Active prefetchers use the fetchers map
|
||||||
|
|
@ -342,7 +342,7 @@ func (sf *subfetcher) terminate(async bool) {
|
||||||
func (sf *subfetcher) openTrie() error {
|
func (sf *subfetcher) openTrie() error {
|
||||||
// Open the verkle tree if the sub-fetcher is in verkle mode. Note, there is
|
// Open the verkle tree if the sub-fetcher is in verkle mode. Note, there is
|
||||||
// only a single fetcher for verkle.
|
// only a single fetcher for verkle.
|
||||||
if sf.db.TrieDB().IsVerkle() {
|
if sf.db.TrieDB().IsUBT() {
|
||||||
tr, err := sf.db.OpenTrie(sf.state)
|
tr, err := sf.db.OpenTrie(sf.state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Trie prefetcher failed opening verkle trie", "root", sf.root, "err", err)
|
log.Warn("Trie prefetcher failed opening verkle trie", "root", sf.root, "err", err)
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ func TestUseAfterTerminate(t *testing.T) {
|
||||||
|
|
||||||
func TestVerklePrefetcher(t *testing.T) {
|
func TestVerklePrefetcher(t *testing.T) {
|
||||||
disk := rawdb.NewMemoryDatabase()
|
disk := rawdb.NewMemoryDatabase()
|
||||||
db := triedb.NewDatabase(disk, triedb.VerkleDefaults)
|
db := triedb.NewDatabase(disk, triedb.UBTDefaults)
|
||||||
sdb := NewDatabase(db, nil)
|
sdb := NewDatabase(db, nil)
|
||||||
|
|
||||||
state, err := New(types.EmptyRootHash, sdb)
|
state, err := New(types.EmptyRootHash, sdb)
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ func (p *StateProcessor) Process(ctx context.Context, block *types.Block, stated
|
||||||
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||||
ProcessBeaconBlockRoot(*beaconRoot, evm)
|
ProcessBeaconBlockRoot(*beaconRoot, evm)
|
||||||
}
|
}
|
||||||
if config.IsPrague(block.Number(), block.Time()) || config.IsVerkle(block.Number(), block.Time()) {
|
if config.IsPrague(block.Number(), block.Time()) || config.IsUBT(block.Number(), block.Time()) {
|
||||||
ProcessParentBlockHash(block.ParentHash(), evm)
|
ProcessParentBlockHash(block.ParentHash(), evm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -182,7 +182,7 @@ func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB,
|
||||||
}
|
}
|
||||||
// Merge the tx-local access event into the "block-local" one, in order to collect
|
// Merge the tx-local access event into the "block-local" one, in order to collect
|
||||||
// all values, so that the witness can be built.
|
// all values, so that the witness can be built.
|
||||||
if statedb.Database().TrieDB().IsVerkle() {
|
if statedb.Database().TrieDB().IsUBT() {
|
||||||
statedb.AccessEvents().Merge(evm.AccessEvents)
|
statedb.AccessEvents().Merge(evm.AccessEvents)
|
||||||
}
|
}
|
||||||
return MakeReceipt(evm, result, statedb, blockNumber, blockHash, blockTime, tx, gp.CumulativeUsed(), root), nil
|
return MakeReceipt(evm, result, statedb, blockNumber, blockHash, blockTime, tx, gp.CumulativeUsed(), root), nil
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ func init() {
|
||||||
|
|
||||||
func activePrecompiledContracts(rules params.Rules) PrecompiledContracts {
|
func activePrecompiledContracts(rules params.Rules) PrecompiledContracts {
|
||||||
switch {
|
switch {
|
||||||
case rules.IsVerkle:
|
case rules.IsUBT:
|
||||||
return PrecompiledContractsVerkle
|
return PrecompiledContractsVerkle
|
||||||
case rules.IsOsaka:
|
case rules.IsOsaka:
|
||||||
return PrecompiledContractsOsaka
|
return PrecompiledContractsOsaka
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainCon
|
||||||
evm.table = &amsterdamInstructionSet
|
evm.table = &amsterdamInstructionSet
|
||||||
case evm.chainRules.IsOsaka:
|
case evm.chainRules.IsOsaka:
|
||||||
evm.table = &osakaInstructionSet
|
evm.table = &osakaInstructionSet
|
||||||
case evm.chainRules.IsVerkle:
|
case evm.chainRules.IsUBT:
|
||||||
// TODO replace with proper instruction set when fork is specified
|
// TODO replace with proper instruction set when fork is specified
|
||||||
evm.table = &verkleInstructionSet
|
evm.table = &verkleInstructionSet
|
||||||
case evm.chainRules.IsPrague:
|
case evm.chainRules.IsPrague:
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ import (
|
||||||
// the rules.
|
// the rules.
|
||||||
func LookupInstructionSet(rules params.Rules) (JumpTable, error) {
|
func LookupInstructionSet(rules params.Rules) (JumpTable, error) {
|
||||||
switch {
|
switch {
|
||||||
case rules.IsVerkle:
|
case rules.IsUBT:
|
||||||
return newCancunInstructionSet(), errors.New("verkle-fork not defined yet")
|
return newCancunInstructionSet(), errors.New("verkle-fork not defined yet")
|
||||||
case rules.IsAmsterdam:
|
case rules.IsAmsterdam:
|
||||||
return newAmsterdamInstructionSet(), nil
|
return newAmsterdamInstructionSet(), nil
|
||||||
|
|
|
||||||
|
|
@ -277,8 +277,8 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||||
if config.OverrideBPO2 != nil {
|
if config.OverrideBPO2 != nil {
|
||||||
overrides.OverrideBPO2 = config.OverrideBPO2
|
overrides.OverrideBPO2 = config.OverrideBPO2
|
||||||
}
|
}
|
||||||
if config.OverrideVerkle != nil {
|
if config.OverrideUBT != nil {
|
||||||
overrides.OverrideVerkle = config.OverrideVerkle
|
overrides.OverrideUBT = config.OverrideUBT
|
||||||
}
|
}
|
||||||
options.Overrides = &overrides
|
options.Overrides = &overrides
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -200,8 +200,8 @@ type Config struct {
|
||||||
// OverrideBPO2 (TODO: remove after the fork)
|
// OverrideBPO2 (TODO: remove after the fork)
|
||||||
OverrideBPO2 *uint64 `toml:",omitempty"`
|
OverrideBPO2 *uint64 `toml:",omitempty"`
|
||||||
|
|
||||||
// OverrideVerkle (TODO: remove after the fork)
|
// OverrideUBT (TODO: remove after the fork)
|
||||||
OverrideVerkle *uint64 `toml:",omitempty"`
|
OverrideUBT *uint64 `toml:",omitempty"`
|
||||||
|
|
||||||
// EIP-7966: eth_sendRawTransactionSync timeouts
|
// EIP-7966: eth_sendRawTransactionSync timeouts
|
||||||
TxSyncDefaultTimeout time.Duration `toml:",omitempty"`
|
TxSyncDefaultTimeout time.Duration `toml:",omitempty"`
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
OverrideOsaka *uint64 `toml:",omitempty"`
|
OverrideOsaka *uint64 `toml:",omitempty"`
|
||||||
OverrideBPO1 *uint64 `toml:",omitempty"`
|
OverrideBPO1 *uint64 `toml:",omitempty"`
|
||||||
OverrideBPO2 *uint64 `toml:",omitempty"`
|
OverrideBPO2 *uint64 `toml:",omitempty"`
|
||||||
OverrideVerkle *uint64 `toml:",omitempty"`
|
OverrideUBT *uint64 `toml:",omitempty"`
|
||||||
TxSyncDefaultTimeout time.Duration `toml:",omitempty"`
|
TxSyncDefaultTimeout time.Duration `toml:",omitempty"`
|
||||||
TxSyncMaxTimeout time.Duration `toml:",omitempty"`
|
TxSyncMaxTimeout time.Duration `toml:",omitempty"`
|
||||||
RangeLimit uint64 `toml:",omitempty"`
|
RangeLimit uint64 `toml:",omitempty"`
|
||||||
|
|
@ -117,7 +117,7 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
enc.OverrideOsaka = c.OverrideOsaka
|
enc.OverrideOsaka = c.OverrideOsaka
|
||||||
enc.OverrideBPO1 = c.OverrideBPO1
|
enc.OverrideBPO1 = c.OverrideBPO1
|
||||||
enc.OverrideBPO2 = c.OverrideBPO2
|
enc.OverrideBPO2 = c.OverrideBPO2
|
||||||
enc.OverrideVerkle = c.OverrideVerkle
|
enc.OverrideUBT = c.OverrideUBT
|
||||||
enc.TxSyncDefaultTimeout = c.TxSyncDefaultTimeout
|
enc.TxSyncDefaultTimeout = c.TxSyncDefaultTimeout
|
||||||
enc.TxSyncMaxTimeout = c.TxSyncMaxTimeout
|
enc.TxSyncMaxTimeout = c.TxSyncMaxTimeout
|
||||||
enc.RangeLimit = c.RangeLimit
|
enc.RangeLimit = c.RangeLimit
|
||||||
|
|
@ -174,7 +174,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
OverrideOsaka *uint64 `toml:",omitempty"`
|
OverrideOsaka *uint64 `toml:",omitempty"`
|
||||||
OverrideBPO1 *uint64 `toml:",omitempty"`
|
OverrideBPO1 *uint64 `toml:",omitempty"`
|
||||||
OverrideBPO2 *uint64 `toml:",omitempty"`
|
OverrideBPO2 *uint64 `toml:",omitempty"`
|
||||||
OverrideVerkle *uint64 `toml:",omitempty"`
|
OverrideUBT *uint64 `toml:",omitempty"`
|
||||||
TxSyncDefaultTimeout *time.Duration `toml:",omitempty"`
|
TxSyncDefaultTimeout *time.Duration `toml:",omitempty"`
|
||||||
TxSyncMaxTimeout *time.Duration `toml:",omitempty"`
|
TxSyncMaxTimeout *time.Duration `toml:",omitempty"`
|
||||||
RangeLimit *uint64 `toml:",omitempty"`
|
RangeLimit *uint64 `toml:",omitempty"`
|
||||||
|
|
@ -324,8 +324,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
if dec.OverrideBPO2 != nil {
|
if dec.OverrideBPO2 != nil {
|
||||||
c.OverrideBPO2 = dec.OverrideBPO2
|
c.OverrideBPO2 = dec.OverrideBPO2
|
||||||
}
|
}
|
||||||
if dec.OverrideVerkle != nil {
|
if dec.OverrideUBT != nil {
|
||||||
c.OverrideVerkle = dec.OverrideVerkle
|
c.OverrideUBT = dec.OverrideUBT
|
||||||
}
|
}
|
||||||
if dec.TxSyncDefaultTimeout != nil {
|
if dec.TxSyncDefaultTimeout != nil {
|
||||||
c.TxSyncDefaultTimeout = *dec.TxSyncDefaultTimeout
|
c.TxSyncDefaultTimeout = *dec.TxSyncDefaultTimeout
|
||||||
|
|
|
||||||
|
|
@ -1086,8 +1086,8 @@ func overrideConfig(original *params.ChainConfig, override *params.ChainConfig)
|
||||||
copy.OsakaTime = timestamp
|
copy.OsakaTime = timestamp
|
||||||
canon = false
|
canon = false
|
||||||
}
|
}
|
||||||
if timestamp := override.VerkleTime; timestamp != nil {
|
if timestamp := override.UBTTime; timestamp != nil {
|
||||||
copy.VerkleTime = timestamp
|
copy.UBTTime = timestamp
|
||||||
canon = false
|
canon = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -317,7 +317,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
||||||
if precompiles != nil {
|
if precompiles != nil {
|
||||||
evm.SetPrecompiles(precompiles)
|
evm.SetPrecompiles(precompiles)
|
||||||
}
|
}
|
||||||
if sim.chainConfig.IsPrague(header.Number, header.Time) || sim.chainConfig.IsVerkle(header.Number, header.Time) {
|
if sim.chainConfig.IsPrague(header.Number, header.Time) || sim.chainConfig.IsUBT(header.Number, header.Time) {
|
||||||
core.ProcessParentBlockHash(header.ParentHash, evm)
|
core.ProcessParentBlockHash(header.ParentHash, evm)
|
||||||
}
|
}
|
||||||
if header.ParentBeaconRoot != nil {
|
if header.ParentBeaconRoot != nil {
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ var (
|
||||||
CancunTime: nil,
|
CancunTime: nil,
|
||||||
PragueTime: nil,
|
PragueTime: nil,
|
||||||
OsakaTime: nil,
|
OsakaTime: nil,
|
||||||
VerkleTime: nil,
|
UBTTime: nil,
|
||||||
Ethash: new(EthashConfig),
|
Ethash: new(EthashConfig),
|
||||||
Clique: nil,
|
Clique: nil,
|
||||||
}
|
}
|
||||||
|
|
@ -263,7 +263,7 @@ var (
|
||||||
CancunTime: nil,
|
CancunTime: nil,
|
||||||
PragueTime: nil,
|
PragueTime: nil,
|
||||||
OsakaTime: nil,
|
OsakaTime: nil,
|
||||||
VerkleTime: nil,
|
UBTTime: nil,
|
||||||
TerminalTotalDifficulty: big.NewInt(math.MaxInt64),
|
TerminalTotalDifficulty: big.NewInt(math.MaxInt64),
|
||||||
Ethash: nil,
|
Ethash: nil,
|
||||||
Clique: &CliqueConfig{Period: 0, Epoch: 30000},
|
Clique: &CliqueConfig{Period: 0, Epoch: 30000},
|
||||||
|
|
@ -293,7 +293,7 @@ var (
|
||||||
CancunTime: nil,
|
CancunTime: nil,
|
||||||
PragueTime: nil,
|
PragueTime: nil,
|
||||||
OsakaTime: nil,
|
OsakaTime: nil,
|
||||||
VerkleTime: nil,
|
UBTTime: nil,
|
||||||
TerminalTotalDifficulty: big.NewInt(math.MaxInt64),
|
TerminalTotalDifficulty: big.NewInt(math.MaxInt64),
|
||||||
Ethash: new(EthashConfig),
|
Ethash: new(EthashConfig),
|
||||||
Clique: nil,
|
Clique: nil,
|
||||||
|
|
@ -323,7 +323,7 @@ var (
|
||||||
CancunTime: newUint64(0),
|
CancunTime: newUint64(0),
|
||||||
PragueTime: newUint64(0),
|
PragueTime: newUint64(0),
|
||||||
OsakaTime: newUint64(0),
|
OsakaTime: newUint64(0),
|
||||||
VerkleTime: nil,
|
UBTTime: nil,
|
||||||
TerminalTotalDifficulty: big.NewInt(0),
|
TerminalTotalDifficulty: big.NewInt(0),
|
||||||
Ethash: new(EthashConfig),
|
Ethash: new(EthashConfig),
|
||||||
Clique: nil,
|
Clique: nil,
|
||||||
|
|
@ -358,7 +358,7 @@ var (
|
||||||
CancunTime: nil,
|
CancunTime: nil,
|
||||||
PragueTime: nil,
|
PragueTime: nil,
|
||||||
OsakaTime: nil,
|
OsakaTime: nil,
|
||||||
VerkleTime: nil,
|
UBTTime: nil,
|
||||||
TerminalTotalDifficulty: big.NewInt(math.MaxInt64),
|
TerminalTotalDifficulty: big.NewInt(math.MaxInt64),
|
||||||
Ethash: new(EthashConfig),
|
Ethash: new(EthashConfig),
|
||||||
Clique: nil,
|
Clique: nil,
|
||||||
|
|
@ -466,7 +466,7 @@ type ChainConfig struct {
|
||||||
BPO4Time *uint64 `json:"bpo4Time,omitempty"` // BPO4 switch time (nil = no fork, 0 = already on bpo4)
|
BPO4Time *uint64 `json:"bpo4Time,omitempty"` // BPO4 switch time (nil = no fork, 0 = already on bpo4)
|
||||||
BPO5Time *uint64 `json:"bpo5Time,omitempty"` // BPO5 switch time (nil = no fork, 0 = already on bpo5)
|
BPO5Time *uint64 `json:"bpo5Time,omitempty"` // BPO5 switch time (nil = no fork, 0 = already on bpo5)
|
||||||
AmsterdamTime *uint64 `json:"amsterdamTime,omitempty"` // Amsterdam switch time (nil = no fork, 0 = already on amsterdam)
|
AmsterdamTime *uint64 `json:"amsterdamTime,omitempty"` // Amsterdam switch time (nil = no fork, 0 = already on amsterdam)
|
||||||
VerkleTime *uint64 `json:"verkleTime,omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle)
|
UBTTime *uint64 `json:"ubtTime,omitempty"` // UBT switch time (nil = no fork, 0 = already on UBT)
|
||||||
|
|
||||||
// TerminalTotalDifficulty is the amount of total difficulty reached by
|
// TerminalTotalDifficulty is the amount of total difficulty reached by
|
||||||
// the network that triggers the consensus upgrade.
|
// the network that triggers the consensus upgrade.
|
||||||
|
|
@ -474,7 +474,7 @@ type ChainConfig struct {
|
||||||
|
|
||||||
DepositContractAddress common.Address `json:"depositContractAddress,omitempty"`
|
DepositContractAddress common.Address `json:"depositContractAddress,omitempty"`
|
||||||
|
|
||||||
// EnableVerkleAtGenesis is a flag that specifies whether the network uses
|
// EnableUBTAtGenesis is a flag that specifies whether the network uses
|
||||||
// the Verkle tree starting from the genesis block. If set to true, the
|
// the Verkle tree starting from the genesis block. If set to true, the
|
||||||
// genesis state will be committed using the Verkle tree, eliminating the
|
// genesis state will be committed using the Verkle tree, eliminating the
|
||||||
// need for any Verkle transition later.
|
// need for any Verkle transition later.
|
||||||
|
|
@ -485,7 +485,7 @@ type ChainConfig struct {
|
||||||
// In production networks (mainnet and public testnets), verkle activation
|
// In production networks (mainnet and public testnets), verkle activation
|
||||||
// always occurs after the genesis block, making this flag irrelevant in
|
// always occurs after the genesis block, making this flag irrelevant in
|
||||||
// those cases.
|
// those cases.
|
||||||
EnableVerkleAtGenesis bool `json:"enableVerkleAtGenesis,omitempty"`
|
EnableUBTAtGenesis bool `json:"enableUBTAtGenesis,omitempty"`
|
||||||
|
|
||||||
// Various consensus engines
|
// Various consensus engines
|
||||||
Ethash *EthashConfig `json:"ethash,omitempty"`
|
Ethash *EthashConfig `json:"ethash,omitempty"`
|
||||||
|
|
@ -595,8 +595,8 @@ func (c *ChainConfig) String() string {
|
||||||
if c.AmsterdamTime != nil {
|
if c.AmsterdamTime != nil {
|
||||||
result += fmt.Sprintf(", AmsterdamTime: %v", *c.AmsterdamTime)
|
result += fmt.Sprintf(", AmsterdamTime: %v", *c.AmsterdamTime)
|
||||||
}
|
}
|
||||||
if c.VerkleTime != nil {
|
if c.UBTTime != nil {
|
||||||
result += fmt.Sprintf(", VerkleTime: %v", *c.VerkleTime)
|
result += fmt.Sprintf(", UBTTime: %v", *c.UBTTime)
|
||||||
}
|
}
|
||||||
result += "}"
|
result += "}"
|
||||||
return result
|
return result
|
||||||
|
|
@ -690,8 +690,8 @@ func (c *ChainConfig) Description() string {
|
||||||
if c.AmsterdamTime != nil {
|
if c.AmsterdamTime != nil {
|
||||||
banner += fmt.Sprintf(" - Amsterdam: @%-10v blob: (%s)\n", *c.AmsterdamTime, c.BlobScheduleConfig.Amsterdam)
|
banner += fmt.Sprintf(" - Amsterdam: @%-10v blob: (%s)\n", *c.AmsterdamTime, c.BlobScheduleConfig.Amsterdam)
|
||||||
}
|
}
|
||||||
if c.VerkleTime != nil {
|
if c.UBTTime != nil {
|
||||||
banner += fmt.Sprintf(" - Verkle: @%-10v blob: (%s)\n", *c.VerkleTime, c.BlobScheduleConfig.Verkle)
|
banner += fmt.Sprintf(" - Verkle: @%-10v blob: (%s)\n", *c.UBTTime, c.BlobScheduleConfig.Verkle)
|
||||||
}
|
}
|
||||||
banner += fmt.Sprintf("\nAll fork specifications can be found at https://ethereum.github.io/execution-specs/src/ethereum/forks/\n")
|
banner += fmt.Sprintf("\nAll fork specifications can be found at https://ethereum.github.io/execution-specs/src/ethereum/forks/\n")
|
||||||
return banner
|
return banner
|
||||||
|
|
@ -866,12 +866,12 @@ func (c *ChainConfig) IsAmsterdam(num *big.Int, time uint64) bool {
|
||||||
return c.IsLondon(num) && isTimestampForked(c.AmsterdamTime, time)
|
return c.IsLondon(num) && isTimestampForked(c.AmsterdamTime, time)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsVerkle returns whether time is either equal to the Verkle fork time or greater.
|
// IsUBT returns whether time is either equal to the Verkle fork time or greater.
|
||||||
func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool {
|
func (c *ChainConfig) IsUBT(num *big.Int, time uint64) bool {
|
||||||
return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time)
|
return c.IsLondon(num) && isTimestampForked(c.UBTTime, time)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsVerkleGenesis checks whether the verkle fork is activated at the genesis block.
|
// IsUBTGenesis checks whether the verkle fork is activated at the genesis block.
|
||||||
//
|
//
|
||||||
// Verkle mode is considered enabled if the verkle fork time is configured,
|
// Verkle mode is considered enabled if the verkle fork time is configured,
|
||||||
// regardless of whether the local time has surpassed the fork activation time.
|
// regardless of whether the local time has surpassed the fork activation time.
|
||||||
|
|
@ -881,13 +881,13 @@ func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool {
|
||||||
// In production networks (mainnet and public testnets), verkle activation
|
// In production networks (mainnet and public testnets), verkle activation
|
||||||
// always occurs after the genesis block, making this function irrelevant in
|
// always occurs after the genesis block, making this function irrelevant in
|
||||||
// those cases.
|
// those cases.
|
||||||
func (c *ChainConfig) IsVerkleGenesis() bool {
|
func (c *ChainConfig) IsUBTGenesis() bool {
|
||||||
return c.EnableVerkleAtGenesis
|
return c.EnableUBTAtGenesis
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEIP4762 returns whether eip 4762 has been activated at given block.
|
// IsEIP4762 returns whether eip 4762 has been activated at given block.
|
||||||
func (c *ChainConfig) IsEIP4762(num *big.Int, time uint64) bool {
|
func (c *ChainConfig) IsEIP4762(num *big.Int, time uint64) bool {
|
||||||
return c.IsVerkle(num, time)
|
return c.IsUBT(num, time)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckCompatible checks whether scheduled fork transitions have been imported
|
// CheckCompatible checks whether scheduled fork transitions have been imported
|
||||||
|
|
@ -945,7 +945,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
|
||||||
{name: "cancunTime", timestamp: c.CancunTime, optional: true},
|
{name: "cancunTime", timestamp: c.CancunTime, optional: true},
|
||||||
{name: "pragueTime", timestamp: c.PragueTime, optional: true},
|
{name: "pragueTime", timestamp: c.PragueTime, optional: true},
|
||||||
{name: "osakaTime", timestamp: c.OsakaTime, optional: true},
|
{name: "osakaTime", timestamp: c.OsakaTime, optional: true},
|
||||||
{name: "verkleTime", timestamp: c.VerkleTime, optional: true},
|
{name: "ubtTime", timestamp: c.UBTTime, optional: true},
|
||||||
{name: "bpo1", timestamp: c.BPO1Time, optional: true},
|
{name: "bpo1", timestamp: c.BPO1Time, optional: true},
|
||||||
{name: "bpo2", timestamp: c.BPO2Time, optional: true},
|
{name: "bpo2", timestamp: c.BPO2Time, optional: true},
|
||||||
{name: "bpo3", timestamp: c.BPO3Time, optional: true},
|
{name: "bpo3", timestamp: c.BPO3Time, optional: true},
|
||||||
|
|
@ -1104,8 +1104,8 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int,
|
||||||
if isForkTimestampIncompatible(c.OsakaTime, newcfg.OsakaTime, headTimestamp) {
|
if isForkTimestampIncompatible(c.OsakaTime, newcfg.OsakaTime, headTimestamp) {
|
||||||
return newTimestampCompatError("Osaka fork timestamp", c.OsakaTime, newcfg.OsakaTime)
|
return newTimestampCompatError("Osaka fork timestamp", c.OsakaTime, newcfg.OsakaTime)
|
||||||
}
|
}
|
||||||
if isForkTimestampIncompatible(c.VerkleTime, newcfg.VerkleTime, headTimestamp) {
|
if isForkTimestampIncompatible(c.UBTTime, newcfg.UBTTime, headTimestamp) {
|
||||||
return newTimestampCompatError("Verkle fork timestamp", c.VerkleTime, newcfg.VerkleTime)
|
return newTimestampCompatError("UBT fork timestamp", c.UBTTime, newcfg.UBTTime)
|
||||||
}
|
}
|
||||||
if isForkTimestampIncompatible(c.BPO1Time, newcfg.BPO1Time, headTimestamp) {
|
if isForkTimestampIncompatible(c.BPO1Time, newcfg.BPO1Time, headTimestamp) {
|
||||||
return newTimestampCompatError("BPO1 fork timestamp", c.BPO1Time, newcfg.BPO1Time)
|
return newTimestampCompatError("BPO1 fork timestamp", c.BPO1Time, newcfg.BPO1Time)
|
||||||
|
|
@ -1380,14 +1380,14 @@ type Rules struct {
|
||||||
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
|
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
|
||||||
IsBerlin, IsLondon bool
|
IsBerlin, IsLondon bool
|
||||||
IsMerge, IsShanghai, IsCancun, IsPrague, IsOsaka bool
|
IsMerge, IsShanghai, IsCancun, IsPrague, IsOsaka bool
|
||||||
IsAmsterdam, IsVerkle bool
|
IsAmsterdam, IsUBT bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rules ensures c's ChainID is not nil.
|
// Rules ensures c's ChainID is not nil.
|
||||||
func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules {
|
func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules {
|
||||||
// disallow setting Merge out of order
|
// disallow setting Merge out of order
|
||||||
isMerge = isMerge && c.IsLondon(num)
|
isMerge = isMerge && c.IsLondon(num)
|
||||||
isVerkle := isMerge && c.IsVerkle(num, timestamp)
|
isUBT := isMerge && c.IsUBT(num, timestamp)
|
||||||
return Rules{
|
return Rules{
|
||||||
IsHomestead: c.IsHomestead(num),
|
IsHomestead: c.IsHomestead(num),
|
||||||
IsEIP150: c.IsEIP150(num),
|
IsEIP150: c.IsEIP150(num),
|
||||||
|
|
@ -1398,7 +1398,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules
|
||||||
IsPetersburg: c.IsPetersburg(num),
|
IsPetersburg: c.IsPetersburg(num),
|
||||||
IsIstanbul: c.IsIstanbul(num),
|
IsIstanbul: c.IsIstanbul(num),
|
||||||
IsBerlin: c.IsBerlin(num),
|
IsBerlin: c.IsBerlin(num),
|
||||||
IsEIP2929: c.IsBerlin(num) && !isVerkle,
|
IsEIP2929: c.IsBerlin(num) && !isUBT,
|
||||||
IsLondon: c.IsLondon(num),
|
IsLondon: c.IsLondon(num),
|
||||||
IsMerge: isMerge,
|
IsMerge: isMerge,
|
||||||
IsShanghai: isMerge && c.IsShanghai(num, timestamp),
|
IsShanghai: isMerge && c.IsShanghai(num, timestamp),
|
||||||
|
|
@ -1406,7 +1406,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules
|
||||||
IsPrague: isMerge && c.IsPrague(num, timestamp),
|
IsPrague: isMerge && c.IsPrague(num, timestamp),
|
||||||
IsOsaka: isMerge && c.IsOsaka(num, timestamp),
|
IsOsaka: isMerge && c.IsOsaka(num, timestamp),
|
||||||
IsAmsterdam: isMerge && c.IsAmsterdam(num, timestamp),
|
IsAmsterdam: isMerge && c.IsAmsterdam(num, timestamp),
|
||||||
IsVerkle: isVerkle,
|
IsUBT: isUBT,
|
||||||
IsEIP4762: isVerkle,
|
IsEIP4762: isUBT,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,10 +126,10 @@ func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *t
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
tconf = &triedb.Config{
|
tconf = &triedb.Config{
|
||||||
Preimages: true,
|
Preimages: true,
|
||||||
IsVerkle: gspec.Config.VerkleTime != nil && *gspec.Config.VerkleTime <= gspec.Timestamp,
|
IsUBT: gspec.Config.UBTTime != nil && *gspec.Config.UBTTime <= gspec.Timestamp,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if scheme == rawdb.PathScheme || tconf.IsVerkle {
|
if scheme == rawdb.PathScheme || tconf.IsUBT {
|
||||||
tconf.PathDB = pathdb.Defaults
|
tconf.PathDB = pathdb.Defaults
|
||||||
} else {
|
} else {
|
||||||
tconf.HashDB = hashdb.Defaults
|
tconf.HashDB = hashdb.Defaults
|
||||||
|
|
|
||||||
|
|
@ -774,7 +774,7 @@ var Forks = map[string]*params.ChainConfig{
|
||||||
MergeNetsplitBlock: big.NewInt(0),
|
MergeNetsplitBlock: big.NewInt(0),
|
||||||
TerminalTotalDifficulty: big.NewInt(0),
|
TerminalTotalDifficulty: big.NewInt(0),
|
||||||
ShanghaiTime: u64(0),
|
ShanghaiTime: u64(0),
|
||||||
VerkleTime: u64(0),
|
UBTTime: u64(0),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -361,8 +361,8 @@ func (t *BinaryTrie) Copy() *BinaryTrie {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsVerkle returns true if the trie is a Verkle tree.
|
// IsUBT returns true if the trie is a Verkle tree.
|
||||||
func (t *BinaryTrie) IsVerkle() bool {
|
func (t *BinaryTrie) IsUBT() bool {
|
||||||
// TODO @gballet This is technically NOT a verkle tree, but it has the same
|
// TODO @gballet This is technically NOT a verkle tree, but it has the same
|
||||||
// behavior and basic structure, so for all intents and purposes, it can be
|
// behavior and basic structure, so for all intents and purposes, it can be
|
||||||
// treated as such. Rename this when verkle gets removed.
|
// treated as such. Rename this when verkle gets removed.
|
||||||
|
|
|
||||||
|
|
@ -324,6 +324,6 @@ func (t *StateTrie) MustNodeIterator(start []byte) NodeIterator {
|
||||||
return t.trie.MustNodeIterator(start)
|
return t.trie.MustNodeIterator(start)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *StateTrie) IsVerkle() bool {
|
func (t *StateTrie) IsUBT() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -202,8 +202,8 @@ func (t *TransitionTrie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error {
|
||||||
panic("not implemented") // TODO: Implement
|
panic("not implemented") // TODO: Implement
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsVerkle returns true if the trie is verkle-tree based
|
// IsUBT returns true if the trie is verkle-tree based
|
||||||
func (t *TransitionTrie) IsVerkle() bool {
|
func (t *TransitionTrie) IsUBT() bool {
|
||||||
// For all intents and purposes, the calling code should treat this as a verkle trie
|
// For all intents and purposes, the calling code should treat this as a verkle trie
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ import (
|
||||||
// Config defines all necessary options for database.
|
// Config defines all necessary options for database.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Preimages bool // Flag whether the preimage of node key is recorded
|
Preimages bool // Flag whether the preimage of node key is recorded
|
||||||
IsVerkle bool // Flag whether the db is holding a verkle tree
|
IsUBT bool // Flag whether the db is holding a verkle tree
|
||||||
HashDB *hashdb.Config // Configs for hash-based scheme
|
HashDB *hashdb.Config // Configs for hash-based scheme
|
||||||
PathDB *pathdb.Config // Configs for experimental path-based scheme
|
PathDB *pathdb.Config // Configs for experimental path-based scheme
|
||||||
}
|
}
|
||||||
|
|
@ -41,15 +41,15 @@ type Config struct {
|
||||||
// default settings.
|
// default settings.
|
||||||
var HashDefaults = &Config{
|
var HashDefaults = &Config{
|
||||||
Preimages: false,
|
Preimages: false,
|
||||||
IsVerkle: false,
|
IsUBT: false,
|
||||||
HashDB: hashdb.Defaults,
|
HashDB: hashdb.Defaults,
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerkleDefaults represents a config for holding verkle trie data
|
// UBTDefaults represents a config for holding verkle trie data
|
||||||
// using path-based scheme with default settings.
|
// using path-based scheme with default settings.
|
||||||
var VerkleDefaults = &Config{
|
var UBTDefaults = &Config{
|
||||||
Preimages: false,
|
Preimages: false,
|
||||||
IsVerkle: true,
|
IsUBT: true,
|
||||||
PathDB: pathdb.Defaults,
|
PathDB: pathdb.Defaults,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,7 +109,7 @@ func NewDatabase(diskdb ethdb.Database, config *Config) *Database {
|
||||||
log.Crit("Both 'hash' and 'path' mode are configured")
|
log.Crit("Both 'hash' and 'path' mode are configured")
|
||||||
}
|
}
|
||||||
if config.PathDB != nil {
|
if config.PathDB != nil {
|
||||||
db.backend = pathdb.New(diskdb, config.PathDB, config.IsVerkle)
|
db.backend = pathdb.New(diskdb, config.PathDB, config.IsUBT)
|
||||||
} else {
|
} else {
|
||||||
db.backend = hashdb.New(diskdb, config.HashDB)
|
db.backend = hashdb.New(diskdb, config.HashDB)
|
||||||
}
|
}
|
||||||
|
|
@ -375,9 +375,9 @@ func (db *Database) IndexProgress() (uint64, uint64, error) {
|
||||||
return pdb.IndexProgress()
|
return pdb.IndexProgress()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsVerkle returns the indicator if the database is holding a verkle tree.
|
// IsUBT returns the indicator if the database is holding a verkle tree.
|
||||||
func (db *Database) IsVerkle() bool {
|
func (db *Database) IsUBT() bool {
|
||||||
return db.config.IsVerkle
|
return db.config.IsUBT
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disk returns the underlying disk database.
|
// Disk returns the underlying disk database.
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ type Database struct {
|
||||||
// the shutdown to reject all following unexpected mutations.
|
// the shutdown to reject all following unexpected mutations.
|
||||||
readOnly bool // Flag if database is opened in read only mode
|
readOnly bool // Flag if database is opened in read only mode
|
||||||
waitSync bool // Flag if database is deactivated due to initial state sync
|
waitSync bool // Flag if database is deactivated due to initial state sync
|
||||||
isVerkle bool // Flag if database is used for verkle tree
|
isUBT bool // Flag if database is used for verkle tree
|
||||||
hasher nodeHasher // Trie node hasher
|
hasher nodeHasher // Trie node hasher
|
||||||
|
|
||||||
config *Config // Configuration for database
|
config *Config // Configuration for database
|
||||||
|
|
@ -146,7 +146,7 @@ type Database struct {
|
||||||
// New attempts to load an already existing layer from a persistent key-value
|
// New attempts to load an already existing layer from a persistent key-value
|
||||||
// store (with a number of memory layers from a journal). If the journal is not
|
// store (with a number of memory layers from a journal). If the journal is not
|
||||||
// matched with the base persistent layer, all the recorded diff layers are discarded.
|
// matched with the base persistent layer, all the recorded diff layers are discarded.
|
||||||
func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database {
|
func New(diskdb ethdb.Database, config *Config, isUBT bool) *Database {
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = Defaults
|
config = Defaults
|
||||||
}
|
}
|
||||||
|
|
@ -154,7 +154,7 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database {
|
||||||
|
|
||||||
db := &Database{
|
db := &Database{
|
||||||
readOnly: config.ReadOnly,
|
readOnly: config.ReadOnly,
|
||||||
isVerkle: isVerkle,
|
isUBT: isUBT,
|
||||||
config: config,
|
config: config,
|
||||||
diskdb: diskdb,
|
diskdb: diskdb,
|
||||||
hasher: merkleNodeHasher,
|
hasher: merkleNodeHasher,
|
||||||
|
|
@ -164,7 +164,7 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database {
|
||||||
// important to note that the introduction of a prefix won't lead to
|
// important to note that the introduction of a prefix won't lead to
|
||||||
// substantial storage overhead, as the underlying database will efficiently
|
// substantial storage overhead, as the underlying database will efficiently
|
||||||
// compress the shared key prefix.
|
// compress the shared key prefix.
|
||||||
if isVerkle {
|
if isUBT {
|
||||||
db.diskdb = rawdb.NewTable(diskdb, string(rawdb.VerklePrefix))
|
db.diskdb = rawdb.NewTable(diskdb, string(rawdb.VerklePrefix))
|
||||||
db.hasher = binaryNodeHasher
|
db.hasher = binaryNodeHasher
|
||||||
}
|
}
|
||||||
|
|
@ -174,7 +174,7 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database {
|
||||||
|
|
||||||
// Repair the history, which might not be aligned with the persistent
|
// Repair the history, which might not be aligned with the persistent
|
||||||
// state in the key-value store due to an unclean shutdown.
|
// state in the key-value store due to an unclean shutdown.
|
||||||
states, trienodes, err := repairHistory(db.diskdb, isVerkle, db.config.ReadOnly, db.tree.bottom().stateID(), db.config.TrienodeHistory >= 0)
|
states, trienodes, err := repairHistory(db.diskdb, isUBT, db.config.ReadOnly, db.tree.bottom().stateID(), db.config.TrienodeHistory >= 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Crit("Failed to repair history", "err", err)
|
log.Crit("Failed to repair history", "err", err)
|
||||||
}
|
}
|
||||||
|
|
@ -196,7 +196,7 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database {
|
||||||
db.setHistoryIndexer()
|
db.setHistoryIndexer()
|
||||||
|
|
||||||
fields := config.fields()
|
fields := config.fields()
|
||||||
if db.isVerkle {
|
if db.isUBT {
|
||||||
fields = append(fields, "verkle", true)
|
fields = append(fields, "verkle", true)
|
||||||
}
|
}
|
||||||
log.Info("Initialized path database", fields...)
|
log.Info("Initialized path database", fields...)
|
||||||
|
|
@ -265,7 +265,7 @@ func (db *Database) setStateGenerator() error {
|
||||||
// - the database is opened in read only mode
|
// - the database is opened in read only mode
|
||||||
// - the snapshot build is explicitly disabled
|
// - the snapshot build is explicitly disabled
|
||||||
// - the database is opened in verkle tree mode
|
// - the database is opened in verkle tree mode
|
||||||
noBuild := db.readOnly || db.config.SnapshotNoBuild || db.isVerkle
|
noBuild := db.readOnly || db.config.SnapshotNoBuild || db.isUBT
|
||||||
|
|
||||||
// Construct the generator and link it to the disk layer, ensuring that the
|
// Construct the generator and link it to the disk layer, ensuring that the
|
||||||
// generation progress is resolved to prevent accessing uncovered states
|
// generation progress is resolved to prevent accessing uncovered states
|
||||||
|
|
@ -408,7 +408,7 @@ func (db *Database) Enable(root common.Hash) error {
|
||||||
|
|
||||||
// Re-construct a new disk layer backed by persistent state
|
// Re-construct a new disk layer backed by persistent state
|
||||||
// and schedule the state snapshot generation if it's permitted.
|
// and schedule the state snapshot generation if it's permitted.
|
||||||
db.tree.init(generateSnapshot(db, root, db.isVerkle || db.config.SnapshotNoBuild))
|
db.tree.init(generateSnapshot(db, root, db.isUBT || db.config.SnapshotNoBuild))
|
||||||
|
|
||||||
// After snap sync, the state of the database may have changed completely.
|
// After snap sync, the state of the database may have changed completely.
|
||||||
// To ensure the history indexer always matches the current state, we must:
|
// To ensure the history indexer always matches the current state, we must:
|
||||||
|
|
@ -586,7 +586,7 @@ func (db *Database) journalPath() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
var fname string
|
var fname string
|
||||||
if db.isVerkle {
|
if db.isUBT {
|
||||||
fname = fmt.Sprintf("verkle.journal")
|
fname = fmt.Sprintf("verkle.journal")
|
||||||
} else {
|
} else {
|
||||||
fname = fmt.Sprintf("merkle.journal")
|
fname = fmt.Sprintf("merkle.journal")
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ type testerConfig struct {
|
||||||
layers int // Number of state transitions to generate for
|
layers int // Number of state transitions to generate for
|
||||||
enableIndex bool // Enable state history indexing or not
|
enableIndex bool // Enable state history indexing or not
|
||||||
journalDir string // Directory path for persisting journal files
|
journalDir string // Directory path for persisting journal files
|
||||||
isVerkle bool // Enables Verkle trie mode if true
|
isUBT bool // Enables Verkle trie mode if true
|
||||||
|
|
||||||
writeBuffer *int // Optional, the size of memory allocated for write buffer
|
writeBuffer *int // Optional, the size of memory allocated for write buffer
|
||||||
trieCache *int // Optional, the size of memory allocated for trie cache
|
trieCache *int // Optional, the size of memory allocated for trie cache
|
||||||
|
|
@ -183,7 +183,7 @@ func newTester(t *testing.T, config *testerConfig) *tester {
|
||||||
NoAsyncFlush: true,
|
NoAsyncFlush: true,
|
||||||
JournalDirectory: config.journalDir,
|
JournalDirectory: config.journalDir,
|
||||||
NoHistoryIndexDelay: true,
|
NoHistoryIndexDelay: true,
|
||||||
}, config.isVerkle)
|
}, config.isUBT)
|
||||||
|
|
||||||
obj = &tester{
|
obj = &tester{
|
||||||
db: db,
|
db: db,
|
||||||
|
|
|
||||||
|
|
@ -376,7 +376,7 @@ func syncHistory(stores ...ethdb.AncientWriter) error {
|
||||||
// persistent state may appear if the trienode history was disabled during the
|
// persistent state may appear if the trienode history was disabled during the
|
||||||
// previous run. This process detects and resolves such gaps, preventing
|
// previous run. This process detects and resolves such gaps, preventing
|
||||||
// unexpected panics.
|
// unexpected panics.
|
||||||
func repairHistory(db ethdb.Database, isVerkle bool, readOnly bool, stateID uint64, enableTrienode bool) (ethdb.ResettableAncientStore, ethdb.ResettableAncientStore, error) {
|
func repairHistory(db ethdb.Database, isUBT bool, readOnly bool, stateID uint64, enableTrienode bool) (ethdb.ResettableAncientStore, ethdb.ResettableAncientStore, error) {
|
||||||
ancient, err := db.AncientDatadir()
|
ancient, err := db.AncientDatadir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO error out if ancient store is disabled. A tons of unit tests
|
// TODO error out if ancient store is disabled. A tons of unit tests
|
||||||
|
|
@ -386,7 +386,7 @@ func repairHistory(db ethdb.Database, isVerkle bool, readOnly bool, stateID uint
|
||||||
}
|
}
|
||||||
// State history is mandatory as it is the key component that ensures
|
// State history is mandatory as it is the key component that ensures
|
||||||
// resilience to deep reorgs.
|
// resilience to deep reorgs.
|
||||||
states, err := rawdb.NewStateFreezer(ancient, isVerkle, readOnly)
|
states, err := rawdb.NewStateFreezer(ancient, isUBT, readOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Crit("Failed to open state history freezer", "err", err)
|
log.Crit("Failed to open state history freezer", "err", err)
|
||||||
}
|
}
|
||||||
|
|
@ -395,7 +395,7 @@ func repairHistory(db ethdb.Database, isVerkle bool, readOnly bool, stateID uint
|
||||||
// node with state proofs.
|
// node with state proofs.
|
||||||
var trienodes ethdb.ResettableAncientStore
|
var trienodes ethdb.ResettableAncientStore
|
||||||
if enableTrienode {
|
if enableTrienode {
|
||||||
trienodes, err = rawdb.NewTrienodeFreezer(ancient, isVerkle, readOnly)
|
trienodes, err = rawdb.NewTrienodeFreezer(ancient, isUBT, readOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Crit("Failed to open trienode history freezer", "err", err)
|
log.Crit("Failed to open trienode history freezer", "err", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ func (db *Database) NodeReader(root common.Hash) (database.NodeReader, error) {
|
||||||
return &reader{
|
return &reader{
|
||||||
db: db,
|
db: db,
|
||||||
state: root,
|
state: root,
|
||||||
noHashCheck: db.isVerkle,
|
noHashCheck: db.isUBT,
|
||||||
layer: layer,
|
layer: layer,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue