-
Notifications
You must be signed in to change notification settings - Fork 115
Description
Summary
The AggLayerBridge account must maintain an up-to-date list of Global Exit Roots (GERs) originating from AggLayer. Since it is a network account, GER updates cannot be triggered via direct calls from user accounts. Instead, a designated Bridge Operator must inject new GER values into the system using network notes.
To support this, we propose:
- Adding a dedicated
UpdateGlobalExitRootaccount component to theAggLayerBridgecontract. - Defining a canonical
GER_UPDATEnetwork note. - Implementing basic validation to ensure that only notes from the authorized operator account can update the GER state.
New GERs are generated offchain (from Miden's perspective, i.e. on the L1), and once observed by the operator, they are communicated to Miden via a GER_UPDATE note. When processed, the network transaction builder routes this note to the bridge account, triggering the update procedure to store the new GER.
Proposed Design
1. Account component
We add a new account component to the AggLayerBridge account: UpdateGlobalExitRoot component.
Responsibilities:
- Expose a dedicated procedure (e.g.
update_ger) that:- Reads the new GER (+ other associated metadata?) from the note payload.
- Appends or updates the GER in the bridge account’s storage.
- Enforces basic authorization
- Store the authorized bridge operator
AccountId- only notes from this account are considered valid
This component would be part of the larger AggLayerBridge account alongside any other bridge-specific components.
MASM Interface
#! Updates the tracked Global Exit Root (GER) in the AggLayer bridge account.
#!
#! This procedure is invoked when a `GER_UPDATE` network note is processed
#! for the `AggLayerBridge` network account. It verifies that the note
#! sender is the authorized bridge operator and then writes the new GER
#! into the bridge account's storage.
#!
#! Inputs: [GER_UPPER, GER_LOWER]
#! Outputs: []
#!
#! Where:
#! - GER_UPPER is the upper 128-bit limb of the 256-bit Global Exit Root.
#! - GER_LOWER is the lower 128-bit limb of the 256-bit Global Exit Root.
#!
#! Panics if:
#! - the note sender is not the configured bridge operator.
#! - the provided GER value is malformed.
#!
#! Invocation: call.update_ger
pub proc update_ger
# TODO:
# - load and check authorized operator against note sender
# - validate GER (optional. We could check that lower/upper parts' elements all represent a 128-bit value via 4 Felts)
# - write GER into bridge storage
# - (optional) validate the script root of the calling note. Effectively only allows "official" `GER_UPDATE` note. This would allow us to shift GER format validation to the note script (but does that help?)
end
2. Network note
Since updates are driven by network notes, we need a canonical GER_UPDATE note. Its payload should include:
global_exit_root– the new GER value to track.
MASM Interface
use.agglayer::update_ger -> agglayer
#! This procedure is used as the script of a network note targeting the
#! `AggLayerBridge` account. It assumes the note payload has been encoded
#! into the two-limb GER representation. It calls into the bridge
#! component's `update_ger` procedure.
#!
#! Inputs: [GER_UPPER, GER_LOWER]
#! Outputs: []
#!
#! Where:
#! - GER_UPPER is the upper 128-bit limb of the 256-bit Global Exit Root.
#! - GER_LOWER is the lower 128-bit limb of the 256-bit Global Exit Root.
#!
#! Panics if:
#! - the call to `update_ger` panics.
#!
#! Invocation: call
begin
# IN: [GER_UPPER, GER_LOWER ]
# OUT: []
call.agglayer::update_ger
end
3. Flow
- Bridge operator detects a new GER registered on the L1.
- Bridge operator issues a new
GER_UPDATEcontaining the relevant information - Once the note is processed by the network, the network transaction builder will detect a
GER_UPDATEnetwork note targeting theAggLayerBridgeaccount. - As the note is processed, it will call
update_global_exit_rootprocedure on the bridge account. The procedure does the following:- Verify the note is coming from an authorized account (the operator account).
- Stores the new GER.
Open Questions
- What's the data structure for storing GERs? How many GERs do we store?
- In theory, this is an ever-growing list
- For the PoC, we can just store a fixed-size queue of GERs
- How to implement a queue in a Miden contract?
- My first attempt with the current capabilities would be a storage map with index - > value mapping, plus, a
last_updated_index, which is basically the index mod queue_size, to point to the last stored index
- My first attempt with the current capabilities would be a storage map with index - > value mapping, plus, a