use alloc::vec::Vec;
use miden_protocol::note::NoteScriptRoot;
use crate::note::{
AllowlistConfigNote,
BlocklistConfigNote,
BurnNote,
ConstantFeePolicyConfigNote,
FaucetMetadataConfigNote,
FaucetPolicyConfigNote,
FeeSponsorshipNote,
MinBurnAmountConfigNote,
MintNote,
NetworkAccountConfigNote,
OwnerConfigNote,
P2idNote,
P2ideNote,
PauseConfigNote,
PswapNote,
RbacConfigNote,
StandardNote,
SwapNote,
};
mod table;
pub use table::*;
pub trait NoteConsumptionCost {
fn consumption_cycles() -> u32;
fn created_notes() -> Vec<NoteScriptRoot> {
Vec::new()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NoteCost {
cycles: u32,
created_notes: Vec<NoteScriptRoot>,
}
impl NoteCost {
pub fn new(cycles: u32, created_notes: Vec<NoteScriptRoot>) -> Self {
Self { cycles, created_notes }
}
pub fn of<N: NoteConsumptionCost>() -> Self {
Self::new(N::consumption_cycles(), N::created_notes())
}
pub fn cycles(&self) -> u32 {
self.cycles
}
pub fn created_notes(&self) -> &[NoteScriptRoot] {
&self.created_notes
}
}
impl StandardNote {
pub fn note_cost(root: NoteScriptRoot) -> Option<NoteCost> {
match StandardNote::from_script_root(root)? {
StandardNote::P2ID => Some(NoteCost::of::<P2idNote>()),
StandardNote::P2IDE => Some(NoteCost::of::<P2ideNote>()),
StandardNote::SWAP => Some(NoteCost::of::<SwapNote>()),
StandardNote::PSWAP => Some(NoteCost::of::<PswapNote>()),
StandardNote::MINT => Some(NoteCost::of::<MintNote>()),
StandardNote::BURN => Some(NoteCost::of::<BurnNote>()),
StandardNote::CONSTANT_FEE_POLICY_CONFIG => {
Some(NoteCost::of::<ConstantFeePolicyConfigNote>())
},
StandardNote::FAUCET_POLICY_CONFIG => Some(NoteCost::of::<FaucetPolicyConfigNote>()),
StandardNote::FAUCET_METADATA_CONFIG => {
Some(NoteCost::of::<FaucetMetadataConfigNote>())
},
StandardNote::MIN_BURN_AMOUNT_CONFIG => Some(NoteCost::of::<MinBurnAmountConfigNote>()),
StandardNote::ALLOWLIST_CONFIG => Some(NoteCost::of::<AllowlistConfigNote>()),
StandardNote::BLOCKLIST_CONFIG => Some(NoteCost::of::<BlocklistConfigNote>()),
StandardNote::PAUSE_CONFIG => Some(NoteCost::of::<PauseConfigNote>()),
StandardNote::OWNER_CONFIG => Some(NoteCost::of::<OwnerConfigNote>()),
StandardNote::RBAC_CONFIG => Some(NoteCost::of::<RbacConfigNote>()),
StandardNote::NETWORK_ACCOUNT_CONFIG => {
Some(NoteCost::of::<NetworkAccountConfigNote>())
},
StandardNote::FEE_SPONSORSHIP => Some(NoteCost::of::<FeeSponsorshipNote>()),
StandardNote::TX_FEE => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::note::TxFeeNote;
#[test]
fn note_cost_pins_every_priced_standard_note_to_its_table_constant() {
for (root, expected_cycles) in [
(P2idNote::script_root(), P2ID_CONSUMPTION_CYCLES),
(P2ideNote::script_root(), P2IDE_CONSUMPTION_CYCLES),
(SwapNote::script_root(), SWAP_CONSUMPTION_CYCLES),
(PswapNote::script_root(), PSWAP_CONSUMPTION_CYCLES),
(MintNote::script_root(), MINT_CONSUMPTION_CYCLES),
(BurnNote::script_root(), BURN_CONSUMPTION_CYCLES),
(
ConstantFeePolicyConfigNote::script_root(),
CONSTANT_FEE_POLICY_CONFIG_CONSUMPTION_CYCLES,
),
(FaucetPolicyConfigNote::script_root(), FAUCET_POLICY_CONFIG_CONSUMPTION_CYCLES),
(
FaucetMetadataConfigNote::script_root(),
FAUCET_METADATA_CONFIG_CONSUMPTION_CYCLES,
),
(
MinBurnAmountConfigNote::script_root(),
MIN_BURN_AMOUNT_CONFIG_CONSUMPTION_CYCLES,
),
(AllowlistConfigNote::script_root(), ALLOWLIST_CONFIG_CONSUMPTION_CYCLES),
(BlocklistConfigNote::script_root(), BLOCKLIST_CONFIG_CONSUMPTION_CYCLES),
(PauseConfigNote::script_root(), PAUSE_CONFIG_CONSUMPTION_CYCLES),
(OwnerConfigNote::script_root(), OWNER_CONFIG_CONSUMPTION_CYCLES),
(RbacConfigNote::script_root(), RBAC_CONFIG_CONSUMPTION_CYCLES),
(
NetworkAccountConfigNote::script_root(),
NETWORK_ACCOUNT_CONFIG_CONSUMPTION_CYCLES,
),
(FeeSponsorshipNote::script_root(), FEE_SPONSORSHIP_CONSUMPTION_CYCLES),
] {
let cost = StandardNote::note_cost(root).expect("standard note should have a cost");
assert_eq!(cost.cycles(), expected_cycles);
}
assert!(StandardNote::note_cost(TxFeeNote::script_root()).is_none());
}
}