Skip to content

Commit

Permalink
transaction with support for multiple namespaces (#1205)
Browse files Browse the repository at this point in the history
  • Loading branch information
akonring authored Mar 8, 2024
1 parent a5386ab commit 2eba5a8
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 54 deletions.
47 changes: 19 additions & 28 deletions sequencer/src/block/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ mod test {
ns_proof_txs,
derived_ns
.tx_payloads
.clone()
.into_iter()
.map(|p| Transaction::new(ns_id, p))
.collect::<Vec<Transaction>>()
Expand Down Expand Up @@ -626,40 +627,30 @@ mod test {
);

// testing tx iterator
// TODO(746) incorporate this test into the following commented code when it's fixed
for tx_idx in 0..derived_ns.tx_table.len() {
let next_tx = block_iter.next().unwrap();
assert_eq!(ns_idx, next_tx.ns_idx);
assert_eq!(tx_idx, next_tx.tx_idx);

let idx = TxIndex { ns_idx, tx_idx };
let tx = block.transaction(&actual_ns_table, &idx).unwrap();
let tx_payload = derived_ns.tx_payloads[tx_idx].to_vec();
// test `transaction()`
assert_eq!(ns_id, tx.vm());
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();
}

// tests for individual txs in this namespace
// TODO(746) rework this part
//
// let mut block_iter = block.iter(); // test iterator correctness
// for (tx_index, tx_payload) in ns.tx_payloads.iter().enumerate() {
// assert!(block_iter.next().is_some());
// let tx_index = TxIndex::try_from(tx_index + tx_index_offset).unwrap();
// tracing::info!("tx index {}", tx_index,);
//
// // test `transaction_with_proof()`
// let (tx, proof) = block.transaction_with_proof(&tx_index).unwrap();
// assert_eq!(tx_payload, tx.payload());
// proof
// .verify(
// &tx,
// tx_index,
// &vid,
// &disperse_data.commit,
// &disperse_data.common,
// )
// .unwrap()
// .unwrap();
// }
// assert!(block_iter.next().is_none());

// prepare for the next loop iteration
// tx_index_offset += actual_tx_table.len();
prev_entry = entry;
derived_block_payload.extend(derived_ns.payload_flat.clone());
}
Expand Down
74 changes: 48 additions & 26 deletions sequencer/src/block/queryable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,44 +69,66 @@ impl QueryablePayload for Payload<TxTableEntryWord> {
meta: &Self::Metadata,
index: &Self::TransactionIndex,
) -> Option<Self::Transaction> {
let index_usize = index.tx_idx; // TODO fix in https://github.com/EspressoSystems/espresso-sequencer/issues/1010
if index_usize >= self.len(meta) {
let (ns_idx, tx_idx) = (index.ns_idx, index.tx_idx);
if ns_idx >= meta.len() {
return None; // error: index out of bounds
}
let (ns_id, _offset) = meta.get_table_entry(ns_idx);
let ns_range = meta.get_payload_range(ns_idx, self.raw_payload.len());
let ns_start_offset = ns_range.start;

let tx_table_len = TxTable::get_tx_table_len(&self.raw_payload[ns_range.clone()]);
if tx_idx >= tx_table_len {
return None; // error: index out of bounds
}

let tx_payloads_offset = tx_table_len
.checked_add(1)?
.checked_mul(TxTableEntry::byte_len())?
.checked_add(ns_start_offset)?;

// start
let tx_table_range_start = if index_usize == 0 {
let tx_table_range_start = if tx_idx == 0 {
None
} else {
let range_proof_start = index_usize.checked_mul(TxTableEntry::byte_len())?;
let offset = tx_idx
.checked_mul(TxTableEntry::byte_len())?
.checked_add(ns_start_offset)?;
Some(TxTableEntry::from_bytes(self.raw_payload.get(
range_proof_start..range_proof_start.checked_add(TxTableEntry::byte_len())?,
offset..offset.checked_add(TxTableEntry::byte_len())?,
)?)?)
};

// end
let tx_table_range_proof_end = index_usize
.checked_add(2)?
.checked_mul(TxTableEntry::byte_len())?;
let tx_table_range_end = TxTableEntry::from_bytes(self.raw_payload.get(
tx_table_range_proof_end.checked_sub(TxTableEntry::byte_len())?
..tx_table_range_proof_end,
)?)?;
let tx_table_range_end = {
let tx_table_end_offset = tx_idx
.checked_add(1)?
.checked_mul(TxTableEntry::byte_len())?
.checked_add(ns_start_offset)?;

let tx_payload_range = tx_payload_range(
&tx_table_range_start,
&tx_table_range_end,
&self.get_tx_table_len(),
self.raw_payload.len(),
)?;
Some(
// TODO don't copy the tx bytes into the return value
// https://github.com/EspressoSystems/hotshot-query-service/issues/267
Transaction::new(
crate::VmId(0),
self.raw_payload.get(tx_payload_range.clone())?.to_vec(),
),
)
TxTableEntry::from_bytes(self.raw_payload.get(
tx_table_end_offset..tx_table_end_offset.checked_add(TxTableEntry::byte_len())?,
)?)?
};

let (tx_payload_start, tx_payload_end) = {
let start =
usize::try_from(tx_table_range_start.clone().unwrap_or(TxTableEntry::zero()))
.ok()?
.checked_add(tx_payloads_offset)?;
let end = usize::try_from(tx_table_range_end.clone())
.ok()?
.checked_add(tx_payloads_offset)?;
let end = std::cmp::min(end, ns_range.end);
let start = std::cmp::min(start, end);
(start, end)
};

let tx_payload = self
.raw_payload
.get(tx_payload_start..tx_payload_end)?
.to_vec();
Some(Transaction::new(ns_id, tx_payload))
}

// TODO currently broken, fix in https://github.com/EspressoSystems/espresso-sequencer/issues/1010
Expand Down

0 comments on commit 2eba5a8

Please sign in to comment.