params, core: add binary transition registry + UBT transition-tree end time

Introduce `params.BinaryTransitionRegistryAddress` (0x1622...1622), the
system contract that exposes MPT-to-binary transition state via fixed
storage slots (started, conversion progress, ended, base root).

Add `ChainConfig.UBTTransitionEndTime *uint64` and the
`UBTTransitionActive(num, time)` helper. While UBT is active and the
header time is below the configured end (or no end is configured), state
access is wrapped in a TransitionTrie that overlays the binary trie on
the frozen MPT base; once headers cross this timestamp, the wrapper is
dropped. Mirrors the threshold semantics of TerminalTotalDifficulty.

Surface the new field in `ChainConfig.String` and the description
banner, and add `ChainOverrides.OverrideUBTTransitionEnd` so the value
can be patched at startup alongside `OverrideUBT`.

No behaviour change yet: callers are introduced in the following commits.
This commit is contained in:
Guillaume Ballet 2026-04-29 16:16:54 +02:00
parent 8e2107dc39
commit 4f6219d5e7
No known key found for this signature in database
3 changed files with 44 additions and 4 deletions

View file

@ -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()
}

View file

@ -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,

View file

@ -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.