Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/geth/chaincmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ func initGenesis(ctx *cli.Context) error {
triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle())
defer triedb.Close()

_, hash, compatErr, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides)
_, hash, compatErr, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides, nil)
if err != nil {
utils.Fatalf("Failed to write genesis block: %v", err)
}
Expand Down
39 changes: 27 additions & 12 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine,
// yet. The corresponding chain config will be returned, either from the
// provided genesis or from the locally stored configuration if the genesis
// has already been initialized.
chainConfig, genesisHash, compatErr, err := SetupGenesisBlockWithOverride(db, triedb, genesis, cfg.Overrides)
chainConfig, genesisHash, compatErr, err := SetupGenesisBlockWithOverride(db, triedb, genesis, cfg.Overrides, cfg.VmConfig.Tracer)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1649,20 +1649,35 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
log.Debug("Committed block data", "size", common.StorageSize(batch.ValueSize()), "elapsed", common.PrettyDuration(time.Since(start)))

var (
err error
root common.Hash
isEIP158 = bc.chainConfig.IsEIP158(block.Number())
isCancun = bc.chainConfig.IsCancun(block.Number(), block.Time())
err error
root common.Hash
isEIP158 = bc.chainConfig.IsEIP158(block.Number())
isCancun = bc.chainConfig.IsCancun(block.Number(), block.Time())
hasStateHook = bc.logger != nil && bc.logger.OnStateUpdate != nil
hasStateSizer = bc.stateSizer != nil
)
if bc.stateSizer == nil {
root, err = statedb.Commit(block.NumberU64(), isEIP158, isCancun)
if hasStateHook || hasStateSizer {
r, update, err := statedb.CommitWithUpdate(block.NumberU64(), isEIP158, isCancun)
if err != nil {
return err
}
if hasStateHook {
trUpdate, err := update.ToTracingUpdate()
if err != nil {
return err
}
bc.logger.OnStateUpdate(trUpdate)
}
if hasStateSizer {
bc.stateSizer.Notify(update)
}
root = r
} else {
root, err = statedb.CommitAndTrack(block.NumberU64(), isEIP158, isCancun, bc.stateSizer)
}
if err != nil {
return err
root, err = statedb.Commit(block.NumberU64(), isEIP158, isCancun)
if err != nil {
return err
}
}

// If node is running in path mode, skip explicit gc operation
// which is unnecessary in this mode.
if bc.triedb.Scheme() == rawdb.PathScheme {
Expand Down
2 changes: 1 addition & 1 deletion core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int,
}
triedb := triedb.NewDatabase(db, triedbConfig)
defer triedb.Close()
_, err := genesis.Commit(db, triedb)
_, err := genesis.Commit(db, triedb, nil)
if err != nil {
panic(err)
}
Expand Down
38 changes: 27 additions & 11 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {

// flushAlloc is very similar with hash, but the main difference is all the
// generated states will be persisted into the given database.
func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, error) {
func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database, tracer *tracing.Hooks) (common.Hash, error) {
emptyRoot := types.EmptyRootHash
if triedb.IsVerkle() {
emptyRoot = types.EmptyVerkleHash
Expand All @@ -185,10 +185,26 @@ func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, e
statedb.SetState(addr, key, value)
}
}
root, err := statedb.Commit(0, false, false)
if err != nil {
return common.Hash{}, err

var root common.Hash
if tracer != nil && tracer.OnStateUpdate != nil {
r, update, err := statedb.CommitWithUpdate(0, false, false)
if err != nil {
return common.Hash{}, err
}
trUpdate, err := update.ToTracingUpdate()
if err != nil {
return common.Hash{}, err
}
tracer.OnStateUpdate(trUpdate)
root = r
} else {
root, err = statedb.Commit(0, false, false)
if err != nil {
return common.Hash{}, err
}
}

// Commit newly generated states into disk if it's not empty.
if root != emptyRoot {
if err := triedb.Commit(root, true); err != nil {
Expand Down Expand Up @@ -296,10 +312,10 @@ func (o *ChainOverrides) apply(cfg *params.ChainConfig) error {
// specify a fork block below the local head block). In case of a conflict, the
// error is a *params.ConfigCompatError and the new, unwritten config is returned.
func SetupGenesisBlock(db ethdb.Database, triedb *triedb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
return SetupGenesisBlockWithOverride(db, triedb, genesis, nil)
return SetupGenesisBlockWithOverride(db, triedb, genesis, nil, nil)
}

func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides, tracer *tracing.Hooks) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
// Copy the genesis, so we can operate on a copy.
genesis = genesis.copy()
// Sanitize the supplied genesis, ensuring it has the associated chain
Expand All @@ -320,7 +336,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
return nil, common.Hash{}, nil, err
}

block, err := genesis.Commit(db, triedb)
block, err := genesis.Commit(db, triedb, tracer)
if err != nil {
return nil, common.Hash{}, nil, err
}
Expand Down Expand Up @@ -348,7 +364,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
if hash := genesis.ToBlock().Hash(); hash != ghash {
return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash}
}
block, err := genesis.Commit(db, triedb)
block, err := genesis.Commit(db, triedb, tracer)
if err != nil {
return nil, common.Hash{}, nil, err
}
Expand Down Expand Up @@ -537,7 +553,7 @@ func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block {

// Commit writes the block and state of a genesis specification to the database.
// The block is committed as the canonical head block.
func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Block, error) {
func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database, tracer *tracing.Hooks) (*types.Block, error) {
if g.Number != 0 {
return nil, errors.New("can't commit genesis block with number > 0")
}
Expand All @@ -552,7 +568,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo
return nil, errors.New("can't start clique chain without signers")
}
// flush the data to disk and compute the state root
root, err := flushAlloc(&g.Alloc, triedb)
root, err := flushAlloc(&g.Alloc, triedb, tracer)
if err != nil {
return nil, err
}
Expand All @@ -578,7 +594,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo
// MustCommit writes the genesis block and state to db, panicking on error.
// The block is committed as the canonical head block.
func (g *Genesis) MustCommit(db ethdb.Database, triedb *triedb.Database) *types.Block {
block, err := g.Commit(db, triedb)
block, err := g.Commit(db, triedb, nil)
if err != nil {
panic(err)
}
Expand Down
10 changes: 5 additions & 5 deletions core/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func testSetupGenesis(t *testing.T, scheme string) {
name: "custom block in DB, genesis == nil",
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
customg.Commit(db, tdb)
customg.Commit(db, tdb, nil)
return SetupGenesisBlock(db, tdb, nil)
},
wantHash: customghash,
Expand All @@ -98,7 +98,7 @@ func testSetupGenesis(t *testing.T, scheme string) {
name: "custom block in DB, genesis == sepolia",
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
customg.Commit(db, tdb)
customg.Commit(db, tdb, nil)
return SetupGenesisBlock(db, tdb, DefaultSepoliaGenesisBlock())
},
wantErr: &GenesisMismatchError{Stored: customghash, New: params.SepoliaGenesisHash},
Expand All @@ -107,7 +107,7 @@ func testSetupGenesis(t *testing.T, scheme string) {
name: "custom block in DB, genesis == hoodi",
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
customg.Commit(db, tdb)
customg.Commit(db, tdb, nil)
return SetupGenesisBlock(db, tdb, DefaultHoodiGenesisBlock())
},
wantErr: &GenesisMismatchError{Stored: customghash, New: params.HoodiGenesisHash},
Expand All @@ -116,7 +116,7 @@ func testSetupGenesis(t *testing.T, scheme string) {
name: "compatible config in DB",
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
oldcustomg.Commit(db, tdb)
oldcustomg.Commit(db, tdb, nil)
return SetupGenesisBlock(db, tdb, &customg)
},
wantHash: customghash,
Expand All @@ -128,7 +128,7 @@ func testSetupGenesis(t *testing.T, scheme string) {
// Commit the 'old' genesis block with Homestead transition at #2.
// Advance to block #4, past the homestead transition block of customg.
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
oldcustomg.Commit(db, tdb)
oldcustomg.Commit(db, tdb, nil)

bc, _ := NewBlockChain(db, &oldcustomg, ethash.NewFullFaker(), DefaultConfig().WithStateScheme(scheme))
defer bc.Stop()
Expand Down
2 changes: 1 addition & 1 deletion core/headerchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func TestHeaderInsertion(t *testing.T) {
db = rawdb.NewMemoryDatabase()
gspec = &Genesis{BaseFee: big.NewInt(params.InitialBaseFee), Config: params.AllEthashProtocolChanges}
)
gspec.Commit(db, triedb.NewDatabase(db, nil))
gspec.Commit(db, triedb.NewDatabase(db, nil), nil)
hc, err := NewHeaderChain(db, gspec.Config, ethash.NewFaker(), func() bool { return false })
if err != nil {
t.Fatal(err)
Expand Down
6 changes: 6 additions & 0 deletions core/state/state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,12 @@ func (s *stateObject) commit() (*accountUpdate, *trienode.NodeSet, error) {
blob: s.code,
}
s.dirtyCode = false // reset the dirty flag

if s.origin == nil {
op.code.originHash = types.EmptyCodeHash
} else {
op.code.originHash = common.BytesToHash(s.origin.CodeHash)
}
}
// Commit storage changes and the associated storage trie
s.commitStorage(op)
Expand Down
2 changes: 1 addition & 1 deletion core/state/state_sizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func calSizeStats(update *stateUpdate) (SizeStats, error) {

codeExists := make(map[common.Hash]struct{})
for _, code := range update.codes {
if _, ok := codeExists[code.hash]; ok || code.exists {
if _, ok := codeExists[code.hash]; ok || code.duplicate {
continue
}
stats.ContractCodes += 1
Expand Down
20 changes: 10 additions & 10 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -1319,16 +1319,16 @@ func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool, blockNum

// commitAndFlush is a wrapper of commit which also commits the state mutations
// to the configured data stores.
func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool, noStorageWiping bool, dedupCode bool) (*stateUpdate, error) {
func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool, noStorageWiping bool, deriveCodeFields bool) (*stateUpdate, error) {
ret, err := s.commit(deleteEmptyObjects, noStorageWiping, block)
if err != nil {
return nil, err
}

if dedupCode {
ret.markCodeExistence(s.reader)
if deriveCodeFields {
if err := ret.deriveCodeFields(s.reader); err != nil {
return nil, err
}
}

// Commit dirty contract code if any exists
if db := s.db.TrieDB().Disk(); db != nil && len(ret.codes) > 0 {
batch := db.NewBatch()
Expand Down Expand Up @@ -1390,14 +1390,14 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool, noStorageWiping
return ret.root, nil
}

// CommitAndTrack writes the state mutations and notifies the size tracker of the state changes.
func (s *StateDB) CommitAndTrack(block uint64, deleteEmptyObjects bool, noStorageWiping bool, sizer *SizeTracker) (common.Hash, error) {
// CommitWithUpdate writes the state mutations and returns the state update for
// external processing (e.g., live tracing hooks or size tracker).
func (s *StateDB) CommitWithUpdate(block uint64, deleteEmptyObjects bool, noStorageWiping bool) (common.Hash, *stateUpdate, error) {
ret, err := s.commitAndFlush(block, deleteEmptyObjects, noStorageWiping, true)
if err != nil {
return common.Hash{}, err
return common.Hash{}, nil, err
}
sizer.Notify(ret)
return ret.root, nil
return ret.root, ret, nil
}

// Prepare handles the preparatory steps for executing a state transition with.
Expand Down
Loading