use super::*;
impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
pub fn find_block_height_from_state_root(&self, state_root: N::StateRoot) -> Result<Option<u32>> {
self.vm.block_store().find_block_height_from_state_root(state_root)
}
pub fn find_block_hash(&self, transaction_id: &N::TransactionID) -> Result<Option<N::BlockHash>> {
self.vm.block_store().find_block_hash(transaction_id)
}
pub fn find_block_height_from_puzzle_commitment(
&self,
puzzle_commitment: &PuzzleCommitment<N>,
) -> Result<Option<u32>> {
self.vm.block_store().find_block_height_from_puzzle_commitment(puzzle_commitment)
}
pub fn find_transaction_id_from_program_id(&self, program_id: &ProgramID<N>) -> Result<Option<N::TransactionID>> {
self.vm.transaction_store().find_transaction_id_from_program_id(program_id)
}
pub fn find_transaction_id_from_transition_id(
&self,
transition_id: &N::TransitionID,
) -> Result<Option<N::TransactionID>> {
self.vm.transaction_store().find_transaction_id_from_transition_id(transition_id)
}
pub fn find_transition_id(&self, id: &Field<N>) -> Result<N::TransitionID> {
self.vm.transition_store().find_transition_id(id)
}
pub fn find_record_ciphertexts<'a>(
&'a self,
view_key: &'a ViewKey<N>,
filter: RecordsFilter<N>,
) -> Result<impl '_ + Iterator<Item = (Field<N>, Cow<'_, Record<N, Ciphertext<N>>>)>> {
let address_x_coordinate = view_key.to_address().to_x_coordinate();
let sk_tag = match GraphKey::try_from(view_key) {
Ok(graph_key) => graph_key.sk_tag(),
Err(e) => bail!("Failed to derive the graph key from the view key: {e}"),
};
Ok(self.records().flat_map(move |cow| {
let (commitment, record) = match cow {
(Cow::Borrowed(commitment), record) => (*commitment, record),
(Cow::Owned(commitment), record) => (commitment, record),
};
let commitment = match filter {
RecordsFilter::All => Ok(Some(commitment)),
RecordsFilter::Spent => Record::<N, Plaintext<N>>::tag(sk_tag, commitment).and_then(|tag| {
self.contains_tag(&tag).map(|is_spent| match is_spent {
true => Some(commitment),
false => None,
})
}),
RecordsFilter::Unspent => Record::<N, Plaintext<N>>::tag(sk_tag, commitment).and_then(|tag| {
self.contains_tag(&tag).map(|is_spent| match is_spent {
true => None,
false => Some(commitment),
})
}),
RecordsFilter::SlowSpent(private_key) => {
Record::<N, Plaintext<N>>::serial_number(private_key, commitment).and_then(|serial_number| {
self.contains_serial_number(&serial_number).map(|is_spent| match is_spent {
true => Some(commitment),
false => None,
})
})
}
RecordsFilter::SlowUnspent(private_key) => {
Record::<N, Plaintext<N>>::serial_number(private_key, commitment).and_then(|serial_number| {
self.contains_serial_number(&serial_number).map(|is_spent| match is_spent {
true => None,
false => Some(commitment),
})
})
}
};
match commitment {
Ok(Some(commitment)) => {
match record.is_owner_with_address_x_coordinate(view_key, &address_x_coordinate) {
true => Some((commitment, record)),
false => None,
}
}
Ok(None) => None,
Err(e) => {
warn!("Failed to process 'find_record_ciphertexts({:?})': {e}", filter);
None
}
}
}))
}
pub fn find_records<'a>(
&'a self,
view_key: &'a ViewKey<N>,
filter: RecordsFilter<N>,
) -> Result<impl '_ + Iterator<Item = (Field<N>, Record<N, Plaintext<N>>)>> {
self.find_record_ciphertexts(view_key, filter).map(|iter| {
iter.flat_map(|(commitment, record)| match record.decrypt(view_key) {
Ok(record) => Some((commitment, record)),
Err(e) => {
warn!("Failed to decrypt the record: {e}");
None
}
})
})
}
}