diff --git a/scripts/espresso_block_scanner.py b/scripts/espresso_block_scanner.py deleted file mode 100644 index 558689bd4..000000000 --- a/scripts/espresso_block_scanner.py +++ /dev/null @@ -1,130 +0,0 @@ -### Simple live Espresso block scanner -### Scan all blocks looking for transaction on each VM. -### For each found transaction, display the VM block containing that transaction, including inclusion proofs for transactions in the Espresso block. - -import argparse -from datetime import datetime -import urllib.request -import json -import time -import sys - -parser = argparse.ArgumentParser( - prog="Espresso Block Scanner", - description="Scans the espresso ledger looking for transactions. For each transaction it prints out the namespace block containing it", - epilog="", -) - -parser.add_argument("-u", "--url", default="http://localhost:50000") - -args = parser.parse_args() - -url = f"{args.url}/availability/block/" - -# Keep track of transaction to avoid showing duplicates -payloads = set() - -# Find the current block number. -res = urllib.request.urlopen(f"{args.url}/status/latest_block_height") -block_number = int(res.read()) -print(f"scanning from block {block_number}") - -# Scan block by block -while True: - try: - page = urllib.request.urlopen(f"{url}{block_number}") - except urllib.error.HTTPError as e: - # "Block not produced yet. waiting for 1 second - time.sleep(1) - continue - except urllib.error.URLError as ex: - # Server is down, reset block number to 0 - - print("URLERROR:" + url + ". Trying again in 10 secs") - print(ex) - time.sleep(10) - block_number = 0 - else: - # We are Ok Espresso block found in page - # If block contains transactions, extract Rollup id and find block with inclusion proofs for the rollup - - received = datetime.now() - block = page.read() - struct = json.loads(block) - - # throw exception if json is different from expected - try: - txns = struct["block"]["transaction_nmt"] - # we only need to show the block once per vm, so if several transactions are seen for same vm in same block, treat them as duplicates - seen_vms = set() - for txn in txns: - vm = txn["vm"] # extract Rollup ID - payload = bytes(txn["payload"]).hex() - # if transaction already seen, skip - if payload in payloads: - continue - payloads.add(payload) - - # if vm already seen in block skip - if vm in seen_vms: - continue - seen_vms.add(vm) - - print( - f"### New transactions for vm {vm} found on Espresso Block {block_number} received at {received} ###" - ) - namespace_block_url = f"{url}{block_number}/namespace/{vm}" - print("GET " + namespace_block_url) - # find block info for Rollup - vm_page = urllib.request.urlopen(namespace_block_url) - vm_block_str = vm_page.read() - vm_block_struct = json.loads(vm_block_str) - - # Omit unnecessary data - del vm_block_struct["proof"]["phantom"] - if vm_block_struct["proof"]["left_boundary_proof"] is None: - vm_block_struct["proof"][ - "left_boundary_proof" - ] = "Null # left boundary proof not needed" - else: - vm_block_struct["proof"][ - "left_boundary_proof" - ] = "[...]" # Merkle proof for inclusion of left boundary vm transaction - if vm_block_struct["proof"]["right_boundary_proof"] == None: - vm_block_struct["proof"][ - "right_boundary_proof" - ] = "Null # right boundary proof not needed" - else: - vm_block_struct["proof"][ - "right_boundary_proof" - ] = "[...]" # Merkle proof for inclusion of righ boundary vm transaction - del vm_block_struct["header"]["metadata"]["l1_finalized"] - for proof in vm_block_struct["proof"]["proofs"]: - # proof is too large to see, Eliding details - proof[ - "proof" - ] = "[...] # Merkle proof for inclusion of each vm transaction in the Espresso Block" - del proof["_phantom_arity"] - - # transform byte arrays in hex strings for visualization - root_as_hex = bytes( - vm_block_struct["header"]["transactions_root"]["root"] - ).hex() - vm_block_struct["header"]["transactions_root"]["root"] = root_as_hex - for txn in vm_block_struct["transactions"]: - payload_hex = bytes(txn["payload"]).hex() - txn["payload"] = payload_hex - - # transform unix timespamp to date - timestamp = vm_block_struct["header"]["metadata"]["timestamp"] - date = datetime.fromtimestamp(timestamp) - vm_block_struct["header"]["metadata"]["timestamp"] = str(date) - - # print trimmed block - print(json.dumps(vm_block_struct, indent=2)) - print() - - except ValueError: - print("Error: invalid json structure") - exit(1) - block_number += 1 diff --git a/sequencer/api/availability.toml b/sequencer/api/availability.toml index 69d509eed..26ac2b4b6 100644 --- a/sequencer/api/availability.toml +++ b/sequencer/api/availability.toml @@ -2,7 +2,7 @@ PATH = ["block/:height/namespace/:namespace"] ":height" = "Integer" ":namespace" = "Integer" -DOC = "Get the namespace proof for a set of VM transactions and the NMT root" +DOC = "Get the transactions in a namespace of the given block, along with a proof." [route.gettimestampwindow] PATH = [ diff --git a/sequencer/src/api.rs b/sequencer/src/api.rs index abec74c12..61a8fdb4b 100644 --- a/sequencer/src/api.rs +++ b/sequencer/src/api.rs @@ -89,7 +89,7 @@ mod test_helpers { persistence::{no_storage::NoStorage, SequencerPersistence}, state::BlockMerkleTree, testing::{wait_for_decide_on_handle, TestConfig}, - Transaction, VmId, + Transaction, }; use async_compatibility_layer::logging::{setup_backtrace, setup_logging}; use async_std::task::sleep; @@ -215,7 +215,7 @@ mod test_helpers { setup_logging(); setup_backtrace(); - let txn = Transaction::new(VmId(0), vec![1, 2, 3, 4]); + let txn = Transaction::new(Default::default(), vec![1, 2, 3, 4]); let port = pick_unused_port().expect("No ports free"); @@ -410,7 +410,7 @@ mod api_tests { use super::*; use crate::{ testing::{wait_for_decide_on_handle, TestConfig}, - Header, Transaction, VmId, + Header, Transaction, }; use async_compatibility_layer::logging::{setup_backtrace, setup_logging}; use async_std::task::sleep; @@ -456,7 +456,7 @@ mod api_tests { setup_backtrace(); let vid = vid_scheme(5); - let txn = Transaction::new(VmId(0), vec![1, 2, 3, 4]); + let txn = Transaction::new(Default::default(), vec![1, 2, 3, 4]); // Start query service. let port = pick_unused_port().expect("No ports free"); @@ -498,6 +498,11 @@ mod api_tests { let mut found_txn = false; let mut found_empty_block = false; for block_num in 0..=block_height { + let header: Header = client + .get(&format!("availability/header/{block_num}")) + .send() + .await + .unwrap(); let ns_query_res: NamespaceProofQueryData = client .get(&format!("availability/block/{block_num}/namespace/0")) .send() @@ -505,11 +510,7 @@ mod api_tests { .unwrap(); ns_query_res .proof - .verify( - &vid, - &ns_query_res.header.payload_commitment, - &ns_query_res.header.ns_table, - ) + .verify(&vid, &header.payload_commitment, &header.ns_table) .unwrap(); found_empty_block = found_empty_block || ns_query_res.transactions.is_empty(); diff --git a/sequencer/src/api/endpoints.rs b/sequencer/src/api/endpoints.rs index 3620448b4..032a576c1 100644 --- a/sequencer/src/api/endpoints.rs +++ b/sequencer/src/api/endpoints.rs @@ -10,7 +10,7 @@ use crate::{ block::payload::{parse_ns_payload, NamespaceProof}, network, state::{BlockMerkleTree, FeeAccountProof, ValidatedState}, - Header, SeqTypes, Transaction, VmId, + Header, NamespaceId, SeqTypes, Transaction, }; use async_std::sync::{Arc, RwLock}; use commit::Committable; @@ -32,7 +32,6 @@ use tide_disco::{ #[derive(Clone, Debug, Serialize, Deserialize)] pub struct NamespaceProofQueryData { pub proof: NamespaceProof, - pub header: Header, pub transactions: Vec, } @@ -80,7 +79,8 @@ where api.get("getnamespaceproof", move |req, state| { async move { let height: usize = req.integer_param("height")?; - let ns_id = VmId(req.integer_param("namespace")?); + let ns_id: u64 = req.integer_param("namespace")?; + let ns_id = NamespaceId::from(ns_id); let (block, common) = try_join!( async move { state @@ -129,7 +129,6 @@ where Ok(NamespaceProofQueryData { transactions, proof, - header: block.header().clone(), }) } .boxed() diff --git a/sequencer/src/bin/submit-transactions.rs b/sequencer/src/bin/submit-transactions.rs index 1f5d8fdb4..aa7045eec 100644 --- a/sequencer/src/bin/submit-transactions.rs +++ b/sequencer/src/bin/submit-transactions.rs @@ -237,7 +237,7 @@ async fn submit_transactions( let hash = tx.commit(); tracing::info!( "submitting transaction {hash} for namespace {} of size {}", - tx.vm(), + tx.namespace(), tx.payload().len() ); if let Err(err) = client @@ -271,13 +271,13 @@ async fn server(port: u16) { } fn random_transaction(opt: &Options, rng: &mut ChaChaRng) -> Transaction { - let vm = rng.gen_range(opt.min_namespace..=opt.max_namespace); + let namespace = rng.gen_range(opt.min_namespace..=opt.max_namespace); let len = rng.gen_range(opt.min_size..=opt.max_size); let mut payload = vec![0; len]; rng.fill_bytes(&mut payload); - Transaction::new(vm.into(), payload) + Transaction::new(namespace.into(), payload) } fn random_seed() -> u64 { diff --git a/sequencer/src/block/entry.rs b/sequencer/src/block/entry.rs index 6ff2e405c..afd8f79c0 100644 --- a/sequencer/src/block/entry.rs +++ b/sequencer/src/block/entry.rs @@ -1,5 +1,5 @@ use super::{Deserialize, Serialize}; -use crate::VmId; +use crate::NamespaceId; use core::fmt; use std::mem::size_of; @@ -69,17 +69,17 @@ impl TryFrom for usize { } } -impl TryFrom for TxTableEntry { +impl TryFrom for TxTableEntry { type Error = >::Error; - fn try_from(value: VmId) -> Result { - TxTableEntryWord::try_from(value.0).map(Self) + fn try_from(value: NamespaceId) -> Result { + TxTableEntryWord::try_from(u64::from(value)).map(Self) } } -impl TryFrom for VmId { +impl TryFrom for NamespaceId { type Error = >::Error; fn try_from(value: TxTableEntry) -> Result { - Ok(Self(From::from(value.0))) + Ok((value.0 as u64).into()) } } diff --git a/sequencer/src/block/payload.rs b/sequencer/src/block/payload.rs index 3e8358263..da0528ea2 100644 --- a/sequencer/src/block/payload.rs +++ b/sequencer/src/block/payload.rs @@ -1,6 +1,6 @@ use crate::block::entry::{TxTableEntry, TxTableEntryWord}; use crate::block::payload; -use crate::{BlockBuildingSnafu, Error, Transaction, VmId}; +use crate::{BlockBuildingSnafu, Error, NamespaceId, Transaction}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use commit::Committable; use derivative::Derivative; @@ -106,7 +106,7 @@ impl Payload { pub fn namespace_with_proof( &self, ns_table: &NameSpaceTable, - ns_id: VmId, + ns_id: NamespaceId, vid_common: VidCommon, ) -> Option { if self.raw_payload.len() != VidSchemeType::get_payload_byte_len(&vid_common) { @@ -167,7 +167,7 @@ impl Payload { pub fn from_txs( txs: impl IntoIterator as BlockPayload>::Transaction>, ) -> Result { - let mut namespaces: HashMap = Default::default(); + let mut namespaces: HashMap = Default::default(); let mut structured_payload = Self { raw_payload: vec![], ns_table: NameSpaceTable { @@ -185,12 +185,12 @@ impl Payload { } fn update_namespace_with_tx( - namespaces: &mut HashMap, + namespaces: &mut HashMap, tx: as BlockPayload>::Transaction, ) { let tx_bytes_len: TxTableEntry = tx.payload().len().try_into().unwrap(); // TODO (Philippe) error handling - let namespace = namespaces.entry(tx.vm()).or_insert(NamespaceInfo { + let namespace = namespaces.entry(tx.namespace()).or_insert(NamespaceInfo { tx_table: Vec::new(), tx_bodies: Vec::new(), tx_bytes_end: TxTableEntry::zero(), @@ -212,7 +212,7 @@ impl Payload { fn generate_raw_payload( &mut self, - namespaces: HashMap, + namespaces: HashMap, ) -> Result<(), Error> { // fill payload and namespace table let mut payload = Vec::new(); @@ -263,12 +263,12 @@ impl Committable for Payload { pub enum NamespaceProof { Existence { ns_payload_flat: Vec, - ns_id: VmId, + ns_id: NamespaceId, ns_proof: LargeRangeProofType, vid_common: VidCommon, }, NonExistence { - ns_id: VmId, + ns_id: NamespaceId, }, } @@ -282,7 +282,7 @@ impl NamespaceProof { vid: &VidSchemeType, commit: &VidCommitment, ns_table: &NameSpaceTable, - ) -> Option<(Vec, VmId)> { + ) -> Option<(Vec, NamespaceId)> { match self { NamespaceProof::Existence { ns_payload_flat, @@ -326,7 +326,7 @@ impl NamespaceProof { } // TODO find a home for this function -pub fn parse_ns_payload(ns_payload_flat: &[u8], ns_id: VmId) -> Vec { +pub fn parse_ns_payload(ns_payload_flat: &[u8], ns_id: NamespaceId) -> Vec { let num_txs = TxTable::get_tx_table_len(ns_payload_flat); let tx_bodies_offset = num_txs .saturating_add(1) @@ -489,9 +489,8 @@ mod test { ns_payload }; - let ns_id = crate::VmId(n.try_into().unwrap()); let already_exists = derived_nss.insert( - ns_id, + (n as u64).into(), NamespaceInfo { payload_flat: ns_payload_flat, tx_table: tx_table_derived, @@ -541,7 +540,7 @@ mod test { for (ns_idx, (ns_id, entry)) in ns_table_iter::(actual_ns_table.get_bytes()).enumerate() { - // warning! ns_id may not equal VmId(ns_idx) due to HashMap nondeterminism + // warning! ns_id may not equal NamespaceId(ns_idx) due to HashMap nondeterminism let derived_ns = derived_nss.remove(&ns_id).unwrap(); @@ -560,8 +559,7 @@ mod test { .unwrap(); assert_eq!( actual_ns_payload_flat, derived_ns.payload_flat, - "namespace {} incorrect payload bytes", - ns_id.0, + "namespace {ns_id} incorrect payload bytes", ); // test ns proof @@ -576,8 +574,7 @@ mod test { { assert_eq!( ns_payload_flat, &derived_ns.payload_flat, - "namespace {} incorrect payload bytes returned from namespace_with_proof", - ns_id.0, + "namespace {ns_id} incorrect payload bytes returned from namespace_with_proof", ); } else { // TODO test for non-existence @@ -586,7 +583,7 @@ mod test { let (ns_proof_txs, ns_proof_ns_id) = ns_proof .verify(&vid, &disperse_data.commit, &actual_ns_table) - .unwrap_or_else(|| panic!("namespace {} proof verification failure", ns_id.0)); + .unwrap_or_else(|| panic!("namespace {ns_id} proof verification failure")); assert_eq!(ns_proof_ns_id, ns_id); assert_eq!( ns_proof_txs, @@ -606,8 +603,7 @@ mod test { assert_eq!( actual_tx_table_len, derived_ns.tx_table.len(), - "namespace {} tx table length expect {} got {}", - ns_id.0, + "namespace {ns_id} tx table length expect {} got {}", derived_ns.tx_table.len(), actual_tx_table_len ); @@ -622,8 +618,7 @@ mod test { .collect(); assert_eq!( actual_tx_table, derived_ns.tx_table, - "namespace {} incorrect tx table for", - ns_id.0 + "namespace {ns_id} incorrect tx table for", ); // testing tx iterator @@ -636,7 +631,7 @@ mod test { 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!(ns_id, tx.namespace()); assert_eq!(tx_payload, tx.payload()); // TODO(1010) transaction_with_proof for multiple namespaces @@ -792,7 +787,7 @@ mod test { let disperse_data = vid.disperse(&block.raw_payload).unwrap(); // make a fake proof for a nonexistent tx in the small block - let tx = Transaction::new(crate::VmId(0), Vec::new()); + 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(), @@ -952,7 +947,7 @@ mod test { use crate::block::entry::TxTableEntry; use crate::block::payload::TableWordTraits; use crate::block::tables::{test::TxTableTest, NameSpaceTable, Table}; - use crate::VmId; + use crate::NamespaceId; use rand::RngCore; pub fn tx_table_byte_len(entries: &[usize]) -> usize { @@ -1010,12 +1005,12 @@ mod test { pub fn ns_table_iter( ns_table_bytes: &[u8], - ) -> impl Iterator + '_ { + ) -> impl Iterator + '_ { ns_table_bytes[NameSpaceTable::::byte_len()..] // first few bytes is the table lengh, skip that .chunks(2 * TxTableEntry::byte_len()) .map(|bytes| { // read (namespace id, entry) from the namespace table - let ns_id = VmId::try_from( + let ns_id = NamespaceId::try_from( TxTableEntry::from_bytes(&bytes[..TxTableEntry::byte_len()]).unwrap(), ) .unwrap(); diff --git a/sequencer/src/block/queryable.rs b/sequencer/src/block/queryable.rs index 8e830591d..ee5650c69 100644 --- a/sequencer/src/block/queryable.rs +++ b/sequencer/src/block/queryable.rs @@ -195,7 +195,7 @@ impl QueryablePayload for Payload { // 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), + Default::default(), self.raw_payload.get(tx_payload_range.clone())?.to_vec(), ), TxInclusionProof { diff --git a/sequencer/src/block/tables.rs b/sequencer/src/block/tables.rs index abd8072aa..525290433 100644 --- a/sequencer/src/block/tables.rs +++ b/sequencer/src/block/tables.rs @@ -1,6 +1,6 @@ use crate::block::entry::TxTableEntry; use crate::block::payload::TableWordTraits; -use crate::{BlockBuildingSnafu, Error, VmId}; +use crate::{BlockBuildingSnafu, Error, NamespaceId}; use derivative::Derivative; use serde::{Deserialize, Serialize}; use snafu::OptionExt; @@ -57,7 +57,9 @@ impl NameSpaceTable { } } - pub fn from_namespace_offsets(namespace_offsets: Vec<(VmId, usize)>) -> Result { + pub fn from_namespace_offsets( + namespace_offsets: Vec<(NamespaceId, usize)>, + ) -> Result { let mut ns_table = NameSpaceTable::from_vec(Vec::from( TxTableEntry::try_from(namespace_offsets.len()) .ok() @@ -65,7 +67,7 @@ impl NameSpaceTable { .to_bytes(), )); for (id, offset) in namespace_offsets { - ns_table.add_new_entry_vmid(id)?; + ns_table.add_new_entry_ns_id(id)?; ns_table.add_new_entry_payload_len(offset)?; } Ok(ns_table) @@ -86,14 +88,14 @@ impl NameSpaceTable { /// Find `ns_id` and return its index into this namespace table. /// /// TODO return Result or Option? Want to avoid catch-all Error type :( - pub fn lookup(&self, ns_id: VmId) -> Option { + pub fn lookup(&self, ns_id: NamespaceId) -> Option { // TODO don't use TxTable, need a new method let ns_table_len = TxTable::get_tx_table_len(&self.bytes); (0..ns_table_len).find(|&ns_index| ns_id == self.get_table_entry(ns_index).0) } - fn add_new_entry_vmid(&mut self, id: VmId) -> Result<(), Error> { + fn add_new_entry_ns_id(&mut self, id: NamespaceId) -> Result<(), Error> { self.bytes.extend( TxTableEntry::try_from(id) .ok() @@ -127,7 +129,7 @@ impl NameSpaceTable { // returns (ns_id, ns_offset) // ns_offset is not checked, could be anything - pub fn get_table_entry(&self, ns_index: usize) -> (VmId, usize) { + pub fn get_table_entry(&self, ns_index: usize) -> (NamespaceId, usize) { // get the range for ns_id bytes in ns table // ensure `range` is within range for ns_table_bytes let start = std::cmp::min( @@ -144,12 +146,13 @@ impl NameSpaceTable { let ns_id_range = start..end; // parse ns_id bytes from ns table - // any failure -> VmId(0) + // any failure -> NamespaceId::default() let mut ns_id_bytes = [0u8; TxTableEntry::byte_len()]; ns_id_bytes[..ns_id_range.len()].copy_from_slice(&self.bytes[ns_id_range]); - let ns_id = - VmId::try_from(TxTableEntry::from_bytes(&ns_id_bytes).unwrap_or(TxTableEntry::zero())) - .unwrap_or(VmId(0)); + let ns_id = NamespaceId::try_from( + TxTableEntry::from_bytes(&ns_id_bytes).unwrap_or(TxTableEntry::zero()), + ) + .unwrap_or_default(); // get the range for ns_offset bytes in ns table // ensure `range` is within range for ns_table_bytes diff --git a/sequencer/src/lib.rs b/sequencer/src/lib.rs index 503606a12..4a34e706a 100644 --- a/sequencer/src/lib.rs +++ b/sequencer/src/lib.rs @@ -26,7 +26,6 @@ mod l1_client; pub mod persistence; mod state; pub mod transaction; -mod vm; use ark_ec::models::CurveConfig; use ark_ed_on_bn254::EdwardsConfig; @@ -74,8 +73,7 @@ pub use header::Header; pub use l1_client::L1BlockInfo; pub use options::Options; pub use state::ValidatedState; -pub use transaction::Transaction; -pub use vm::{Vm, VmId, VmTransaction}; +pub use transaction::{NamespaceId, Transaction}; pub mod network { use hotshot_types::message::Message; @@ -554,7 +552,7 @@ pub mod testing { #[cfg(test)] mod test { - use super::{transaction::ApplicationTransaction, vm::TestVm, *}; + use super::*; use async_compatibility_layer::logging::{setup_backtrace, setup_logging}; use futures::StreamExt; @@ -580,15 +578,14 @@ mod test { } // Submit target transaction to handle - let txn = ApplicationTransaction::new(vec![1, 2, 3]); - let submitted_txn = Transaction::new(TestVm {}.id(), bincode::serialize(&txn).unwrap()); + let txn = Transaction::new(Default::default(), vec![1, 2, 3]); handles[0] - .submit_transaction(submitted_txn.clone()) + .submit_transaction(txn.clone()) .await .expect("Failed to submit transaction"); tracing::info!("Submitted transaction to handle: {txn:?}"); - wait_for_decide_on_handle(&mut events, &submitted_txn).await; + wait_for_decide_on_handle(&mut events, &txn).await; } #[async_std::test] diff --git a/sequencer/src/transaction.rs b/sequencer/src/transaction.rs index 8f00b9812..ab822852b 100644 --- a/sequencer/src/transaction.rs +++ b/sequencer/src/transaction.rs @@ -1,10 +1,40 @@ use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use commit::{Commitment, Committable}; +use derive_more::{Display, From, Into}; use hotshot_types::traits::block_contents::Transaction as HotShotTransaction; -use jf_primitives::merkle_tree::namespaced_merkle_tree::Namespaced; +use jf_primitives::merkle_tree::namespaced_merkle_tree::{Namespace, Namespaced}; use serde::{Deserialize, Serialize}; -use crate::vm::{Vm, VmId, VmTransaction}; +#[derive( + Clone, + Copy, + Serialize, + Deserialize, + Debug, + Display, + PartialEq, + Eq, + Hash, + Into, + From, + Default, + CanonicalDeserialize, + CanonicalSerialize, + PartialOrd, + Ord, +)] +#[display(fmt = "{_0}")] +pub struct NamespaceId(u64); + +impl Namespace for NamespaceId { + fn max() -> Self { + Self(u64::max_value()) + } + + fn min() -> Self { + Self(u64::min_value()) + } +} #[derive( Clone, @@ -18,76 +48,48 @@ use crate::vm::{Vm, VmId, VmTransaction}; CanonicalDeserialize, )] pub struct Transaction { - vm: VmId, + namespace: NamespaceId, payload: Vec, } impl Transaction { - pub fn new(vm: VmId, payload: Vec) -> Self { - Self { vm, payload } + pub fn new(namespace: NamespaceId, payload: Vec) -> Self { + Self { namespace, payload } } - pub fn vm(&self) -> VmId { - self.vm + pub fn namespace(&self) -> NamespaceId { + self.namespace } pub fn payload(&self) -> &[u8] { &self.payload } - pub fn as_vm(&self, vm: &V) -> Option { - if self.vm() == vm.id() { - V::Transaction::decode(self.payload()) - } else { - None - } - } - #[cfg(any(test, feature = "testing"))] pub fn random(rng: &mut dyn rand::RngCore) -> Self { use rand::Rng; let len = rng.gen_range(0..100); Self::new( - VmId(rng.gen_range(0..10)), + NamespaceId(rng.gen_range(0..10)), (0..len).map(|_| rand::random::()).collect(), ) } } -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)] -pub(crate) struct ApplicationTransaction(Vec); - -impl ApplicationTransaction { - #[allow(unused)] - pub(crate) fn new(payload: Vec) -> Self { - Self(payload) - } -} - -impl VmTransaction for ApplicationTransaction { - fn encode(&self) -> Vec { - bincode::serialize(self).unwrap() - } - - fn decode(bytes: &[u8]) -> Option { - bincode::deserialize(bytes).ok() - } -} - impl HotShotTransaction for Transaction {} impl Namespaced for Transaction { - type Namespace = VmId; + type Namespace = NamespaceId; fn get_namespace(&self) -> Self::Namespace { - self.vm + self.namespace } } impl Committable for Transaction { fn commit(&self) -> Commitment { commit::RawCommitmentBuilder::new("Transaction") - .u64_field("vm", self.vm.0) - .var_size_bytes(&self.payload) // TODO how can we specify a field name like "payload" + .u64_field("namespace", self.namespace.into()) + .var_size_bytes(&self.payload) .finalize() } } diff --git a/sequencer/src/vm.rs b/sequencer/src/vm.rs deleted file mode 100644 index 070ea6708..000000000 --- a/sequencer/src/vm.rs +++ /dev/null @@ -1,61 +0,0 @@ -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use derive_more::{Display, From, Into}; -use jf_primitives::merkle_tree::namespaced_merkle_tree::Namespace; -use serde::{Deserialize, Serialize}; - -use crate::transaction::{ApplicationTransaction, Transaction}; - -#[derive( - Clone, - Copy, - Serialize, - Deserialize, - Debug, - Display, - PartialEq, - Eq, - Hash, - Into, - From, - Default, - CanonicalDeserialize, - CanonicalSerialize, - PartialOrd, - Ord, -)] -#[display(fmt = "{_0}")] -pub struct VmId(pub(crate) u64); - -pub trait Vm { - type Transaction: VmTransaction; - fn id(&self) -> VmId; - - fn wrap(&self, txn: &Self::Transaction) -> Transaction { - Transaction::new(self.id(), txn.encode()) - } -} - -impl Namespace for VmId { - fn max() -> Self { - VmId(u64::max_value()) - } - - fn min() -> Self { - VmId(u64::min_value()) - } -} - -pub trait VmTransaction: Sized + Send + Sync { - fn encode(&self) -> Vec; - fn decode(bytes: &[u8]) -> Option; -} - -#[derive(Clone, Copy, Debug, Default)] -pub(crate) struct TestVm; - -impl Vm for TestVm { - type Transaction = ApplicationTransaction; - fn id(&self) -> VmId { - VmId(0) - } -}