miden_agglayer/
agglayer_note.rs1use miden_protocol::note::{NoteScript, NoteScriptRoot};
2use miden_standards::note::costs::NoteCost;
3
4use crate::{
5 B2AggNote,
6 ClaimNote,
7 ConfigAggBridgeNote,
8 DeregisterAggFaucetNote,
9 RemoveGerNote,
10 UpdateGerNote,
11};
12
13#[allow(non_camel_case_types)]
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum AgglayerNote {
21 CLAIM,
22 B2AGG,
23 CONFIG_AGG_BRIDGE,
24 DEREGISTER_AGG_FAUCET,
25 UPDATE_GER,
26 REMOVE_GER,
27}
28
29impl AgglayerNote {
30 pub fn from_script_root(root: NoteScriptRoot) -> Option<Self> {
36 match root {
37 r if r == ClaimNote::script_root() => Some(Self::CLAIM),
38 r if r == B2AggNote::script_root() => Some(Self::B2AGG),
39 r if r == ConfigAggBridgeNote::script_root() => Some(Self::CONFIG_AGG_BRIDGE),
40 r if r == DeregisterAggFaucetNote::script_root() => Some(Self::DEREGISTER_AGG_FAUCET),
41 r if r == UpdateGerNote::script_root() => Some(Self::UPDATE_GER),
42 r if r == RemoveGerNote::script_root() => Some(Self::REMOVE_GER),
43 _ => None,
44 }
45 }
46
47 pub fn name(&self) -> &'static str {
52 match self {
53 Self::CLAIM => "CLAIM",
54 Self::B2AGG => "B2AGG",
55 Self::CONFIG_AGG_BRIDGE => "CONFIG_AGG_BRIDGE",
56 Self::DEREGISTER_AGG_FAUCET => "DEREGISTER_AGG_FAUCET",
57 Self::UPDATE_GER => "UPDATE_GER",
58 Self::REMOVE_GER => "REMOVE_GER",
59 }
60 }
61
62 pub fn script(&self) -> NoteScript {
64 match self {
65 Self::CLAIM => ClaimNote::script(),
66 Self::B2AGG => B2AggNote::script(),
67 Self::CONFIG_AGG_BRIDGE => ConfigAggBridgeNote::script(),
68 Self::DEREGISTER_AGG_FAUCET => DeregisterAggFaucetNote::script(),
69 Self::UPDATE_GER => UpdateGerNote::script(),
70 Self::REMOVE_GER => RemoveGerNote::script(),
71 }
72 }
73
74 pub fn script_root(&self) -> NoteScriptRoot {
76 match self {
77 Self::CLAIM => ClaimNote::script_root(),
78 Self::B2AGG => B2AggNote::script_root(),
79 Self::CONFIG_AGG_BRIDGE => ConfigAggBridgeNote::script_root(),
80 Self::DEREGISTER_AGG_FAUCET => DeregisterAggFaucetNote::script_root(),
81 Self::UPDATE_GER => UpdateGerNote::script_root(),
82 Self::REMOVE_GER => RemoveGerNote::script_root(),
83 }
84 }
85
86 fn cost(&self) -> NoteCost {
88 match self {
89 Self::CLAIM => NoteCost::of::<ClaimNote>(),
90 Self::B2AGG => NoteCost::of::<B2AggNote>(),
91 Self::CONFIG_AGG_BRIDGE => NoteCost::of::<ConfigAggBridgeNote>(),
92 Self::DEREGISTER_AGG_FAUCET => NoteCost::of::<DeregisterAggFaucetNote>(),
93 Self::UPDATE_GER => NoteCost::of::<UpdateGerNote>(),
94 Self::REMOVE_GER => NoteCost::of::<RemoveGerNote>(),
95 }
96 }
97
98 pub fn note_cost(root: NoteScriptRoot) -> Option<NoteCost> {
104 Some(Self::from_script_root(root)?.cost())
105 }
106}
107
108#[cfg(test)]
112mod tests {
113 use miden_standards::note::{MintNote, P2idNote};
114
115 use super::*;
116 use crate::costs::{
117 B2AGG_CONSUMPTION_CYCLES,
118 CLAIM_CONSUMPTION_CYCLES,
119 CONFIG_AGG_BRIDGE_CONSUMPTION_CYCLES,
120 DEREGISTER_AGG_FAUCET_CONSUMPTION_CYCLES,
121 REMOVE_GER_CONSUMPTION_CYCLES,
122 UPDATE_GER_CONSUMPTION_CYCLES,
123 };
124
125 const ALL_NOTES: [AgglayerNote; 6] = [
126 AgglayerNote::CLAIM,
127 AgglayerNote::B2AGG,
128 AgglayerNote::CONFIG_AGG_BRIDGE,
129 AgglayerNote::DEREGISTER_AGG_FAUCET,
130 AgglayerNote::UPDATE_GER,
131 AgglayerNote::REMOVE_GER,
132 ];
133
134 #[test]
137 fn variant_tables_are_self_consistent_and_pin_the_table_constants() {
138 for note in ALL_NOTES {
139 assert_eq!(AgglayerNote::from_script_root(note.script_root()), Some(note));
140 assert_eq!(note.script().root(), note.script_root());
141
142 let expected_cycles = match note {
143 AgglayerNote::CLAIM => CLAIM_CONSUMPTION_CYCLES,
144 AgglayerNote::B2AGG => B2AGG_CONSUMPTION_CYCLES,
145 AgglayerNote::CONFIG_AGG_BRIDGE => CONFIG_AGG_BRIDGE_CONSUMPTION_CYCLES,
146 AgglayerNote::DEREGISTER_AGG_FAUCET => DEREGISTER_AGG_FAUCET_CONSUMPTION_CYCLES,
147 AgglayerNote::UPDATE_GER => UPDATE_GER_CONSUMPTION_CYCLES,
148 AgglayerNote::REMOVE_GER => REMOVE_GER_CONSUMPTION_CYCLES,
149 };
150 let cost = AgglayerNote::note_cost(note.script_root())
151 .expect("every agglayer note should have a cost");
152 assert_eq!(cost.cycles(), expected_cycles, "cost mismatch for {}", note.name());
153 }
154
155 assert_eq!(AgglayerNote::from_script_root(P2idNote::script_root()), None);
157 }
158
159 #[test]
160 fn note_cost_resolves_only_agglayer_notes() {
161 let claim_cost =
162 AgglayerNote::note_cost(ClaimNote::script_root()).expect("CLAIM should have a cost");
163 assert_eq!(claim_cost.cycles(), CLAIM_CONSUMPTION_CYCLES);
164 assert_eq!(claim_cost.created_notes(), [MintNote::script_root()]);
165
166 assert!(AgglayerNote::note_cost(P2idNote::script_root()).is_none());
167 }
168}