diff --git a/core/genesis.go b/core/genesis.go index d77ea10d8c..8095b4442a 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -276,10 +276,11 @@ func (e *GenesisMismatchError) Error() string { // ChainOverrides contains the changes to chain config. type ChainOverrides struct { - OverrideOsaka *uint64 - OverrideBPO1 *uint64 - OverrideBPO2 *uint64 - OverrideUBT *uint64 + OverrideOsaka *uint64 + OverrideBPO1 *uint64 + OverrideBPO2 *uint64 + OverrideUBT *uint64 + OverrideUBTTransitionEnd *uint64 } // apply applies the chain overrides on the supplied chain config. @@ -299,6 +300,9 @@ func (o *ChainOverrides) apply(cfg *params.ChainConfig) error { if o.OverrideUBT != nil { cfg.UBTTime = o.OverrideUBT } + if o.OverrideUBTTransitionEnd != nil { + cfg.UBTTransitionEndTime = o.OverrideUBTTransitionEnd + } return cfg.CheckConfigForkOrder() } diff --git a/params/config.go b/params/config.go index 17508cbf27..00752479d6 100644 --- a/params/config.go +++ b/params/config.go @@ -468,6 +468,15 @@ type ChainConfig struct { AmsterdamTime *uint64 `json:"amsterdamTime,omitempty"` // Amsterdam switch time (nil = no fork, 0 = already on amsterdam) UBTTime *uint64 `json:"ubtTime,omitempty"` // UBT switch time (nil = no fork, 0 = already on UBT) + // UBTTransitionEndTime is the timestamp at which the MPT-to-binary + // transition tree is no longer applied. While UBT is active and the + // timestamp is below this value (or nil), state access is wrapped in a + // TransitionTrie that overlays the binary trie on the frozen MPT base. + // Once headers reach this time, the transition wrapper is dropped and + // state is read directly from the binary trie. nil = wrapper stays on + // indefinitely. Mirrors the threshold semantics of TerminalTotalDifficulty. + UBTTransitionEndTime *uint64 `json:"ubtTransitionEndTime,omitempty"` + // TerminalTotalDifficulty is the amount of total difficulty reached by // the network that triggers the consensus upgrade. TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"` @@ -598,6 +607,9 @@ func (c *ChainConfig) String() string { if c.UBTTime != nil { result += fmt.Sprintf(", UBTTime: %v", *c.UBTTime) } + if c.UBTTransitionEndTime != nil { + result += fmt.Sprintf(", UBTTransitionEndTime: %v", *c.UBTTransitionEndTime) + } result += "}" return result } @@ -693,6 +705,9 @@ func (c *ChainConfig) Description() string { if c.UBTTime != nil { banner += fmt.Sprintf(" - UBT: @%-10v blob: (%s)\n", *c.UBTTime, c.BlobScheduleConfig.UBT) } + if c.UBTTransitionEndTime != nil { + banner += fmt.Sprintf(" - UBT transition tree ends: @%-10v\n", *c.UBTTransitionEndTime) + } banner += fmt.Sprintf("\nAll fork specifications can be found at https://ethereum.github.io/execution-specs/src/ethereum/forks/\n") return banner } @@ -871,6 +886,17 @@ func (c *ChainConfig) IsUBT(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.UBTTime, time) } +// UBTTransitionActive reports whether state access at the given block number +// and time should still be wrapped in a TransitionTrie (binary overlay on top +// of the frozen MPT base). It is true when UBT is active and either no end +// time is configured or the block is still before the configured end time. +func (c *ChainConfig) UBTTransitionActive(num *big.Int, time uint64) bool { + if !c.IsUBT(num, time) { + return false + } + return c.UBTTransitionEndTime == nil || time < *c.UBTTransitionEndTime +} + // IsUBTGenesis checks whether the verkle fork is activated at the genesis block. // // Verkle mode is considered enabled if the verkle fork time is configured, diff --git a/params/protocol_params.go b/params/protocol_params.go index 9da275c486..831d05a3b9 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -222,6 +222,16 @@ var ( // EIP-7251 - Increase the MAX_EFFECTIVE_BALANCE ConsolidationQueueAddress = common.HexToAddress("0x0000BBdDc7CE488642fb579F8B00f3a590007251") ConsolidationQueueCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd") + + // BinaryTransitionRegistryAddress is the system contract that exposes the + // MPT-to-binary transition state via storage slots: + // slot 0 = transition started flag + // slot 1 = address of the last translated account + // slot 2 = hash of the last translated storage slot + // slot 3 = "storage processed" flag + // slot 4 = transition ended flag + // slot 5 = frozen MPT base root + BinaryTransitionRegistryAddress = common.HexToAddress("0x1622162216221622162216221622162216221622") ) // System log events.