Skip to main content

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}