Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 55 additions & 4 deletions rust/cardano-chain-follower/src/multi_era_block_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ impl MultiEraBlock {
/// # Errors
///
/// If the given bytes cannot be decoded as a multi-era block, an error is returned.
pub fn new(
pub(crate) fn new(
chain: Network, raw_data: Vec<u8>, previous: &Point, fork: u64,
) -> anyhow::Result<Self, Error> {
// This lets us reliably count any bad block arising from deserialization.
Expand All @@ -170,55 +170,93 @@ impl MultiEraBlock {
}

/// Remake the block on a new fork.
pub fn set_fork(&mut self, fork: u64) {
pub(crate) fn set_fork(&mut self, fork: u64) {
self.fork = fork;
}

/// Decodes the data into a multi-era block.
///
/// # Returns
/// The decoded block data, which can easily be processed by a consumer.
#[must_use]
#[allow(clippy::missing_panics_doc)]
pub fn decode(&self) -> &pallas::ledger::traverse::MultiEraBlock {
self.inner.data.borrow_block()
}

/// Decodes the data into a multi-era block.
///
/// # Returns
/// The raw byte data of the block.
#[must_use]
#[allow(clippy::missing_panics_doc)]
pub fn raw(&self) -> &Vec<u8> {
self.inner.data.borrow_raw_data()
}

/// Returns the block point of this block.
///
/// # Returns
/// The block point of this block.
#[must_use]
pub fn point(&self) -> Point {
self.inner.point.clone()
}

/// Returns the block point of the previous block.
///
/// # Returns
/// The previous blocks `Point`
#[must_use]
pub fn previous(&self) -> Point {
self.inner.previous.clone()
}

/// Is the block data immutable on-chain.
///
/// Immutable blocks are by-definition those that exist in the Mithril Snapshot
/// (Immutable Database) of the Node.
///
/// # Returns
/// `true` if the block is immutable, `false` otherwise.
#[must_use]
pub fn immutable(&self) -> bool {
self.fork == 0
}

/// Is the block data immutable on-chain.
/// What fork is the block from.
///
/// The fork is a synthetic number that represents how many rollbacks have been
/// detected in the running chain. The fork is:
/// - 0 - for all immutable data;
/// - 1 - for any data read from the blockchain during a *backfill* on initial sync
/// - 2+ - for each subsequent rollback detected while reading live blocks.
///
/// # Returns
/// The fork the block was found on.
#[must_use]
pub fn fork(&self) -> u64 {
self.fork
}

/// What chain was the block from
///
/// # Returns
/// - The chain that this block originated on.
#[must_use]
pub fn chain(&self) -> Network {
self.inner.chain
}

/// Get The Decoded Metadata fora a transaction and known label from the block
///
/// # Parameters
/// - `txn_idx` - Index of the Transaction in the Block
/// - `label` - The label of the transaction
///
/// # Returns
/// - Metadata for the given label in the transaction.
/// - Or None if the label requested isn't present.
#[must_use]
pub fn txn_metadata(
&self, txn_idx: usize, label: u64,
Expand All @@ -233,10 +271,23 @@ impl MultiEraBlock {
}

/// Returns the witness map for the block.
#[allow(dead_code)]
pub(crate) fn witness_map(&self) -> Option<&TxWitness> {
self.inner.witness_map.as_ref()
}

/// If the Witness exists for a given transaction then return its public key.
#[must_use]
pub fn witness_for_tx(&self, vkey_hash: &[u8; 28], tx_num: u16) -> Option<Vec<u8>> {
if let Some(witnesses) = self.witness_map() {
if witnesses.check_witness_in_tx(vkey_hash, tx_num) {
if let Some(pub_key) = witnesses.get_witness_pk_addr(vkey_hash) {
return Some(pub_key.into());
}
}
}

None
}
}

impl Display for MultiEraBlock {
Expand Down
19 changes: 8 additions & 11 deletions rust/cardano-chain-follower/src/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@ use crate::utils::blake2b_244;
/// `WitnessMap` type of `DashMap` with
/// key as [u8; 28] = (`blake2b_244` hash of the public key)
/// value as `(Bytes, Vec<u8>) = (public key, tx index within the block)`
#[allow(dead_code)]
pub(crate) type WitnessMap = DashMap<[u8; 28], (Bytes, Vec<u8>)>;
pub(crate) type WitnessMap = DashMap<[u8; 28], (Bytes, Vec<u16>)>;

#[derive(Debug)]
#[allow(dead_code)]
/// `TxWitness` struct to store the witness data.
pub(crate) struct TxWitness(WitnessMap);

#[allow(dead_code)]
impl TxWitness {
/// Create a new `TxWitness` from a list of `MultiEraTx`.
pub(crate) fn new(txs: &[MultiEraTx]) -> anyhow::Result<Self> {
Expand All @@ -29,9 +26,9 @@ impl TxWitness {
if let Some(vkey_witness_set) = witness_set.vkeywitness.clone() {
for vkey_witness in vkey_witness_set {
let vkey_hash = blake2b_244(&vkey_witness.vkey)?;
let tx_num = u8::try_from(i)?;
let tx_num = u16::try_from(i)?;
map.entry(vkey_hash)
.and_modify(|entry: &mut (_, Vec<u8>)| entry.1.push(tx_num))
.and_modify(|entry: &mut (_, Vec<u16>)| entry.1.push(tx_num))
.or_insert((vkey_witness.vkey.clone(), vec![tx_num]));
}
};
Expand All @@ -41,9 +38,9 @@ impl TxWitness {
if let Some(vkey_witness_set) = witness_set.vkeywitness.clone() {
for vkey_witness in vkey_witness_set {
let vkey_hash = blake2b_244(&vkey_witness.vkey)?;
let tx_num = u8::try_from(i)?;
let tx_num = u16::try_from(i)?;
map.entry(vkey_hash)
.and_modify(|entry: &mut (_, Vec<u8>)| entry.1.push(tx_num))
.and_modify(|entry: &mut (_, Vec<u16>)| entry.1.push(tx_num))
.or_insert((vkey_witness.vkey.clone(), vec![tx_num]));
}
}
Expand All @@ -53,9 +50,9 @@ impl TxWitness {
if let Some(vkey_witness_set) = &witness_set.vkeywitness.clone() {
for vkey_witness in vkey_witness_set {
let vkey_hash = blake2b_244(&vkey_witness.vkey)?;
let tx_num = u8::try_from(i)?;
let tx_num = u16::try_from(i)?;
map.entry(vkey_hash)
.and_modify(|entry: &mut (_, Vec<u8>)| entry.1.push(tx_num))
.and_modify(|entry: &mut (_, Vec<u16>)| entry.1.push(tx_num))
.or_insert((vkey_witness.vkey.clone(), vec![tx_num]));
}
}
Expand All @@ -67,7 +64,7 @@ impl TxWitness {
}

/// Check whether the public key hash is in the given transaction number.
pub(crate) fn check_witness_in_tx(&self, vkey_hash: &[u8; 28], tx_num: u8) -> bool {
pub(crate) fn check_witness_in_tx(&self, vkey_hash: &[u8; 28], tx_num: u16) -> bool {
self.0
.get(vkey_hash)
.map_or(false, |entry| entry.1.contains(&tx_num))
Expand Down
1 change: 1 addition & 0 deletions rust/deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ version = 2
ignore = [
{ id = "RUSTSEC-2020-0168", reason = "`mach` is used by wasmtime and we have no control over that." },
{ id = "RUSTSEC-2021-0145", reason = "we don't target windows, and don't use a custom global allocator." },
{ id = "RUSTSEC-2024-0370", reason = "`proc-macro-error` is used by crates we rely on, we can't control what they use."},
]

[bans]
Expand Down