1use super::*;
17
18impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
19 pub fn find_block_height_from_state_root(&self, state_root: N::StateRoot) -> Result<Option<u32>> {
21 self.vm.block_store().find_block_height_from_state_root(state_root)
22 }
23
24 pub fn find_block_hash(&self, transaction_id: &N::TransactionID) -> Result<Option<N::BlockHash>> {
26 self.vm.block_store().find_block_hash(transaction_id)
27 }
28
29 pub fn find_block_height_from_solution_id(&self, solution_id: &SolutionID<N>) -> Result<Option<u32>> {
31 self.vm.block_store().find_block_height_from_solution_id(solution_id)
32 }
33
34 pub fn find_latest_transaction_id_from_program_id(
36 &self,
37 program_id: &ProgramID<N>,
38 ) -> Result<Option<N::TransactionID>> {
39 self.vm.transaction_store().find_latest_transaction_id_from_program_id(program_id)
40 }
41
42 pub fn find_transaction_id_from_program_id_and_edition(
44 &self,
45 program_id: &ProgramID<N>,
46 edition: u16,
47 ) -> Result<Option<N::TransactionID>> {
48 self.vm.transaction_store().find_transaction_id_from_program_id_and_edition(program_id, edition)
49 }
50
51 pub fn find_transaction_id_from_transition_id(
53 &self,
54 transition_id: &N::TransitionID,
55 ) -> Result<Option<N::TransactionID>> {
56 self.vm.transaction_store().find_transaction_id_from_transition_id(transition_id)
57 }
58
59 pub fn find_transition_id(&self, id: &Field<N>) -> Result<N::TransitionID> {
61 self.vm.transition_store().find_transition_id(id)
62 }
63
64 #[allow(clippy::type_complexity)]
66 pub fn find_record_ciphertexts<'a>(
67 &'a self,
68 view_key: &'a ViewKey<N>,
69 filter: RecordsFilter<N>,
70 ) -> Result<impl 'a + Iterator<Item = (Field<N>, Cow<'a, Record<N, Ciphertext<N>>>)>> {
71 let address_x_coordinate = view_key.to_address().to_x_coordinate();
73 let sk_tag = match GraphKey::try_from(view_key) {
75 Ok(graph_key) => graph_key.sk_tag(),
76 Err(e) => bail!("Failed to derive the graph key from the view key: {e}"),
77 };
78
79 Ok(self.records().flat_map(move |cow| {
80 let (commitment, record) = match cow {
82 (Cow::Borrowed(commitment), record) => (*commitment, record),
83 (Cow::Owned(commitment), record) => (commitment, record),
84 };
85
86 let commitment = match filter {
88 RecordsFilter::All => Ok(Some(commitment)),
89 RecordsFilter::Spent => Record::<N, Plaintext<N>>::tag(sk_tag, commitment).and_then(|tag| {
90 self.contains_tag(&tag).map(|is_spent| match is_spent {
92 true => Some(commitment),
93 false => None,
94 })
95 }),
96 RecordsFilter::Unspent => Record::<N, Plaintext<N>>::tag(sk_tag, commitment).and_then(|tag| {
97 self.contains_tag(&tag).map(|is_spent| match is_spent {
99 true => None,
100 false => Some(commitment),
101 })
102 }),
103 RecordsFilter::SlowSpent(private_key) => {
104 Record::<N, Plaintext<N>>::serial_number(private_key, commitment).and_then(|serial_number| {
105 self.contains_serial_number(&serial_number).map(|is_spent| match is_spent {
107 true => Some(commitment),
108 false => None,
109 })
110 })
111 }
112 RecordsFilter::SlowUnspent(private_key) => {
113 Record::<N, Plaintext<N>>::serial_number(private_key, commitment).and_then(|serial_number| {
114 self.contains_serial_number(&serial_number).map(|is_spent| match is_spent {
116 true => None,
117 false => Some(commitment),
118 })
119 })
120 }
121 };
122
123 match commitment {
124 Ok(Some(commitment)) => {
125 match record.is_owner_with_address_x_coordinate(view_key, &address_x_coordinate) {
126 true => Some((commitment, record)),
127 false => None,
128 }
129 }
130 Ok(None) => None,
131 Err(e) => {
132 warn!("Failed to process 'find_record_ciphertexts({:?})': {e}", filter);
133 None
134 }
135 }
136 }))
137 }
138
139 #[allow(clippy::type_complexity)]
141 pub fn find_records<'a>(
142 &'a self,
143 view_key: &'a ViewKey<N>,
144 filter: RecordsFilter<N>,
145 ) -> Result<impl 'a + Iterator<Item = (Field<N>, Record<N, Plaintext<N>>)>> {
146 self.find_record_ciphertexts(view_key, filter).map(|iter| {
147 iter.flat_map(|(commitment, record)| match record.decrypt(view_key) {
148 Ok(record) => Some((commitment, record)),
149 Err(e) => {
150 warn!("Failed to decrypt the record: {e}");
151 None
152 }
153 })
154 })
155 }
156}