miden_agglayer/deregister_note.rs
1//! DEREGISTER_AGG_FAUCET note creation utilities.
2//!
3//! This module provides helpers for creating DEREGISTER_AGG_FAUCET notes,
4//! which are used to deregister faucets from the bridge's faucet registry.
5
6extern crate alloc;
7
8use alloc::string::ToString;
9use alloc::vec;
10use alloc::vec::Vec;
11
12use miden_core::Felt;
13use miden_protocol::account::AccountId;
14use miden_protocol::crypto::rand::FeltRng;
15use miden_protocol::errors::NoteError;
16use miden_protocol::note::{
17 Note,
18 NoteAssets,
19 NoteAttachment,
20 NoteAttachments,
21 NoteRecipient,
22 NoteScript,
23 NoteScriptRoot,
24 NoteStorage,
25 NoteType,
26 PartialNoteMetadata,
27};
28use miden_standards::note::costs::NoteConsumptionCost;
29use miden_standards::note::{NetworkAccountTarget, NoteExecutionHint};
30use miden_utils_sync::LazyLock;
31
32use crate::costs::DEREGISTER_AGG_FAUCET_CONSUMPTION_CYCLES;
33use crate::note_script;
34
35// NOTE SCRIPT
36// ================================================================================================
37
38/// Path to the DEREGISTER_AGG_FAUCET note script procedure in the agglayer package.
39const DEREGISTER_AGG_FAUCET_SCRIPT_PATH: &str = "::agglayer::notes::deregister_agg_faucet::main";
40
41// Initialize the DEREGISTER_AGG_FAUCET note script only once
42static DEREGISTER_AGG_FAUCET_SCRIPT: LazyLock<NoteScript> =
43 LazyLock::new(|| note_script(DEREGISTER_AGG_FAUCET_SCRIPT_PATH));
44
45// DEREGISTER_AGG_FAUCET NOTE
46// ================================================================================================
47
48/// DEREGISTER_AGG_FAUCET note.
49///
50/// Deregisters a faucet from the bridge's faucet registry, token registry, and faucet metadata.
51/// Carries only the faucet account ID; the bridge recomputes the token-registry key from its own
52/// stored metadata rather than trusting note-supplied values. The note is always public.
53///
54/// Any in-flight B2AGG / CLAIM notes targeting the faucet fail once this note is consumed, since
55/// `assert_faucet_registered` / `lookup_faucet_by_token_address` no longer find it.
56pub struct DeregisterAggFaucetNote;
57
58impl DeregisterAggFaucetNote {
59 // CONSTANTS
60 // --------------------------------------------------------------------------------------------
61
62 /// Expected number of storage items for a DEREGISTER_AGG_FAUCET note.
63 /// Layout: [faucet_id_suffix, faucet_id_prefix]
64 pub const NUM_STORAGE_ITEMS: usize = 2;
65
66 // PUBLIC ACCESSORS
67 // --------------------------------------------------------------------------------------------
68
69 /// Returns the DEREGISTER_AGG_FAUCET note script.
70 pub fn script() -> NoteScript {
71 DEREGISTER_AGG_FAUCET_SCRIPT.clone()
72 }
73
74 /// Returns the DEREGISTER_AGG_FAUCET note script root.
75 pub fn script_root() -> NoteScriptRoot {
76 DEREGISTER_AGG_FAUCET_SCRIPT.root()
77 }
78
79 // BUILDERS
80 // --------------------------------------------------------------------------------------------
81
82 /// Creates a DEREGISTER_AGG_FAUCET note to deregister a faucet from the bridge's registry.
83 ///
84 /// The note storage contains 2 felts:
85 /// - `faucet_id_suffix`: The suffix of the faucet account ID
86 /// - `faucet_id_prefix`: The prefix of the faucet account ID
87 ///
88 /// # Parameters
89 /// - `faucet_account_id`: The account ID of the faucet to deregister
90 /// - `sender_account_id`: The account ID of the note creator (must hold the `FAUCET_MNGR` role)
91 /// - `target_account_id`: The bridge account ID that will consume this note
92 /// - `rng`: Random number generator for creating the note serial number
93 ///
94 /// # Errors
95 /// Returns an error if note creation fails.
96 pub fn create<R: FeltRng>(
97 faucet_account_id: AccountId,
98 sender_account_id: AccountId,
99 target_account_id: AccountId,
100 rng: &mut R,
101 ) -> Result<Note, NoteError> {
102 // Create note storage with 2 felts: [faucet_id_suffix, faucet_id_prefix]
103 let storage_values: Vec<Felt> =
104 vec![faucet_account_id.suffix(), faucet_account_id.prefix().as_felt()];
105
106 let note_storage = NoteStorage::new(storage_values)?;
107
108 // Generate a serial number for the note
109 let serial_num = rng.draw_word();
110
111 let recipient = NoteRecipient::new(serial_num, Self::script(), note_storage);
112
113 let attachment = NetworkAccountTarget::new(target_account_id, NoteExecutionHint::Always)
114 .map_err(|e| NoteError::other(e.to_string()))?;
115 let attachments = NoteAttachments::from(NoteAttachment::from(attachment));
116 let metadata = PartialNoteMetadata::new(sender_account_id, NoteType::Public);
117
118 // DEREGISTER_AGG_FAUCET notes don't carry assets
119 let assets = NoteAssets::new(vec![])?;
120
121 Ok(Note::with_attachments(assets, metadata, recipient, attachments))
122 }
123}
124
125// NOTE CONSUMPTION COST
126// ================================================================================================
127
128impl NoteConsumptionCost for DeregisterAggFaucetNote {
129 fn consumption_cycles() -> u32 {
130 DEREGISTER_AGG_FAUCET_CONSUMPTION_CYCLES
131 }
132}