Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple namespaces in QueryablePayload::transaction_with_proof #1212

Merged
merged 2 commits into from
Mar 15, 2024
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
1 change: 0 additions & 1 deletion sequencer/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ impl BlockPayload for Payload<TxTableEntryWord> {
{
Self {
raw_payload: encoded_transactions.into_iter().collect(),
tx_table_len_proof: Default::default(),
ns_table: metadata.clone(), // TODO don't clone ns_table
}
}
Expand Down
82 changes: 24 additions & 58 deletions sequencer/src/block/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use commit::Committable;
use derivative::Derivative;
use hotshot::traits::BlockPayload;
use hotshot_types::vid::{
vid_scheme, LargeRangeProofType, SmallRangeProofType, VidCommitment, VidCommon, VidSchemeType,
vid_scheme, LargeRangeProofType, VidCommitment, VidCommon, VidSchemeType,
};
use jf_primitives::vid::{
payload_prover::{PayloadProver, Statement},
Expand All @@ -19,7 +19,6 @@ use num_traits::PrimInt;
use serde::{Deserialize, Serialize};
use snafu::OptionExt;
use std::default::Default;
use std::sync::OnceLock;
use std::{collections::HashMap, fmt::Display, ops::Range};

use crate::block::tables::NameSpaceTable;
Expand Down Expand Up @@ -76,14 +75,14 @@ pub struct Payload<TableWord: TableWordTraits> {

// Sequence of bytes representing the namespace table
pub(super) ns_table: NameSpaceTable<TableWord>,

// cache frequently used items
// TODO(X) Revisit caching of frequently used items
//
// TODO type should be `OnceLock<SmallRangeProofType>` instead of `OnceLock<Option<SmallRangeProofType>>`. We can correct this after `once_cell_try` is stabilized <https://github.com/rust-lang/rust/issues/109737>.
#[derivative(Hash = "ignore")]
#[derivative(PartialEq = "ignore")]
#[serde(skip)]
pub tx_table_len_proof: OnceLock<Option<SmallRangeProofType>>,
// TODO type should be `OnceLock<SmallRangeProofType>` instead of `OnceLock<Option<SmallRangeProofType>>`.
// We can correct this after `once_cell_try` is stabilized <https://github.com/rust-lang/rust/issues/109737>.
// #[derivative(Hash = "ignore")]
// #[derivative(PartialEq = "ignore")]
// #[serde(skip)]
// pub tx_table_len_proof: OnceLock<Option<SmallRangeProofType>>,
}

impl<TableWord: TableWordTraits> Payload<TableWord> {
Expand Down Expand Up @@ -136,33 +135,6 @@ impl<TableWord: TableWordTraits> Payload<TableWord> {
})
}

/// Return length of the tx table, read from the payload bytes.
///
/// This quantity equals number of txs in the payload.
pub fn get_tx_table_len(&self) -> TxTableEntry {
let tx_table_len_range = self.tx_table_len_range();
let mut entry_bytes = [0u8; TxTableEntry::byte_len()];
entry_bytes[..tx_table_len_range.len()]
.copy_from_slice(&self.raw_payload[tx_table_len_range]);

TxTableEntry::from_bytes_array(entry_bytes)
}

// Fetch the tx table length range proof from cache.
// Build the proof if missing from cache.
// Returns `None` if an error occurred.
pub fn get_tx_table_len_proof(
&self,
vid: &impl PayloadProver<SmallRangeProofType>,
) -> Option<&SmallRangeProofType> {
self.tx_table_len_proof
.get_or_init(|| {
vid.payload_proof(&self.raw_payload, self.tx_table_len_range())
.ok()
})
.as_ref()
}

pub fn get_ns_table(&self) -> &NameSpaceTable<TableWord> {
&self.ns_table
}
Expand All @@ -174,7 +146,6 @@ impl<TableWord: TableWordTraits> Payload<TableWord> {
let mut structured_payload = Self {
raw_payload: bytes![],
ns_table: NameSpaceTable::default(),
tx_table_len_proof: Default::default(),
};
for tx in txs.into_iter() {
Payload::<TableWord>::update_namespace_with_tx(&mut namespaces, tx);
Expand Down Expand Up @@ -236,14 +207,6 @@ impl<TableWord: TableWordTraits> Payload<TableWord> {
self.raw_payload = payload;
Ok(())
}

/// Return a range `r` such that `self.payload[r]` is the bytes of the tx table length.
///
/// Typically `r` is `0..TxTableEntry::byte_len()`.
/// But it might differ from this if the payload byte length is less than `TxTableEntry::byte_len()`.
fn tx_table_len_range(&self) -> Range<usize> {
0..std::cmp::min(TxTableEntry::byte_len(), self.raw_payload.len())
}
}

impl<TableWord: TableWordTraits + std::fmt::Debug> Display for Payload<TableWord> {
Expand Down Expand Up @@ -374,7 +337,7 @@ mod test {
entry::{TxTableEntry, TxTableEntryWord},
payload::{Payload, TableWordTraits},
queryable,
tables::{test::TxTableTest, NameSpaceTable, Table},
tables::{test::TxTableTest, NameSpaceTable, Table, TxTable},
tx_iterator::TxIndex,
},
Transaction,
Expand Down Expand Up @@ -426,7 +389,6 @@ mod test {
setup_logging();
setup_backtrace();
let mut rng = jf_utils::test_rng();

struct NamespaceInfo {
payload_flat: Vec<u8>,
tx_table: Vec<TxTableEntry>, // TODO Philippe => change
Expand Down Expand Up @@ -634,16 +596,15 @@ mod test {
assert_eq!(ns_id, tx.namespace());
assert_eq!(tx_payload, tx.payload());

// TODO(1010) transaction_with_proof for multiple namespaces
// test `transaction_with_proof()`
// let (tx, proof) = block
// .transaction_with_proof(&actual_ns_table, &idx)
// .unwrap();
// assert_eq!(tx_payload, tx.payload());
// proof
// .verify(&tx, idx, &vid, &disperse_data.commit, &disperse_data.common)
// .unwrap()
// .unwrap();
let (tx, proof) = block
.transaction_with_proof(&actual_ns_table, &idx)
.unwrap();
assert_eq!(tx_payload, tx.payload());
proof
.verify(&tx, idx, &vid, &disperse_data.commit, &disperse_data.common)
.unwrap()
.unwrap();
}

prev_entry = entry;
Expand Down Expand Up @@ -789,8 +750,13 @@ mod test {
// make a fake proof for a nonexistent tx in the small block
let tx = Transaction::new(Default::default(), Vec::new());
let proof = queryable::gen_tx_proof_for_testing(
block.get_tx_table_len(),
block.get_tx_table_len_proof(&vid).unwrap().clone(),
0..block.raw_payload.len(),
TxTableEntry::from_usize(TxTable::get_tx_table_len(&block.raw_payload)),
vid.payload_proof(
&block.raw_payload,
0..std::cmp::min(TxTableEntry::byte_len(), block.raw_payload.len()),
)
.unwrap(),
vid.payload_proof(&block.raw_payload, 0..3).unwrap(),
);

Expand Down
Loading
Loading