snarkvm_console_program/state_path/transition_leaf/
mod.rs1mod bytes;
17mod serialize;
18mod string;
19mod to_bits;
20
21use snarkvm_console_network::prelude::*;
22use snarkvm_console_types::Field;
23
24#[derive(Copy, Clone, Debug, PartialEq, Eq)]
26#[repr(u8)]
27pub enum LeafVersion {
28 Static = 1,
30 Dynamic = 2,
32}
33
34impl TryFrom<u8> for LeafVersion {
35 type Error = Error;
36
37 fn try_from(value: u8) -> Result<Self> {
38 match value {
39 1 => Ok(Self::Static),
40 2 => Ok(Self::Dynamic),
41 _ => bail!("Invalid transition leaf version: {value}"),
42 }
43 }
44}
45
46#[derive(Copy, Clone, PartialEq, Eq)]
48pub struct TransitionLeaf<N: Network> {
49 version: u8,
51 index: u8,
53 variant: u8,
55 id: Field<N>,
57}
58
59impl<N: Network> TransitionLeaf<N> {
60 pub const fn new(index: u8, variant: u8, id: Field<N>) -> Self {
62 Self { version: LeafVersion::Static as u8, index, variant, id }
63 }
64
65 pub const fn new_record_with_dynamic_id(index: u8, id: Field<N>) -> Self {
67 Self { version: LeafVersion::Dynamic as u8, index, variant: 3, id }
68 }
69
70 pub const fn new_external_record_with_dynamic_id(index: u8, id: Field<N>) -> Self {
72 Self { version: LeafVersion::Dynamic as u8, index, variant: 4, id }
73 }
74
75 pub fn from(version: u8, index: u8, variant: u8, id: Field<N>) -> Result<Self> {
78 let leaf_version = LeafVersion::try_from(version)?;
80 if matches!(leaf_version, LeafVersion::Dynamic) && variant != 3 && variant != 4 {
82 bail!("Dynamic transition leaf variant must be 3 (Record) or 4 (ExternalRecord), found {variant}");
83 }
84 Ok(Self { version, index, variant, id })
85 }
86
87 pub const fn version(&self) -> u8 {
89 self.version
90 }
91
92 pub const fn index(&self) -> u8 {
94 self.index
95 }
96
97 pub const fn variant(&self) -> u8 {
99 self.variant
100 }
101
102 pub const fn id(&self) -> Field<N> {
104 self.id
105 }
106}
107
108#[cfg(test)]
109mod test_helpers {
110 use super::*;
111 use snarkvm_console_network::MainnetV0;
112
113 type CurrentNetwork = MainnetV0;
114
115 pub(super) fn sample_leaf(rng: &mut TestRng) -> TransitionLeaf<CurrentNetwork> {
117 TransitionLeaf::new(rng.r#gen(), rng.r#gen(), Uniform::rand(rng))
119 }
120
121 pub(super) fn sample_dynamic_leaf(rng: &mut TestRng) -> TransitionLeaf<CurrentNetwork> {
123 if rng.r#gen() {
125 TransitionLeaf::new_record_with_dynamic_id(rng.r#gen(), Uniform::rand(rng))
126 } else {
127 TransitionLeaf::new_external_record_with_dynamic_id(rng.r#gen(), Uniform::rand(rng))
128 }
129 }
130}