-
Notifications
You must be signed in to change notification settings - Fork 107
feat(AggLayer): UPDATE_GER note
#2333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
ac4f08f
feat: UPDATE_GER note outline
mmagician 26da911
feat: working update ger note
mmagician bce0fe2
chore: swap upper, lower GER parts
mmagician d47ca95
Merge branch 'agglayer' into mmagician-update-ger
mmagician b9774be
lint: regen error file
mmagician 75d3910
Merge branch 'agglayer' into mmagician-update-ger
mmagician File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| use miden::agglayer::bridge_in | ||
| use miden::protocol::active_note | ||
|
|
||
| # CONSTANTS | ||
| # ================================================================================================= | ||
| const UPDATE_GER_NOTE_NUM_STORAGE_ITEMS = 8 | ||
| const STORAGE_PTR_GER_LOWER = 0 | ||
| const STORAGE_PTR_GER_UPPER = 4 | ||
|
|
||
| # ERRORS | ||
| # ================================================================================================= | ||
| const ERR_UPDATE_GER_UNEXPECTED_NUMBER_OF_STORAGE_ITEMS = "UPDATE_GER script expects exactly 8 note storage items" | ||
|
|
||
| #! Agglayer Bridge UPDATE_GER script: updates the GER by calling the bridge_in::update_ger function. | ||
| #! | ||
| #! This note can only be consumed by the specific agglayer bridge account whose ID is provided | ||
| #! in the note attachment (target_account_id). | ||
|
Comment on lines
+16
to
+17
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not currently enforced, right? If so, might be good to add a comment about this. |
||
| #! | ||
| #! Requires that the account exposes: | ||
| #! - agglayer::bridge_in::update_ger procedure. | ||
| #! | ||
| #! Inputs: [ARGS, pad(12)] | ||
| #! Outputs: [pad(16)] | ||
| #! NoteStorage layout (8 felts total): | ||
| #! - GER_LOWER [0..3] | ||
| #! - GER_UPPER [4..7] | ||
| #! | ||
| #! Panics if: | ||
| #! - account does not expose update_ger procedure. | ||
| #! - target account ID does not match the consuming account ID. | ||
| #! - number of note storage items is not exactly 8. | ||
| begin | ||
| dropw | ||
| # => [pad(16)] | ||
|
|
||
| push.STORAGE_PTR_GER_LOWER exec.active_note::get_storage | ||
| # => [num_storage_items, dest_ptr, pad(16)] | ||
|
|
||
| push.UPDATE_GER_NOTE_NUM_STORAGE_ITEMS assert_eq.err=ERR_UPDATE_GER_UNEXPECTED_NUMBER_OF_STORAGE_ITEMS drop | ||
| # => [pad(16)] | ||
|
|
||
| # Load GER_LOWER and GER_UPPER from note storage | ||
| mem_loadw_be.STORAGE_PTR_GER_UPPER | ||
| swapw mem_loadw_be.STORAGE_PTR_GER_LOWER | ||
| # => [GER_LOWER[4], GER_UPPER[4]] | ||
|
|
||
| call.bridge_in::update_ger | ||
| # => [] | ||
|
|
||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| extern crate alloc; | ||
|
|
||
| use alloc::vec; | ||
|
|
||
| use miden_protocol::crypto::rand::FeltRng; | ||
| use miden_protocol::errors::NoteError; | ||
| use miden_protocol::note::{ | ||
| Note, | ||
| NoteAssets, | ||
| NoteMetadata, | ||
| NoteRecipient, | ||
| NoteStorage, | ||
| NoteTag, | ||
| NoteType, | ||
| }; | ||
|
|
||
| use crate::{ExitRoot, update_ger_script}; | ||
|
|
||
| /// Creates an UPDATE_GER note with the given GER (Global Exit Root) data. | ||
| /// | ||
| /// The note storage contains 8 felts: GER[0..7] | ||
| pub fn create_update_ger_note<R: FeltRng>( | ||
| ger: ExitRoot, | ||
| sender_account_id: miden_protocol::account::AccountId, | ||
| rng: &mut R, | ||
| ) -> Result<Note, NoteError> { | ||
| let update_ger_script = update_ger_script(); | ||
|
|
||
| // Create note storage with 8 felts: GER[0..7] | ||
| let storage_values = ger.to_elements().to_vec(); | ||
|
|
||
| let note_storage = NoteStorage::new(storage_values)?; | ||
|
|
||
| // Generate a serial number for the note | ||
| let serial_num = rng.draw_word(); | ||
|
|
||
| let recipient = NoteRecipient::new(serial_num, update_ger_script, note_storage); | ||
|
|
||
| // Create note metadata - use a simple public tag | ||
| let note_tag = NoteTag::new(0); | ||
| let metadata = NoteMetadata::new(sender_account_id, NoteType::Public, note_tag); | ||
|
|
||
| // UPDATE_GER notes don't carry assets | ||
| let assets = NoteAssets::new(vec![])?; | ||
|
|
||
| Ok(Note::new(assets, metadata, recipient)) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,3 +5,4 @@ mod crypto_utils; | |
| mod mmr_frontier; | ||
| mod solidity_miden_address_conversion; | ||
| pub mod test_utils; | ||
| mod update_ger; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| use miden_agglayer::{ExitRoot, create_existing_bridge_account, create_update_ger_note}; | ||
| use miden_protocol::Word; | ||
| use miden_protocol::account::StorageSlotName; | ||
| use miden_protocol::crypto::rand::FeltRng; | ||
| use miden_protocol::transaction::OutputNote; | ||
| use miden_testing::MockChain; | ||
|
|
||
| #[tokio::test] | ||
| async fn test_update_ger_note_updates_storage() -> anyhow::Result<()> { | ||
| let mut builder = MockChain::builder(); | ||
|
|
||
| // CREATE BRIDGE ACCOUNT | ||
| // -------------------------------------------------------------------------------------------- | ||
| let bridge_seed = builder.rng_mut().draw_word(); | ||
| let bridge_account = create_existing_bridge_account(bridge_seed); | ||
| builder.add_account(bridge_account.clone())?; | ||
|
|
||
| // CREATE UPDATE_GER NOTE WITH 8 STORAGE ITEMS | ||
| // -------------------------------------------------------------------------------------------- | ||
|
|
||
| let ger_bytes: [u8; 32] = [ | ||
| 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, | ||
| 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, | ||
| 0x77, 0x88, | ||
| ]; | ||
| let ger = ExitRoot::from(ger_bytes); | ||
| let update_ger_note = create_update_ger_note(ger, bridge_account.id(), builder.rng_mut())?; | ||
|
|
||
| builder.add_output_note(OutputNote::Full(update_ger_note.clone())); | ||
| let mock_chain = builder.build()?; | ||
|
|
||
| // EXECUTE UPDATE_GER NOTE AGAINST BRIDGE ACCOUNT | ||
| // -------------------------------------------------------------------------------------------- | ||
| let tx_context = mock_chain | ||
| .build_tx_context(bridge_account.id(), &[update_ger_note.id()], &[])? | ||
| .build()?; | ||
| let executed_transaction = tx_context.execute().await?; | ||
|
|
||
| // VERIFY GER WAS UPDATED IN STORAGE | ||
| // -------------------------------------------------------------------------------------------- | ||
| let mut updated_bridge_account = bridge_account.clone(); | ||
| updated_bridge_account.apply_delta(executed_transaction.account_delta())?; | ||
|
|
||
| let ger_upper = updated_bridge_account | ||
| .storage() | ||
| .get_item(&StorageSlotName::new("miden::agglayer::bridge::ger_upper")?) | ||
| .unwrap(); | ||
| let ger_lower = updated_bridge_account | ||
| .storage() | ||
| .get_item(&StorageSlotName::new("miden::agglayer::bridge::ger_lower")?) | ||
| .unwrap(); | ||
| let expected_lower: Word = ger.to_elements()[0..4].try_into().unwrap(); | ||
| let expected_upper: Word = ger.to_elements()[4..8].try_into().unwrap(); | ||
| assert_eq!(ger_upper, expected_upper); | ||
| assert_eq!(ger_lower, expected_lower); | ||
|
|
||
| Ok(()) | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of comments on these:
GER? it seems like, the claim note inputs can be used to compute theGERand then, we just need to check if theGERcomputed from the note matches theGERin the bride. For this, we just need to storeGERcommitment (i.e., RPO hash). This would mean we need only one storage slot.hash(ger) |-> 1/0. This way, given aGER, we can compute its hash to reduce it to a single word, and then do a lookup to check if theGERis known or not.GERupdate functionality is in thebridge_inmodule. It probably would make sense to have a separatebridge_operatormodule for things like this.