From 3d35cf4b8e32a67b007309b9b8ece95d9a355f9a Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Thu, 29 Aug 2024 16:14:52 +0500 Subject: [PATCH 01/37] refactor: extract block kernel to a separate masm file (#474) --- .../prover/asm/block_kernel.masm | 160 +++++++++++++++++ .../src/block_builder/prover/mod.rs | 162 +----------------- 2 files changed, 161 insertions(+), 161 deletions(-) create mode 100644 crates/block-producer/src/block_builder/prover/asm/block_kernel.masm diff --git a/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm b/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm new file mode 100644 index 000000000..ccf704641 --- /dev/null +++ b/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm @@ -0,0 +1,160 @@ +#! Note: For now, the "block kernel" only computes the account root. Eventually, it will compute +#! the entire block header. +#! +#! Stack inputs: [num_accounts_updated, OLD_ACCOUNT_ROOT, NEW_ACCOUNT_HASH_0, account_id_0, ... , +#! NEW_ACCOUNT_HASH_n, account_id_n] + +use.std::collections::smt +use.std::collections::mmr + +const.ACCOUNT_TREE_DEPTH=64 +const.CHAIN_MMR_PTR=1000 + +#! Compute the account root +#! +#! Stack: [num_accounts_updated, OLD_ACCOUNT_ROOT, +#! NEW_ACCOUNT_HASH_0, account_id_0, ... , NEW_ACCOUNT_HASH_n, account_id_n] +#! Output: [NEW_ACCOUNT_ROOT] +proc.compute_account_root + dup neq.0 + # => [0 or 1, num_accounts_updated, OLD_ACCOUNT_ROOT, + # NEW_ACCOUNT_HASH_0, account_id_0, ... , NEW_ACCOUNT_HASH_n, account_id_n] + + while.true + # stack: [counter, ROOT_0, ..., NEW_ACCOUNT_HASH_i, account_id_i , ...] + + # Move counter down for next iteration + movdn.9 + # => [ROOT_i, NEW_ACCOUNT_HASH_i, account_id_i, counter, ...] + + # Prepare stack for `mtree_set` + movup.8 push.ACCOUNT_TREE_DEPTH + # => [account_tree_depth, account_id_i, ROOT_i, NEW_ACCOUNT_HASH_i, counter, ...] + + # set new value in SMT + mtree_set dropw + # => [ROOT_{i+1}, counter, ...] + + # loop counter + movup.4 sub.1 dup neq.0 + # => [0 or 1, counter-1, ROOT_{i+1}, ...] + end + + drop + # => [ROOT_{n-1}] +end + +#! Compute the note root. +#! +#! Each batch contains a tree of depth 13 for its created notes. The block's created notes tree is created +#! by aggregating up to 2^8 tree roots coming from the batches contained in the block. +#! +#! `SMT_EMPTY_ROOT` must be `E21`, the root of the empty tree of depth 21. If less than 2^8 batches are +#! contained in the block, `E13` is used as the padding value; this is derived from the fact that +#! `SMT_EMPTY_ROOT` is `E21`, and that our tree has depth 8. +#! +#! Stack: [num_notes_updated, SMT_EMPTY_ROOT, +#! batch_note_root_idx_0, BATCH_NOTE_TREE_ROOT_0, +#! ... , +#! batch_note_root_idx_{n-1}, BATCH_NOTE_TREE_ROOT_{n-1}] +#! Output: [NOTES_ROOT] +proc.compute_note_root + # assess if we should loop + dup neq.0 + #=> [0 or 1, num_notes_updated, SMT_EMPTY_ROOT, ... ] + + while.true + #=> [note_roots_left_to_update, ROOT_i, batch_note_root_idx_i, BATCH_NOTE_TREE_ROOT_i, ... ] + + # Prepare stack for mtree_set + movdn.9 movup.4 push.8 + #=> [depth=8, batch_note_root_idx_i, ROOT_i, BATCH_NOTE_TREE_ROOT_i, note_roots_left_to_update, ... ] + + mtree_set dropw + #=> [ROOT_{i+1}, note_roots_left_to_update, ... ] + + # loop counter + movup.4 sub.1 dup neq.0 + #=> [0 or 1, note_roots_left_to_update - 1, ROOT_{i+1}, ... ] + end + + drop + # => [ROOT_{n-1}] +end + +#! Stack: [num_produced_nullifiers, OLD_NULLIFIER_ROOT, NULLIFIER_VALUE, +#! NULLIFIER_0, ..., NULLIFIER_n] +#! Output: [NULLIFIER_ROOT] +proc.compute_nullifier_root + # assess if we should loop + dup neq.0 + #=> [0 or 1, num_produced_nullifiers, OLD_NULLIFIER_ROOT, NULLIFIER_VALUE, NULLIFIER_0, ..., NULLIFIER_n ] + + while.true + #=> [num_nullifiers_left_to_update, ROOT_i, NULLIFIER_VALUE, NULLIFIER_i, ... ] + + # Prepare stack for `smt::set` + movdn.12 movupw.2 dupw.2 + #=> [NULLIFIER_VALUE, NULLIFIER_i, ROOT_i, NULLIFIER_VALUE, num_nullifiers_left_to_update, ... ] + + exec.smt::set + #=> [OLD_VALUE, ROOT_{i+1}, NULLIFIER_VALUE, num_nullifiers_left_to_update, ... ] + + # Check that OLD_VALUE == 0 (i.e. that nullifier was indeed not previously produced) + assertz assertz assertz assertz + #=> [ROOT_{i+1}, NULLIFIER_VALUE, num_nullifiers_left_to_update, ... ] + + # loop counter + movup.8 sub.1 dup neq.0 + #=> [0 or 1, num_nullifiers_left_to_update - 1, ROOT_{i+1}, NULLIFIER_VALUE, ... ] + end + #=> [0, ROOT_{n-1}, NULLIFIER_VALUE ] + + drop swapw dropw + # => [ROOT_{n-1}] +end + +#! Compute the chain MMR root +#! +#! Stack: [ PREV_CHAIN_MMR_HASH, PREV_BLOCK_HASH_TO_INSERT ] +#! Advice map: PREV_CHAIN_MMR_HASH -> NUM_LEAVES || peak_0 || .. || peak_{n-1} || +#! +#! Output: [ CHAIN_MMR_ROOT ] +proc.compute_chain_mmr_root + push.CHAIN_MMR_PTR movdn.4 + # => [ PREV_CHAIN_MMR_HASH, chain_mmr_ptr, PREV_BLOCK_HASH_TO_INSERT ] + + # load the chain MMR (as of previous block) at memory location CHAIN_MMR_PTR + exec.mmr::unpack + # => [ PREV_BLOCK_HASH_TO_INSERT ] + + push.CHAIN_MMR_PTR movdn.4 + # => [ PREV_BLOCK_HASH_TO_INSERT, chain_mmr_ptr ] + + # add PREV_BLOCK_HASH_TO_INSERT to chain MMR + exec.mmr::add + # => [ ] + + # Compute new MMR root + push.CHAIN_MMR_PTR exec.mmr::pack + # => [ CHAIN_MMR_ROOT ] +end + +# Stack: [, , , ] +begin + exec.compute_account_root mem_storew.0 dropw + # => [, , ] + + exec.compute_note_root mem_storew.1 dropw + # => [ , ] + + exec.compute_nullifier_root mem_storew.2 dropw + # => [ ] + + exec.compute_chain_mmr_root + # => [ CHAIN_MMR_ROOT ] + + # Load output on stack + padw mem_loadw.2 padw mem_loadw.1 padw mem_loadw.0 + #=> [ ACCOUNT_ROOT, NOTE_ROOT, NULLIFIER_ROOT, CHAIN_MMR_ROOT ] +end \ No newline at end of file diff --git a/crates/block-producer/src/block_builder/prover/mod.rs b/crates/block-producer/src/block_builder/prover/mod.rs index 24851c031..8eea73a18 100644 --- a/crates/block-producer/src/block_builder/prover/mod.rs +++ b/crates/block-producer/src/block_builder/prover/mod.rs @@ -24,167 +24,7 @@ pub mod block_witness; #[cfg(test)] mod tests; -/// Note: For now, the "block kernel" only computes the account root. Eventually, it will compute -/// the entire block header. -/// -/// Stack inputs: [num_accounts_updated, OLD_ACCOUNT_ROOT, NEW_ACCOUNT_HASH_0, account_id_0, ... , -/// NEW_ACCOUNT_HASH_n, account_id_n] -const BLOCK_KERNEL_MASM: &str = " -use.std::collections::smt -use.std::collections::mmr - -const.ACCOUNT_TREE_DEPTH=64 -const.CHAIN_MMR_PTR=1000 - -#! Compute the account root -#! -#! Stack: [num_accounts_updated, OLD_ACCOUNT_ROOT, -#! NEW_ACCOUNT_HASH_0, account_id_0, ... , NEW_ACCOUNT_HASH_n, account_id_n] -#! Output: [NEW_ACCOUNT_ROOT] -proc.compute_account_root - dup neq.0 - # => [0 or 1, num_accounts_updated, OLD_ACCOUNT_ROOT, - # NEW_ACCOUNT_HASH_0, account_id_0, ... , NEW_ACCOUNT_HASH_n, account_id_n] - - while.true - # stack: [counter, ROOT_0, ..., NEW_ACCOUNT_HASH_i, account_id_i , ...] - - # Move counter down for next iteration - movdn.9 - # => [ROOT_i, NEW_ACCOUNT_HASH_i, account_id_i, counter, ...] - - # Prepare stack for `mtree_set` - movup.8 push.ACCOUNT_TREE_DEPTH - # => [account_tree_depth, account_id_i, ROOT_i, NEW_ACCOUNT_HASH_i, counter, ...] - - # set new value in SMT - mtree_set dropw - # => [ROOT_{i+1}, counter, ...] - - # loop counter - movup.4 sub.1 dup neq.0 - # => [0 or 1, counter-1, ROOT_{i+1}, ...] - end - - drop - # => [ROOT_{n-1}] -end - -#! Compute the note root. -#! -#! Each batch contains a tree of depth 13 for its created notes. The block's created notes tree is created -#! by aggregating up to 2^8 tree roots coming from the batches contained in the block. -#! -#! `SMT_EMPTY_ROOT` must be `E21`, the root of the empty tree of depth 21. If less than 2^8 batches are -#! contained in the block, `E13` is used as the padding value; this is derived from the fact that -#! `SMT_EMPTY_ROOT` is `E21`, and that our tree has depth 8. -#! -#! Stack: [num_notes_updated, SMT_EMPTY_ROOT, -#! batch_note_root_idx_0, BATCH_NOTE_TREE_ROOT_0, -#! ... , -#! batch_note_root_idx_{n-1}, BATCH_NOTE_TREE_ROOT_{n-1}] -#! Output: [NOTES_ROOT] -proc.compute_note_root - # assess if we should loop - dup neq.0 - #=> [0 or 1, num_notes_updated, SMT_EMPTY_ROOT, ... ] - - while.true - #=> [note_roots_left_to_update, ROOT_i, batch_note_root_idx_i, BATCH_NOTE_TREE_ROOT_i, ... ] - - # Prepare stack for mtree_set - movdn.9 movup.4 push.8 - #=> [depth=8, batch_note_root_idx_i, ROOT_i, BATCH_NOTE_TREE_ROOT_i, note_roots_left_to_update, ... ] - - mtree_set dropw - #=> [ROOT_{i+1}, note_roots_left_to_update, ... ] - - # loop counter - movup.4 sub.1 dup neq.0 - #=> [0 or 1, note_roots_left_to_update - 1, ROOT_{i+1}, ... ] - end - - drop - # => [ROOT_{n-1}] -end - -#! Stack: [num_produced_nullifiers, OLD_NULLIFIER_ROOT, NULLIFIER_VALUE, -#! NULLIFIER_0, ..., NULLIFIER_n] -#! Output: [NULLIFIER_ROOT] -proc.compute_nullifier_root - # assess if we should loop - dup neq.0 - #=> [0 or 1, num_produced_nullifiers, OLD_NULLIFIER_ROOT, NULLIFIER_VALUE, NULLIFIER_0, ..., NULLIFIER_n ] - - while.true - #=> [num_nullifiers_left_to_update, ROOT_i, NULLIFIER_VALUE, NULLIFIER_i, ... ] - - # Prepare stack for `smt::set` - movdn.12 movupw.2 dupw.2 - #=> [NULLIFIER_VALUE, NULLIFIER_i, ROOT_i, NULLIFIER_VALUE, num_nullifiers_left_to_update, ... ] - - exec.smt::set - #=> [OLD_VALUE, ROOT_{i+1}, NULLIFIER_VALUE, num_nullifiers_left_to_update, ... ] - - # Check that OLD_VALUE == 0 (i.e. that nullifier was indeed not previously produced) - assertz assertz assertz assertz - #=> [ROOT_{i+1}, NULLIFIER_VALUE, num_nullifiers_left_to_update, ... ] - - # loop counter - movup.8 sub.1 dup neq.0 - #=> [0 or 1, num_nullifiers_left_to_update - 1, ROOT_{i+1}, NULLIFIER_VALUE, ... ] - end - #=> [0, ROOT_{n-1}, NULLIFIER_VALUE ] - - drop swapw dropw - # => [ROOT_{n-1}] -end - -#! Compute the chain MMR root -#! -#! Stack: [ PREV_CHAIN_MMR_HASH, PREV_BLOCK_HASH_TO_INSERT ] -#! Advice map: PREV_CHAIN_MMR_HASH -> NUM_LEAVES || peak_0 || .. || peak_{n-1} || -#! -#! Output: [ CHAIN_MMR_ROOT ] -proc.compute_chain_mmr_root - push.CHAIN_MMR_PTR movdn.4 - # => [ PREV_CHAIN_MMR_HASH, chain_mmr_ptr, PREV_BLOCK_HASH_TO_INSERT ] - - # load the chain MMR (as of previous block) at memory location CHAIN_MMR_PTR - exec.mmr::unpack - # => [ PREV_BLOCK_HASH_TO_INSERT ] - - push.CHAIN_MMR_PTR movdn.4 - # => [ PREV_BLOCK_HASH_TO_INSERT, chain_mmr_ptr ] - - # add PREV_BLOCK_HASH_TO_INSERT to chain MMR - exec.mmr::add - # => [ ] - - # Compute new MMR root - push.CHAIN_MMR_PTR exec.mmr::pack - # => [ CHAIN_MMR_ROOT ] -end - -# Stack: [, , , ] -begin - exec.compute_account_root mem_storew.0 dropw - # => [, , ] - - exec.compute_note_root mem_storew.1 dropw - # => [ , ] - - exec.compute_nullifier_root mem_storew.2 dropw - # => [ ] - - exec.compute_chain_mmr_root - # => [ CHAIN_MMR_ROOT ] - - # Load output on stack - padw mem_loadw.2 padw mem_loadw.1 padw mem_loadw.0 - #=> [ ACCOUNT_ROOT, NOTE_ROOT, NULLIFIER_ROOT, CHAIN_MMR_ROOT ] -end -"; +const BLOCK_KERNEL_MASM: &str = include_str!("asm/block_kernel.masm"); #[derive(Debug)] pub(crate) struct BlockProver { From dae92dd86308106279c0d7653cff21be093455b0 Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Fri, 30 Aug 2024 15:36:56 +0500 Subject: [PATCH 02/37] Removed note details from sync responses (#462) * refactor: remove note details from sync responses * docs: update `CHANGELOG.md` --- CHANGELOG.md | 1 + crates/store/src/db/mod.rs | 38 +++++++- crates/store/src/db/sql.rs | 165 ++++++--------------------------- crates/store/src/db/tests.rs | 6 +- crates/store/src/server/api.rs | 24 +---- 5 files changed, 71 insertions(+), 163 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a23f1d516..95c411a15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Added `GetNoteAuthenticationInfo` endpoint (#421). - Added `SyncNotes` endpoint (#424). - Added `execution_hint` field to the `Notes` table (#441). +- Optimized state synchronizations by removing unnecessary fetching and parsing of note details (#462). ### Changes diff --git a/crates/store/src/db/mod.rs b/crates/store/src/db/mod.rs index c38ceb8f7..b4fab1be6 100644 --- a/crates/store/src/db/mod.rs +++ b/crates/store/src/db/mod.rs @@ -7,7 +7,7 @@ use std::{ use deadpool_sqlite::{Config as SqliteConfig, Hook, HookError, Pool, Runtime}; use miden_node_proto::{ domain::accounts::{AccountInfo, AccountSummary}, - generated::note::Note as NotePb, + generated::note::{Note as NotePb, NoteSyncRecord as NoteSyncRecordPb}, }; use miden_objects::{ accounts::AccountDelta, @@ -83,7 +83,7 @@ impl From for NotePb { #[derive(Debug, PartialEq)] pub struct StateSyncUpdate { - pub notes: Vec, + pub notes: Vec, pub block_header: BlockHeader, pub chain_tip: BlockNumber, pub account_updates: Vec, @@ -93,11 +93,43 @@ pub struct StateSyncUpdate { #[derive(Debug, PartialEq)] pub struct NoteSyncUpdate { - pub notes: Vec, + pub notes: Vec, pub block_header: BlockHeader, pub chain_tip: BlockNumber, } +#[derive(Debug, Clone, PartialEq)] +pub struct NoteSyncRecord { + pub block_num: BlockNumber, + pub note_index: BlockNoteIndex, + pub note_id: RpoDigest, + pub metadata: NoteMetadata, + pub merkle_path: MerklePath, +} + +impl From for NoteSyncRecordPb { + fn from(note: NoteSyncRecord) -> Self { + Self { + note_index: note.note_index.to_absolute_index(), + note_id: Some(note.note_id.into()), + metadata: Some(note.metadata.into()), + merkle_path: Some(Into::into(¬e.merkle_path)), + } + } +} + +impl From for NoteSyncRecord { + fn from(note: NoteRecord) -> Self { + Self { + block_num: note.block_num, + note_index: note.note_index, + note_id: note.note_id, + metadata: note.metadata, + merkle_path: note.merkle_path, + } + } +} + impl Db { /// Open a connection to the DB, apply any pending migrations, and ensure that the genesis block /// is as expected and present in the database. diff --git a/crates/store/src/db/sql.rs b/crates/store/src/db/sql.rs index ae03cb9f4..8ae55eb83 100644 --- a/crates/store/src/db/sql.rs +++ b/crates/store/src/db/sql.rs @@ -23,7 +23,8 @@ use rusqlite::{ }; use super::{ - NoteRecord, NoteSyncUpdate, NullifierInfo, Result, StateSyncUpdate, TransactionSummary, + NoteRecord, NoteSyncRecord, NoteSyncUpdate, NullifierInfo, Result, StateSyncUpdate, + TransactionSummary, }; use crate::{ errors::{DatabaseError, NoteSyncError, StateSyncError}, @@ -95,8 +96,6 @@ pub fn select_accounts_by_block_range( block_end: BlockNumber, account_ids: &[AccountId], ) -> Result> { - let account_ids: Vec = account_ids.iter().copied().map(u64_to_value).collect(); - let mut stmt = conn.prepare_cached( " SELECT @@ -114,6 +113,7 @@ pub fn select_accounts_by_block_range( ", )?; + let account_ids: Vec = account_ids.iter().copied().map(u64_to_value).collect(); let mut rows = stmt.query(params![block_start, block_end, Rc::new(account_ids)])?; let mut result = Vec::new(); @@ -531,7 +531,7 @@ pub fn insert_notes(transaction: &Transaction, notes: &[NoteRecord]) -> Result Result> { - let tags: Vec = tags.iter().copied().map(u32_to_value).collect(); - let account_ids: Vec = account_ids.iter().copied().map(u64_to_value).collect(); - +) -> Result> { let mut stmt = conn.prepare_cached( " SELECT @@ -564,12 +561,11 @@ pub fn select_notes_since_block_by_tag_and_sender( tag, aux, execution_hint, - merkle_path, - details + merkle_path FROM notes WHERE - -- find the next block which contains at least one note with a matching tag + -- find the next block which contains at least one note with a matching tag or sender block_num = ( SELECT block_num @@ -584,104 +580,14 @@ pub fn select_notes_since_block_by_tag_and_sender( 1 ) AND -- filter the block's notes and return only the ones matching the requested tags + -- or senders (tag IN rarray(?1) OR sender IN rarray(?2)); ", )?; - let mut rows = stmt.query(params![Rc::new(tags), Rc::new(account_ids), block_num])?; - - let mut res = Vec::new(); - while let Some(row) = rows.next()? { - let block_num = row.get(0)?; - let note_index = BlockNoteIndex::new(row.get(1)?, row.get(2)?); - let note_id_data = row.get_ref(3)?.as_blob()?; - let note_id = RpoDigest::read_from_bytes(note_id_data)?; - let note_type = row.get::<_, u8>(4)?; - let sender = column_value_as_u64(row, 5)?; - let tag: u32 = row.get(6)?; - let aux: u64 = row.get(7)?; - let aux = aux.try_into().map_err(DatabaseError::InvalidFelt)?; - let execution_hint = column_value_as_u64(row, 8)?; - let merkle_path_data = row.get_ref(9)?.as_blob()?; - let merkle_path = MerklePath::read_from_bytes(merkle_path_data)?; - let details_data = row.get_ref(10)?.as_blob_or_null()?; - let details = details_data.map(>::read_from_bytes).transpose()?; - let metadata = NoteMetadata::new( - sender.try_into()?, - NoteType::try_from(note_type)?, - tag.into(), - execution_hint.try_into()?, - aux, - )?; - - let note = NoteRecord { - block_num, - note_index, - note_id, - details, - metadata, - merkle_path, - }; - res.push(note); - } - Ok(res) -} - -/// Select notes matching the tag search criteria using the given [Connection]. -/// -/// # Returns -/// -/// All matching notes from the first block greater than `block_num` containing a matching note. -/// A note is considered a match if it has any of the given tags. If no matching notes are found -/// at all, then an empty vector is returned. -/// -/// # Note -/// -/// This method returns notes from a single block. To fetch all notes up to the chain tip, -/// multiple requests are necessary. -pub fn select_notes_since_block_by_tag( - conn: &mut Connection, - tags: &[u32], - block_num: BlockNumber, -) -> Result> { let tags: Vec = tags.iter().copied().map(u32_to_value).collect(); - - let mut stmt = conn.prepare( - " - SELECT - block_num, - batch_index, - note_index, - note_id, - note_type, - sender, - tag, - aux, - execution_hint, - merkle_path, - details - FROM - notes - WHERE - -- find the next block which contains at least one note with a matching tag - block_num = ( - SELECT - block_num - FROM - notes - WHERE - tag IN rarray(?1) AND - block_num > ?2 - ORDER BY - block_num ASC - LIMIT - 1 - ) AND - -- filter the block's notes and return only the ones matching the requested tags - tag IN rarray(?1); - ", - )?; - let mut rows = stmt.query(params![Rc::new(tags), block_num])?; + let account_ids: Vec = account_ids.iter().copied().map(u64_to_value).collect(); + let mut rows = stmt.query(params![Rc::new(tags), Rc::new(account_ids), block_num])?; let mut res = Vec::new(); while let Some(row) = rows.next()? { @@ -697,8 +603,6 @@ pub fn select_notes_since_block_by_tag( let execution_hint = column_value_as_u64(row, 8)?; let merkle_path_data = row.get_ref(9)?.as_blob()?; let merkle_path = MerklePath::read_from_bytes(merkle_path_data)?; - let details_data = row.get_ref(10)?.as_blob_or_null()?; - let details = details_data.map(>::read_from_bytes).transpose()?; let metadata = NoteMetadata::new( sender.try_into()?, @@ -708,11 +612,10 @@ pub fn select_notes_since_block_by_tag( aux, )?; - let note = NoteRecord { + let note = NoteSyncRecord { block_num, note_index, note_id, - details, metadata, merkle_path, }; @@ -1042,19 +945,14 @@ pub fn get_state_sync( block_num, )?; - let (block_header, chain_tip) = if !notes.is_empty() { - let block_header = select_block_header_by_block_num(conn, Some(notes[0].block_num))? - .ok_or(StateSyncError::EmptyBlockHeadersTable)?; - let tip = select_block_header_by_block_num(conn, None)? - .ok_or(StateSyncError::EmptyBlockHeadersTable)?; - - (block_header, tip.block_num()) - } else { - let block_header = select_block_header_by_block_num(conn, None)? - .ok_or(StateSyncError::EmptyBlockHeadersTable)?; - - let block_num = block_header.block_num(); - (block_header, block_num) + let tip = select_block_header_by_block_num(conn, None)? + .ok_or(StateSyncError::EmptyBlockHeadersTable)?; + let chain_tip = tip.block_num(); + let block_header = match notes.first() { + None => tip, + Some(note) if note.block_num == chain_tip => tip, + Some(note) => select_block_header_by_block_num(conn, Some(note.block_num))? + .ok_or(StateSyncError::EmptyBlockHeadersTable)?, }; let account_updates = @@ -1093,21 +991,16 @@ pub fn get_note_sync( block_num: BlockNumber, note_tags: &[u32], ) -> Result { - let notes = select_notes_since_block_by_tag(conn, note_tags, block_num)?; - - let (block_header, chain_tip) = if !notes.is_empty() { - let block_header = select_block_header_by_block_num(conn, Some(notes[0].block_num))? - .ok_or(NoteSyncError::EmptyBlockHeadersTable)?; - let tip = select_block_header_by_block_num(conn, None)? - .ok_or(NoteSyncError::EmptyBlockHeadersTable)?; - - (block_header, tip.block_num()) - } else { - let block_header = select_block_header_by_block_num(conn, None)? - .ok_or(NoteSyncError::EmptyBlockHeadersTable)?; - - let block_num = block_header.block_num(); - (block_header, block_num) + let notes = select_notes_since_block_by_tag_and_sender(conn, note_tags, &[], block_num)?; + + let tip = select_block_header_by_block_num(conn, None)? + .ok_or(NoteSyncError::EmptyBlockHeadersTable)?; + let chain_tip = tip.block_num(); + let block_header = match notes.first() { + None => tip, + Some(note) if note.block_num == chain_tip => tip, + Some(note) => select_block_header_by_block_num(conn, Some(note.block_num))? + .ok_or(NoteSyncError::EmptyBlockHeadersTable)?, }; Ok(NoteSyncUpdate { notes, block_header, chain_tip }) diff --git a/crates/store/src/db/tests.rs b/crates/store/src/db/tests.rs index 92e3a94ff..f0621a1f6 100644 --- a/crates/store/src/db/tests.rs +++ b/crates/store/src/db/tests.rs @@ -896,7 +896,7 @@ fn test_notes() { let res = sql::select_notes_since_block_by_tag_and_sender(&mut conn, &[tag], &[], block_num_1 - 1) .unwrap(); - assert_eq!(res, vec![note.clone()]); + assert_eq!(res, vec![note.clone().into()]); let block_num_2 = note.block_num + 1; create_block(&mut conn, block_num_2); @@ -919,12 +919,12 @@ fn test_notes() { let res = sql::select_notes_since_block_by_tag_and_sender(&mut conn, &[tag], &[], block_num_1 - 1) .unwrap(); - assert_eq!(res, vec![note.clone()]); + assert_eq!(res, vec![note.clone().into()]); // only the second note is returned let res = sql::select_notes_since_block_by_tag_and_sender(&mut conn, &[tag], &[], block_num_1) .unwrap(); - assert_eq!(res, vec![note2.clone()]); + assert_eq!(res, vec![note2.clone().into()]); // test query notes by id let notes = vec![note, note2]; diff --git a/crates/store/src/server/api.rs b/crates/store/src/server/api.rs index d22fc178e..2af092925 100644 --- a/crates/store/src/server/api.rs +++ b/crates/store/src/server/api.rs @@ -7,7 +7,7 @@ use miden_node_proto::{ generated::{ self, account::AccountSummary, - note::{NoteAuthenticationInfo as NoteAuthenticationInfoProto, NoteSyncRecord}, + note::NoteAuthenticationInfo as NoteAuthenticationInfoProto, requests::{ ApplyBlockRequest, CheckNullifiersByPrefixRequest, CheckNullifiersRequest, GetAccountDetailsRequest, GetAccountStateDeltaRequest, GetBlockByNumberRequest, @@ -190,16 +190,7 @@ impl api_server::Api for StoreApi { }) .collect(); - let notes = state - .notes - .into_iter() - .map(|note| NoteSyncRecord { - note_index: note.note_index.to_absolute_index(), - note_id: Some(note.note_id.into()), - metadata: Some(note.metadata.into()), - merkle_path: Some(Into::into(¬e.merkle_path)), - }) - .collect(); + let notes = state.notes.into_iter().map(Into::into).collect(); let nullifiers = state .nullifiers @@ -241,16 +232,7 @@ impl api_server::Api for StoreApi { .await .map_err(internal_error)?; - let notes = state - .notes - .into_iter() - .map(|note| NoteSyncRecord { - note_index: note.note_index.to_absolute_index(), - note_id: Some(note.note_id.into()), - metadata: Some(note.metadata.into()), - merkle_path: Some((¬e.merkle_path).into()), - }) - .collect(); + let notes = state.notes.into_iter().map(Into::into).collect(); Ok(Response::new(SyncNoteResponse { chain_tip: state.chain_tip, From d25ef9c3a04cd54fd6c566eefd7efbab9cc78b7c Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Sat, 31 Aug 2024 11:58:16 +0500 Subject: [PATCH 03/37] feat: get chain tip from the state (#477) --- crates/store/src/db/mod.rs | 2 -- crates/store/src/db/sql.rs | 27 +++++++-------------------- crates/store/src/server/api.rs | 4 ++-- 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/crates/store/src/db/mod.rs b/crates/store/src/db/mod.rs index b4fab1be6..5191344e7 100644 --- a/crates/store/src/db/mod.rs +++ b/crates/store/src/db/mod.rs @@ -85,7 +85,6 @@ impl From for NotePb { pub struct StateSyncUpdate { pub notes: Vec, pub block_header: BlockHeader, - pub chain_tip: BlockNumber, pub account_updates: Vec, pub transactions: Vec, pub nullifiers: Vec, @@ -95,7 +94,6 @@ pub struct StateSyncUpdate { pub struct NoteSyncUpdate { pub notes: Vec, pub block_header: BlockHeader, - pub chain_tip: BlockNumber, } #[derive(Debug, Clone, PartialEq)] diff --git a/crates/store/src/db/sql.rs b/crates/store/src/db/sql.rs index 8ae55eb83..0e3ea4a4d 100644 --- a/crates/store/src/db/sql.rs +++ b/crates/store/src/db/sql.rs @@ -945,15 +945,9 @@ pub fn get_state_sync( block_num, )?; - let tip = select_block_header_by_block_num(conn, None)? - .ok_or(StateSyncError::EmptyBlockHeadersTable)?; - let chain_tip = tip.block_num(); - let block_header = match notes.first() { - None => tip, - Some(note) if note.block_num == chain_tip => tip, - Some(note) => select_block_header_by_block_num(conn, Some(note.block_num))? - .ok_or(StateSyncError::EmptyBlockHeadersTable)?, - }; + let block_header = + select_block_header_by_block_num(conn, notes.first().map(|note| note.block_num))? + .ok_or(StateSyncError::EmptyBlockHeadersTable)?; let account_updates = select_accounts_by_block_range(conn, block_num, block_header.block_num(), account_ids)?; @@ -975,7 +969,6 @@ pub fn get_state_sync( Ok(StateSyncUpdate { notes, block_header, - chain_tip, account_updates, transactions, nullifiers, @@ -993,17 +986,11 @@ pub fn get_note_sync( ) -> Result { let notes = select_notes_since_block_by_tag_and_sender(conn, note_tags, &[], block_num)?; - let tip = select_block_header_by_block_num(conn, None)? - .ok_or(NoteSyncError::EmptyBlockHeadersTable)?; - let chain_tip = tip.block_num(); - let block_header = match notes.first() { - None => tip, - Some(note) if note.block_num == chain_tip => tip, - Some(note) => select_block_header_by_block_num(conn, Some(note.block_num))? - .ok_or(NoteSyncError::EmptyBlockHeadersTable)?, - }; + let block_header = + select_block_header_by_block_num(conn, notes.first().map(|note| note.block_num))? + .ok_or(NoteSyncError::EmptyBlockHeadersTable)?; - Ok(NoteSyncUpdate { notes, block_header, chain_tip }) + Ok(NoteSyncUpdate { notes, block_header }) } // APPLY BLOCK diff --git a/crates/store/src/server/api.rs b/crates/store/src/server/api.rs index 2af092925..a6ba8d5c5 100644 --- a/crates/store/src/server/api.rs +++ b/crates/store/src/server/api.rs @@ -202,7 +202,7 @@ impl api_server::Api for StoreApi { .collect(); Ok(Response::new(SyncStateResponse { - chain_tip: state.chain_tip, + chain_tip: self.state.latest_block_num().await, block_header: Some(state.block_header.into()), mmr_delta: Some(delta.into()), accounts, @@ -235,7 +235,7 @@ impl api_server::Api for StoreApi { let notes = state.notes.into_iter().map(Into::into).collect(); Ok(Response::new(SyncNoteResponse { - chain_tip: state.chain_tip, + chain_tip: self.state.latest_block_num().await, block_header: Some(state.block_header.into()), mmr_path: Some((&mmr_proof.merkle_path).into()), notes, From 7180c571bee23449cf72e069c8c928753c8fd600 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Sun, 1 Sep 2024 14:04:53 -0700 Subject: [PATCH 04/37] chore: increment crate versions to v0.6.0 --- CHANGELOG.md | 5 ++++- Cargo.lock | 54 ++++++++++++++++++++++++++-------------------------- Cargo.toml | 16 ++++++++-------- 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95c411a15..353c533f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v0.6.0 (TBD) + +- Optimized state synchronizations by removing unnecessary fetching and parsing of note details (#462). + ## 0.5.0 (2024-08-27) ### Enhancements @@ -13,7 +17,6 @@ - Added `GetNoteAuthenticationInfo` endpoint (#421). - Added `SyncNotes` endpoint (#424). - Added `execution_hint` field to the `Notes` table (#441). -- Optimized state synchronizations by removing unnecessary fetching and parsing of note details (#462). ### Changes diff --git a/Cargo.lock b/Cargo.lock index 318a25ddf..ed0636bba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -881,7 +881,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.4.0", + "rustc_version 0.4.1", "syn", ] @@ -1118,9 +1118,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "979f00864edc7516466d6b3157706e06c032f22715700ddd878228a91d02bc56" +checksum = "dbb949699c3e4df3a183b1d2142cb24277057055ed23c68ed58894f76c517223" dependencies = [ "cfg-if", "libc", @@ -1174,7 +1174,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.4.0", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", @@ -1356,9 +1356,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -1661,7 +1661,7 @@ dependencies = [ "miden-core", "miden-miette", "miden-thiserror", - "rustc_version 0.4.0", + "rustc_version 0.4.1", "smallvec", "tracing", "unicode-width", @@ -1708,7 +1708,7 @@ dependencies = [ [[package]] name = "miden-faucet" -version = "0.5.0" +version = "0.6.0" dependencies = [ "actix-cors", "actix-web", @@ -1796,7 +1796,7 @@ dependencies = [ [[package]] name = "miden-node" -version = "0.5.0" +version = "0.6.0" dependencies = [ "anyhow", "clap", @@ -1817,7 +1817,7 @@ dependencies = [ [[package]] name = "miden-node-block-producer" -version = "0.5.0" +version = "0.6.0" dependencies = [ "async-trait", "figment", @@ -1845,7 +1845,7 @@ dependencies = [ [[package]] name = "miden-node-proto" -version = "0.5.0" +version = "0.6.0" dependencies = [ "hex", "miden-node-utils", @@ -1862,7 +1862,7 @@ dependencies = [ [[package]] name = "miden-node-rpc" -version = "0.5.0" +version = "0.6.0" dependencies = [ "directories", "figment", @@ -1885,7 +1885,7 @@ dependencies = [ [[package]] name = "miden-node-store" -version = "0.5.0" +version = "0.6.0" dependencies = [ "deadpool-sqlite", "directories", @@ -1918,7 +1918,7 @@ dependencies = [ [[package]] name = "miden-node-utils" -version = "0.5.0" +version = "0.6.0" dependencies = [ "anyhow", "figment", @@ -1934,9 +1934,9 @@ dependencies = [ [[package]] name = "miden-objects" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecc47eda3cdef2c29cd4dc6db8aef920d9cfc1b063b1cc8004a94fd98f1aa58" +checksum = "a20fbba068de2a21c5196c83f435c3ca69f7c283acb55cabc2e645a6bdfbbf00" dependencies = [ "miden-assembly", "miden-core", @@ -1973,7 +1973,7 @@ dependencies = [ [[package]] name = "miden-rpc-proto" -version = "0.5.0" +version = "0.6.0" [[package]] name = "miden-stdlib" @@ -2251,9 +2251,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] @@ -2362,7 +2362,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.4.0", + "indexmap 2.5.0", ] [[package]] @@ -2769,9 +2769,9 @@ dependencies = [ [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver 1.0.23", ] @@ -3058,9 +3058,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "2.0.76" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -3214,9 +3214,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.3" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", @@ -3302,7 +3302,7 @@ version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", diff --git a/Cargo.toml b/Cargo.toml index c1b0ee5f7..370a13d31 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ resolver = "2" [workspace.package] edition = "2021" rust-version = "1.80" -version = "0.5.0" +version = "0.6.0" license = "MIT" authors = ["Miden contributors"] homepage = "https://polygon.technology/polygon-miden" @@ -27,14 +27,14 @@ readme = "README.md" [workspace.dependencies] miden-air = { version = "0.10", default-features = false } miden-lib = { version = "0.5" } -miden-node-block-producer = { path = "crates/block-producer", version = "0.5" } -miden-node-faucet = { path = "bin/faucet", version = "0.5" } -miden-node-proto = { path = "crates/proto", version = "0.5" } -miden-node-rpc = { path = "crates/rpc", version = "0.5" } -miden-node-rpc-proto = { path = "crates/rpc-proto", version = "0.5" } -miden-node-store = { path = "crates/store", version = "0.5" } +miden-node-block-producer = { path = "crates/block-producer", version = "0.6" } +miden-node-faucet = { path = "bin/faucet", version = "0.6" } +miden-node-proto = { path = "crates/proto", version = "0.6" } +miden-node-rpc = { path = "crates/rpc", version = "0.6" } +miden-node-rpc-proto = { path = "crates/rpc-proto", version = "0.6" } +miden-node-store = { path = "crates/store", version = "0.6" } miden-node-test-macro = { path = "crates/test-macro" } -miden-node-utils = { path = "crates/utils", version = "0.5" } +miden-node-utils = { path = "crates/utils", version = "0.6" } miden-objects = { version = "0.5" } miden-processor = { version = "0.10" } miden-stdlib = { version = "0.10", default-features = false } From 8dc465e230ee5536f18ae2c5e20d614717bd4b3e Mon Sep 17 00:00:00 2001 From: Mirko <48352201+Mirko-von-Leipzig@users.noreply.github.com> Date: Sun, 1 Sep 2024 23:27:17 +0200 Subject: [PATCH 05/37] chore: update dependencies (#476) --- Cargo.lock | 243 +++++++++++------- Cargo.toml | 3 +- crates/block-producer/Cargo.toml | 1 - .../block-producer/src/test_utils/account.rs | 7 +- crates/proto/Cargo.toml | 10 +- crates/proto/build.rs | 2 +- crates/proto/src/domain/accounts.rs | 1 - crates/proto/src/domain/blocks.rs | 2 +- crates/proto/src/domain/digest.rs | 4 +- crates/proto/src/generated/account.rs | 4 +- crates/proto/src/generated/block.rs | 2 +- crates/proto/src/generated/block_producer.rs | 47 ++-- crates/proto/src/generated/digest.rs | 2 +- crates/proto/src/generated/note.rs | 2 +- crates/proto/src/generated/requests.rs | 14 +- crates/proto/src/generated/responses.rs | 10 +- crates/proto/src/generated/rpc.rs | 56 ++-- crates/proto/src/generated/smt.rs | 2 +- crates/proto/src/generated/store.rs | 62 ++--- crates/proto/src/generated/transaction.rs | 4 +- crates/rpc/Cargo.toml | 4 +- crates/rpc/src/server/api.rs | 1 - crates/store/Cargo.toml | 3 +- crates/store/src/db/migrations.rs | 7 +- crates/store/src/server/api.rs | 2 +- 25 files changed, 243 insertions(+), 252 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ed0636bba..0646fa13c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 2.6.0", + "bitflags", "bytes", "futures-core", "futures-sink", @@ -45,8 +45,8 @@ dependencies = [ "actix-service", "actix-utils", "ahash", - "base64 0.22.1", - "bitflags 2.6.0", + "base64", + "bitflags", "brotli", "bytes", "bytestring", @@ -54,8 +54,8 @@ dependencies = [ "encoding_rs", "flate2", "futures-core", - "h2", - "http", + "h2 0.3.26", + "http 0.2.12", "httparse", "httpdate", "itoa", @@ -91,7 +91,7 @@ checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" dependencies = [ "bytestring", "cfg-if", - "http", + "http 0.2.12", "regex", "regex-lite", "serde", @@ -412,6 +412,12 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.3.0" @@ -420,18 +426,17 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axum" -version = "0.6.20" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" dependencies = [ "async-trait", "axum-core", - "bitflags 1.3.2", "bytes", "futures-util", - "http", + "http 1.1.0", "http-body", - "hyper", + "http-body-util", "itoa", "matchit", "memchr", @@ -440,7 +445,7 @@ dependencies = [ "pin-project-lite", "rustversion", "serde", - "sync_wrapper", + "sync_wrapper 1.0.1", "tower", "tower-layer", "tower-service", @@ -448,17 +453,20 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.3.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" dependencies = [ "async-trait", "bytes", "futures-util", - "http", + "http 1.1.0", "http-body", + "http-body-util", "mime", + "pin-project-lite", "rustversion", + "sync_wrapper 0.1.2", "tower-layer", "tower-service", ] @@ -487,12 +495,6 @@ dependencies = [ "backtrace", ] -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -511,7 +513,7 @@ version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cexpr", "clang-sys", "itertools 0.12.1", @@ -540,12 +542,6 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.6.0" @@ -1173,7 +1169,26 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", + "indexmap 2.5.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", "indexmap 2.5.0", "slab", "tokio", @@ -1234,22 +1249,39 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" -version = "0.4.6" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http", - "pin-project-lite", + "http 1.1.0", ] [[package]] -name = "http-range-header" -version = "0.3.1" +name = "http-body-util" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body", + "pin-project-lite", +] [[package]] name = "httparse" @@ -1265,38 +1297,56 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.30" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", - "h2", - "http", + "h2 0.4.6", + "http 1.1.0", "http-body", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] [[package]] name = "hyper-timeout" -version = "0.4.1" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body", "hyper", "pin-project-lite", + "socket2", "tokio", - "tokio-io-timeout", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -1515,7 +1565,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.6.0", + "bitflags", "libc", ] @@ -1831,7 +1881,6 @@ dependencies = [ "miden-processor", "miden-stdlib", "miden-tx", - "once_cell", "rand_chacha", "serde", "thiserror", @@ -1895,7 +1944,6 @@ dependencies = [ "miden-node-proto", "miden-node-utils", "miden-objects", - "once_cell", "prost", "rusqlite", "rusqlite_migration", @@ -2473,7 +2521,7 @@ checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.6.0", + "bitflags", "lazy_static", "num-traits", "rand", @@ -2487,9 +2535,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" +checksum = "e13db3d3fde688c61e2446b4d843bc27a7e8af269a69440c0308021dc92333cc" dependencies = [ "bytes", "prost-derive", @@ -2497,13 +2545,13 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.12.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" +checksum = "5bb182580f71dd070f88d01ce3de9f4da5021db7115d2e1c3605a754153b77c1" dependencies = [ "bytes", "heck", - "itertools 0.12.1", + "itertools 0.13.0", "log", "multimap", "once_cell", @@ -2518,12 +2566,12 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" +checksum = "18bec9b0adc4eba778b33684b7ba3e7137789434769ee3ce3930463ef904cfca" dependencies = [ "anyhow", - "itertools 0.12.1", + "itertools 0.13.0", "proc-macro2", "quote", "syn", @@ -2531,9 +2579,9 @@ dependencies = [ [[package]] name = "prost-reflect" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5eec97d5d34bdd17ad2db2219aabf46b054c6c41bd5529767c9ce55be5898f" +checksum = "55a6a9143ae25c25fa7b6a48d6cc08b10785372060009c25140a4e7c340e95af" dependencies = [ "logos", "miette", @@ -2544,18 +2592,18 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.12.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" +checksum = "cee5168b05f49d4b0ca581206eb14a7b22fafd963efe729ac48eb03266e25cc2" dependencies = [ "prost", ] [[package]] name = "protox" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac532509cee918d40f38c3e12f8ef9230f215f017d54de7dd975015538a42ce7" +checksum = "873f359bdecdfe6e353752f97cb9ee69368df55b16363ed2216da85e03232a58" dependencies = [ "bytes", "miette", @@ -2568,9 +2616,9 @@ dependencies = [ [[package]] name = "protox-parse" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6c33f43516fe397e2f930779d720ca12cd057f7da4cd6326a0ef78d69dee96" +checksum = "a3a462d115462c080ae000c29a47f0b3985737e5d3a995fcdbcaa5c782068dde" dependencies = [ "logos", "miette", @@ -2658,7 +2706,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 2.6.0", + "bitflags", ] [[package]] @@ -2728,7 +2776,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae" dependencies = [ - "bitflags 2.6.0", + "bitflags", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -2782,7 +2830,7 @@ version = "0.38.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" dependencies = [ - "bitflags 2.6.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -3073,6 +3121,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + [[package]] name = "tempfile" version = "3.12.0" @@ -3230,16 +3284,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-macros" version = "2.4.0" @@ -3311,23 +3355,26 @@ dependencies = [ [[package]] name = "tonic" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" +checksum = "c6f6ba989e4b2c58ae83d862d3a3e27690b6e3ae630d0deb59f3697f32aa88ad" dependencies = [ "async-stream", "async-trait", "axum", - "base64 0.21.7", + "base64", "bytes", - "h2", - "http", + "h2 0.4.6", + "http 1.1.0", "http-body", + "http-body-util", "hyper", "hyper-timeout", + "hyper-util", "percent-encoding", "pin-project", "prost", + "socket2", "tokio", "tokio-stream", "tower", @@ -3338,9 +3385,9 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4ef6dd70a610078cb4e338a0f79d06bc759ff1b22d2120c2ff02ae264ba9c2" +checksum = "fe4ee8877250136bd7e3d2331632810a4df4ea5e004656990d8d66d2f5ee8a67" dependencies = [ "prettyplease", "proc-macro2", @@ -3351,15 +3398,15 @@ dependencies = [ [[package]] name = "tonic-web" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc3b0e1cedbf19fdfb78ef3d672cb9928e0a91a9cb4629cc0c916e8cff8aaaa1" +checksum = "b904b18f914fe88913a9f0d750065b39c9c497e4b2aa05148f2c29a724145541" dependencies = [ - "base64 0.21.7", + "base64", "bytes", - "http", + "http 1.1.0", "http-body", - "hyper", + "http-body-util", "pin-project", "tokio-stream", "tonic", @@ -3391,17 +3438,15 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" +checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 2.6.0", + "bitflags", "bytes", - "futures-core", - "futures-util", - "http", + "http 1.1.0", "http-body", - "http-range-header", + "http-body-util", "pin-project-lite", "tower-layer", "tower-service", diff --git a/Cargo.toml b/Cargo.toml index 370a13d31..b21db9431 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,8 @@ miden-objects = { version = "0.5" } miden-processor = { version = "0.10" } miden-stdlib = { version = "0.10", default-features = false } miden-tx = { version = "0.5" } +prost = { version = "0.13" } thiserror = { version = "1.0" } -tonic = { version = "0.11" } +tonic = { version = "0.12" } tracing = { version = "0.1" } tracing-subscriber = { version = "0.3", features = ["fmt", "json", "env-filter"] } diff --git a/crates/block-producer/Cargo.toml b/crates/block-producer/Cargo.toml index 85f69b037..0ee8257d5 100644 --- a/crates/block-producer/Cargo.toml +++ b/crates/block-producer/Cargo.toml @@ -39,7 +39,6 @@ miden-lib = { workspace = true, features = ["testing"] } miden-node-test-macro = { path = "../test-macro" } miden-objects = { workspace = true, features = ["testing"] } miden-tx = { workspace = true, features = ["testing"] } -once_cell = { version = "1.18" } rand_chacha = { version = "0.3", default-features = false } tokio = { version = "1.38", features = ["test-util"] } winterfell = { version = "0.9" } diff --git a/crates/block-producer/src/test_utils/account.rs b/crates/block-producer/src/test_utils/account.rs index 0facc1bda..c4f92b6be 100644 --- a/crates/block-producer/src/test_utils/account.rs +++ b/crates/block-producer/src/test_utils/account.rs @@ -1,15 +1,14 @@ -use std::{collections::HashMap, ops::Not}; +use std::{collections::HashMap, ops::Not, sync::LazyLock}; use miden_objects::{ accounts::{get_account_seed, AccountStorageType, AccountType}, Hasher, }; -use once_cell::sync::Lazy; use super::*; -pub static MOCK_ACCOUNTS: Lazy>> = - Lazy::new(Default::default); +pub static MOCK_ACCOUNTS: LazyLock>> = + LazyLock::new(Default::default); /// A mock representation fo private accounts. An account starts in state `states[0]`, is modified /// to state `states[1]`, and so on. diff --git a/crates/proto/Cargo.toml b/crates/proto/Cargo.toml index b2666395f..4caf9fba0 100644 --- a/crates/proto/Cargo.toml +++ b/crates/proto/Cargo.toml @@ -15,7 +15,7 @@ repository.workspace = true hex = { version = "0.4" } miden-node-utils = { workspace = true } miden-objects = { workspace = true } -prost = { version = "0.12" } +prost = { workspace = true } thiserror = { workspace = true } tonic = { workspace = true } @@ -24,7 +24,7 @@ proptest = { version = "1.5" } [build-dependencies] miette = { version = "7.2", features = ["fancy"] } -prost = { version = "0.12" } -prost-build = { version = "0.12" } -protox = { version = "0.6" } -tonic-build = { version = "0.11" } +prost = { workspace = true } +prost-build = { version = "0.13" } +protox = { version = "0.7" } +tonic-build = { version = "0.12" } diff --git a/crates/proto/build.rs b/crates/proto/build.rs index e73f41bc9..e08074c4a 100644 --- a/crates/proto/build.rs +++ b/crates/proto/build.rs @@ -4,7 +4,7 @@ use std::{ }; use miette::IntoDiagnostic; -use prost::Message; +use protox::prost::Message; /// Generates Rust protobuf bindings from .proto files in the root directory. /// diff --git a/crates/proto/src/domain/accounts.rs b/crates/proto/src/domain/accounts.rs index cc9fb7306..eaea327e4 100644 --- a/crates/proto/src/domain/accounts.rs +++ b/crates/proto/src/domain/accounts.rs @@ -186,7 +186,6 @@ impl TryFrom for AccountState { fn try_from(from: AccountTransactionInputRecord) -> Result { let account_id = from .account_id - .clone() .ok_or(AccountTransactionInputRecord::missing_field(stringify!(account_id)))? .try_into()?; diff --git a/crates/proto/src/domain/blocks.rs b/crates/proto/src/domain/blocks.rs index a1c496b7d..b46ab87fe 100644 --- a/crates/proto/src/domain/blocks.rs +++ b/crates/proto/src/domain/blocks.rs @@ -35,7 +35,7 @@ impl TryFrom<&block::BlockHeader> for BlockHeader { type Error = ConversionError; fn try_from(value: &block::BlockHeader) -> Result { - value.clone().try_into() + value.try_into() } } diff --git a/crates/proto/src/domain/digest.rs b/crates/proto/src/domain/digest.rs index b3f15416b..288620944 100644 --- a/crates/proto/src/domain/digest.rs +++ b/crates/proto/src/domain/digest.rs @@ -187,7 +187,7 @@ impl TryFrom<&digest::Digest> for [Felt; 4] { type Error = ConversionError; fn try_from(value: &digest::Digest) -> Result { - value.clone().try_into() + value.try_into() } } @@ -195,7 +195,7 @@ impl TryFrom<&digest::Digest> for Digest { type Error = ConversionError; fn try_from(value: &digest::Digest) -> Result { - value.clone().try_into() + value.try_into() } } diff --git a/crates/proto/src/generated/account.rs b/crates/proto/src/generated/account.rs index 0edd3bfc5..d01e9f0da 100644 --- a/crates/proto/src/generated/account.rs +++ b/crates/proto/src/generated/account.rs @@ -1,6 +1,6 @@ // This file is @generated by prost-build. #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] #[prost(skip_debug)] pub struct AccountId { /// A miden account is defined with a little bit of proof-of-work, the id itself is defined as @@ -10,7 +10,7 @@ pub struct AccountId { pub id: u64, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct AccountSummary { #[prost(message, optional, tag = "1")] pub account_id: ::core::option::Option, diff --git a/crates/proto/src/generated/block.rs b/crates/proto/src/generated/block.rs index 14ca28944..fec751fb8 100644 --- a/crates/proto/src/generated/block.rs +++ b/crates/proto/src/generated/block.rs @@ -1,6 +1,6 @@ // This file is @generated by prost-build. #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct BlockHeader { /// specifies the version of the protocol. #[prost(uint32, tag = "1")] diff --git a/crates/proto/src/generated/block_producer.rs b/crates/proto/src/generated/block_producer.rs index 2aabecafe..362af881b 100644 --- a/crates/proto/src/generated/block_producer.rs +++ b/crates/proto/src/generated/block_producer.rs @@ -23,8 +23,8 @@ pub mod api_client { where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -49,7 +49,7 @@ pub mod api_client { >, , - >>::Error: Into + Send + Sync, + >>::Error: Into + std::marker::Send + std::marker::Sync, { ApiClient::new(InterceptedService::new(inner, interceptor)) } @@ -121,7 +121,7 @@ pub mod api_server { use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with ApiServer. #[async_trait] - pub trait Api: Send + Sync + 'static { + pub trait Api: std::marker::Send + std::marker::Sync + 'static { async fn submit_proven_transaction( &self, request: tonic::Request< @@ -133,20 +133,18 @@ pub mod api_server { >; } #[derive(Debug)] - pub struct ApiServer { - inner: _Inner, + pub struct ApiServer { + inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, max_decoding_message_size: Option, max_encoding_message_size: Option, } - struct _Inner(Arc); - impl ApiServer { + impl ApiServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } pub fn from_arc(inner: Arc) -> Self { - let inner = _Inner(inner); Self { inner, accept_compression_encodings: Default::default(), @@ -196,8 +194,8 @@ pub mod api_server { impl tonic::codegen::Service> for ApiServer where T: Api, - B: Body + Send + 'static, - B::Error: Into + Send + 'static, + B: Body + std::marker::Send + 'static, + B::Error: Into + std::marker::Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -209,7 +207,6 @@ pub mod api_server { Poll::Ready(Ok(())) } fn call(&mut self, req: http::Request) -> Self::Future { - let inner = self.inner.clone(); match req.uri().path() { "/block_producer.Api/SubmitProvenTransaction" => { #[allow(non_camel_case_types)] @@ -243,7 +240,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = SubmitProvenTransactionSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -265,8 +261,11 @@ pub mod api_server { Ok( http::Response::builder() .status(200) - .header("grpc-status", "12") - .header("content-type", "application/grpc") + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ) .body(empty_body()) .unwrap(), ) @@ -275,7 +274,7 @@ pub mod api_server { } } } - impl Clone for ApiServer { + impl Clone for ApiServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -287,17 +286,9 @@ pub mod api_server { } } } - impl Clone for _Inner { - fn clone(&self) -> Self { - Self(Arc::clone(&self.0)) - } - } - impl std::fmt::Debug for _Inner { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } - } - impl tonic::server::NamedService for ApiServer { - const NAME: &'static str = "block_producer.Api"; + /// Generated gRPC service name + pub const SERVICE_NAME: &str = "block_producer.Api"; + impl tonic::server::NamedService for ApiServer { + const NAME: &'static str = SERVICE_NAME; } } diff --git a/crates/proto/src/generated/digest.rs b/crates/proto/src/generated/digest.rs index b17aafc09..e6dde1693 100644 --- a/crates/proto/src/generated/digest.rs +++ b/crates/proto/src/generated/digest.rs @@ -1,7 +1,7 @@ // This file is @generated by prost-build. /// A hash digest, the result of a hash function. #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] #[prost(skip_debug)] pub struct Digest { #[prost(fixed64, tag = "1")] diff --git a/crates/proto/src/generated/note.rs b/crates/proto/src/generated/note.rs index 74f462e54..dc8d3171e 100644 --- a/crates/proto/src/generated/note.rs +++ b/crates/proto/src/generated/note.rs @@ -1,6 +1,6 @@ // This file is @generated by prost-build. #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct NoteMetadata { #[prost(message, optional, tag = "1")] pub sender: ::core::option::Option, diff --git a/crates/proto/src/generated/requests.rs b/crates/proto/src/generated/requests.rs index 4b8124487..4250a49dd 100644 --- a/crates/proto/src/generated/requests.rs +++ b/crates/proto/src/generated/requests.rs @@ -28,7 +28,7 @@ pub struct CheckNullifiersRequest { /// /// The Merkle path is an MMR proof for the block's leaf, based on the current chain length. #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetBlockHeaderByNumberRequest { /// The block number of the target block. /// @@ -127,24 +127,24 @@ pub struct GetNoteAuthenticationInfoRequest { pub note_ids: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct ListNullifiersRequest {} #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct ListAccountsRequest {} #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct ListNotesRequest {} /// Returns the latest state of an account with the specified ID. #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetAccountDetailsRequest { /// Account ID to get details. #[prost(message, optional, tag = "1")] pub account_id: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetBlockByNumberRequest { /// The block number of the target block. #[prost(fixed32, tag = "1")] @@ -153,7 +153,7 @@ pub struct GetBlockByNumberRequest { /// Returns delta of the account states in the range from `from_block_num` (exclusive) to /// `to_block_num` (inclusive). #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetAccountStateDeltaRequest { /// ID of the account for which the delta is requested. #[prost(message, optional, tag = "1")] diff --git a/crates/proto/src/generated/responses.rs b/crates/proto/src/generated/responses.rs index 875d7ff47..478ffc899 100644 --- a/crates/proto/src/generated/responses.rs +++ b/crates/proto/src/generated/responses.rs @@ -1,6 +1,6 @@ // This file is @generated by prost-build. #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct ApplyBlockResponse {} #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -30,7 +30,7 @@ pub struct GetBlockHeaderByNumberResponse { pub chain_length: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct NullifierUpdate { #[prost(message, optional, tag = "1")] pub nullifier: ::core::option::Option, @@ -125,7 +125,7 @@ pub struct GetBlockInputsResponse { } /// An account returned as a response to the GetTransactionInputs #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct AccountTransactionInputRecord { #[prost(message, optional, tag = "1")] pub account_id: ::core::option::Option, @@ -135,7 +135,7 @@ pub struct AccountTransactionInputRecord { } /// A nullifier returned as a response to the GetTransactionInputs #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct NullifierTransactionInputRecord { #[prost(message, optional, tag = "1")] pub nullifier: ::core::option::Option, @@ -156,7 +156,7 @@ pub struct GetTransactionInputsResponse { pub block_height: u32, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct SubmitProvenTransactionResponse { /// The node's current block height #[prost(fixed32, tag = "1")] diff --git a/crates/proto/src/generated/rpc.rs b/crates/proto/src/generated/rpc.rs index be76165b9..3f35dceb2 100644 --- a/crates/proto/src/generated/rpc.rs +++ b/crates/proto/src/generated/rpc.rs @@ -23,8 +23,8 @@ pub mod api_client { where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -49,7 +49,7 @@ pub mod api_client { >, , - >>::Error: Into + Send + Sync, + >>::Error: Into + std::marker::Send + std::marker::Sync, { ApiClient::new(InterceptedService::new(inner, interceptor)) } @@ -340,7 +340,7 @@ pub mod api_server { use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with ApiServer. #[async_trait] - pub trait Api: Send + Sync + 'static { + pub trait Api: std::marker::Send + std::marker::Sync + 'static { async fn check_nullifiers( &self, request: tonic::Request, @@ -419,20 +419,18 @@ pub mod api_server { >; } #[derive(Debug)] - pub struct ApiServer { - inner: _Inner, + pub struct ApiServer { + inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, max_decoding_message_size: Option, max_encoding_message_size: Option, } - struct _Inner(Arc); - impl ApiServer { + impl ApiServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } pub fn from_arc(inner: Arc) -> Self { - let inner = _Inner(inner); Self { inner, accept_compression_encodings: Default::default(), @@ -482,8 +480,8 @@ pub mod api_server { impl tonic::codegen::Service> for ApiServer where T: Api, - B: Body + Send + 'static, - B::Error: Into + Send + 'static, + B: Body + std::marker::Send + 'static, + B::Error: Into + std::marker::Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -495,7 +493,6 @@ pub mod api_server { Poll::Ready(Ok(())) } fn call(&mut self, req: http::Request) -> Self::Future { - let inner = self.inner.clone(); match req.uri().path() { "/rpc.Api/CheckNullifiers" => { #[allow(non_camel_case_types)] @@ -529,7 +526,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = CheckNullifiersSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -579,7 +575,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = CheckNullifiersByPrefixSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -628,7 +623,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = GetAccountDetailsSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -677,7 +671,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = GetAccountStateDeltaSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -726,7 +719,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = GetBlockByNumberSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -776,7 +768,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = GetBlockHeaderByNumberSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -825,7 +816,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = GetNotesByIdSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -874,7 +864,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = SubmitProvenTransactionSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -923,7 +912,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = SyncNotesSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -972,7 +960,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = SyncStateSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -994,8 +981,11 @@ pub mod api_server { Ok( http::Response::builder() .status(200) - .header("grpc-status", "12") - .header("content-type", "application/grpc") + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ) .body(empty_body()) .unwrap(), ) @@ -1004,7 +994,7 @@ pub mod api_server { } } } - impl Clone for ApiServer { + impl Clone for ApiServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -1016,17 +1006,9 @@ pub mod api_server { } } } - impl Clone for _Inner { - fn clone(&self) -> Self { - Self(Arc::clone(&self.0)) - } - } - impl std::fmt::Debug for _Inner { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } - } - impl tonic::server::NamedService for ApiServer { - const NAME: &'static str = "rpc.Api"; + /// Generated gRPC service name + pub const SERVICE_NAME: &str = "rpc.Api"; + impl tonic::server::NamedService for ApiServer { + const NAME: &'static str = SERVICE_NAME; } } diff --git a/crates/proto/src/generated/smt.rs b/crates/proto/src/generated/smt.rs index 2e22f63b1..552ce9e32 100644 --- a/crates/proto/src/generated/smt.rs +++ b/crates/proto/src/generated/smt.rs @@ -1,7 +1,7 @@ // This file is @generated by prost-build. /// An entry in a leaf. #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct SmtLeafEntry { #[prost(message, optional, tag = "1")] pub key: ::core::option::Option, diff --git a/crates/proto/src/generated/store.rs b/crates/proto/src/generated/store.rs index f14135837..6d32c3219 100644 --- a/crates/proto/src/generated/store.rs +++ b/crates/proto/src/generated/store.rs @@ -23,8 +23,8 @@ pub mod api_client { where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -49,7 +49,7 @@ pub mod api_client { >, , - >>::Error: Into + Send + Sync, + >>::Error: Into + std::marker::Send + std::marker::Sync, { ApiClient::new(InterceptedService::new(inner, interceptor)) } @@ -487,7 +487,7 @@ pub mod api_server { use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with ApiServer. #[async_trait] - pub trait Api: Send + Sync + 'static { + pub trait Api: std::marker::Send + std::marker::Sync + 'static { async fn apply_block( &self, request: tonic::Request, @@ -608,20 +608,18 @@ pub mod api_server { >; } #[derive(Debug)] - pub struct ApiServer { - inner: _Inner, + pub struct ApiServer { + inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, max_decoding_message_size: Option, max_encoding_message_size: Option, } - struct _Inner(Arc); - impl ApiServer { + impl ApiServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } pub fn from_arc(inner: Arc) -> Self { - let inner = _Inner(inner); Self { inner, accept_compression_encodings: Default::default(), @@ -671,8 +669,8 @@ pub mod api_server { impl tonic::codegen::Service> for ApiServer where T: Api, - B: Body + Send + 'static, - B::Error: Into + Send + 'static, + B: Body + std::marker::Send + 'static, + B::Error: Into + std::marker::Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -684,7 +682,6 @@ pub mod api_server { Poll::Ready(Ok(())) } fn call(&mut self, req: http::Request) -> Self::Future { - let inner = self.inner.clone(); match req.uri().path() { "/store.Api/ApplyBlock" => { #[allow(non_camel_case_types)] @@ -718,7 +715,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = ApplyBlockSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -767,7 +763,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = CheckNullifiersSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -817,7 +812,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = CheckNullifiersByPrefixSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -866,7 +860,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = GetAccountDetailsSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -915,7 +908,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = GetAccountStateDeltaSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -964,7 +956,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = GetBlockByNumberSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -1014,7 +1005,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = GetBlockHeaderByNumberSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -1063,7 +1053,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = GetBlockInputsSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -1113,7 +1102,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = GetNoteAuthenticationInfoSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -1162,7 +1150,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = GetNotesByIdSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -1211,7 +1198,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = GetTransactionInputsSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -1260,7 +1246,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = ListAccountsSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -1309,7 +1294,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = ListNotesSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -1358,7 +1342,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = ListNullifiersSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -1407,7 +1390,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = SyncNotesSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -1456,7 +1438,6 @@ pub mod api_server { let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; let method = SyncStateSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) @@ -1478,8 +1459,11 @@ pub mod api_server { Ok( http::Response::builder() .status(200) - .header("grpc-status", "12") - .header("content-type", "application/grpc") + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ) .body(empty_body()) .unwrap(), ) @@ -1488,7 +1472,7 @@ pub mod api_server { } } } - impl Clone for ApiServer { + impl Clone for ApiServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -1500,17 +1484,9 @@ pub mod api_server { } } } - impl Clone for _Inner { - fn clone(&self) -> Self { - Self(Arc::clone(&self.0)) - } - } - impl std::fmt::Debug for _Inner { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } - } - impl tonic::server::NamedService for ApiServer { - const NAME: &'static str = "store.Api"; + /// Generated gRPC service name + pub const SERVICE_NAME: &str = "store.Api"; + impl tonic::server::NamedService for ApiServer { + const NAME: &'static str = SERVICE_NAME; } } diff --git a/crates/proto/src/generated/transaction.rs b/crates/proto/src/generated/transaction.rs index 3656ff592..443f71d35 100644 --- a/crates/proto/src/generated/transaction.rs +++ b/crates/proto/src/generated/transaction.rs @@ -1,12 +1,12 @@ // This file is @generated by prost-build. #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct TransactionId { #[prost(message, optional, tag = "1")] pub id: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct TransactionSummary { #[prost(message, optional, tag = "1")] pub transaction_id: ::core::option::Option, diff --git a/crates/rpc/Cargo.toml b/crates/rpc/Cargo.toml index a4d779625..d96659419 100644 --- a/crates/rpc/Cargo.toml +++ b/crates/rpc/Cargo.toml @@ -21,12 +21,12 @@ miden-node-store = { workspace = true } miden-node-utils = { workspace = true } miden-objects = { workspace = true } miden-tx = { workspace = true } -prost = { version = "0.12" } +prost = { workspace = true } serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.38", features = ["rt-multi-thread", "net", "macros"] } toml = { version = "0.8" } tonic = { workspace = true } -tonic-web = { version = "0.11" } +tonic-web = { version = "0.12" } tracing = { workspace = true } tracing-subscriber = { workspace = true } diff --git a/crates/rpc/src/server/api.rs b/crates/rpc/src/server/api.rs index fc4836d08..acf8e0d9f 100644 --- a/crates/rpc/src/server/api.rs +++ b/crates/rpc/src/server/api.rs @@ -208,7 +208,6 @@ impl api_server::Api for RpcApi { let _account_id: AccountId = request .get_ref() .account_id - .clone() .ok_or(Status::invalid_argument("account_id is missing"))? .try_into() .map_err(|err| Status::invalid_argument(format!("Invalid account id: {err}")))?; diff --git a/crates/store/Cargo.toml b/crates/store/Cargo.toml index e22d89f60..acf54987d 100644 --- a/crates/store/Cargo.toml +++ b/crates/store/Cargo.toml @@ -20,8 +20,7 @@ miden-lib = { workspace = true } miden-node-proto = { workspace = true } miden-node-utils = { workspace = true } miden-objects = { workspace = true } -once_cell = { version = "1.18" } -prost = { version = "0.12" } +prost = { workspace = true } rusqlite = { version = "0.31", features = ["array", "buildtime_bindgen", "bundled"] } rusqlite_migration = { version = "1.0" } serde = { version = "1.0", features = ["derive"] } diff --git a/crates/store/src/db/migrations.rs b/crates/store/src/db/migrations.rs index e93591d85..8ccbcdaf7 100644 --- a/crates/store/src/db/migrations.rs +++ b/crates/store/src/db/migrations.rs @@ -1,5 +1,6 @@ +use std::sync::LazyLock; + use miden_objects::crypto::hash::blake::{Blake3Digest, Blake3_160}; -use once_cell::sync::Lazy; use rusqlite::Connection; use rusqlite_migration::{Migrations, SchemaVersion, M}; use tracing::{debug, error, info, instrument}; @@ -13,8 +14,8 @@ use crate::{ type Hash = Blake3Digest<20>; const MIGRATION_SCRIPTS: [&str; 1] = [include_str!("migrations/001-init.sql")]; -static MIGRATION_HASHES: Lazy> = Lazy::new(compute_migration_hashes); -static MIGRATIONS: Lazy = Lazy::new(prepare_migrations); +static MIGRATION_HASHES: LazyLock> = LazyLock::new(compute_migration_hashes); +static MIGRATIONS: LazyLock = LazyLock::new(prepare_migrations); fn up(s: &'static str) -> M<'static> { M::up(s).foreign_key_check() diff --git a/crates/store/src/server/api.rs b/crates/store/src/server/api.rs index a6ba8d5c5..85fa23d32 100644 --- a/crates/store/src/server/api.rs +++ b/crates/store/src/server/api.rs @@ -602,7 +602,7 @@ fn validate_nullifiers(nullifiers: &[generated::digest::Digest]) -> Result Result, Status> { notes .iter() - .map(|digest| Ok(RpoDigest::try_from(digest.clone())?.into())) + .map(|digest| Ok(RpoDigest::try_from(digest)?.into())) .collect::>() .map_err(|_| invalid_argument("Digest field is not in the modulus range")) } From 424a18c2bd7afc0746dc684a100379eabef0402b Mon Sep 17 00:00:00 2001 From: Tomas Rodriguez Dala <43424983+tomyrd@users.noreply.github.com> Date: Tue, 3 Sep 2024 17:40:48 -0300 Subject: [PATCH 06/37] fix: type shadowing in proto file (#481) * fix: change field name in `GetAccountDetailsResponse` * update: CHANGELOG --- CHANGELOG.md | 1 + crates/proto/src/generated/responses.rs | 2 +- crates/rpc-proto/proto/responses.proto | 2 +- crates/store/src/server/api.rs | 2 +- proto/responses.proto | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 353c533f5..6afef8bfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## v0.6.0 (TBD) - Optimized state synchronizations by removing unnecessary fetching and parsing of note details (#462). +- [BREAKING] Changed `GetAccountDetailsResponse` field to `details` (#481). ## 0.5.0 (2024-08-27) diff --git a/crates/proto/src/generated/responses.rs b/crates/proto/src/generated/responses.rs index 478ffc899..02b456e7f 100644 --- a/crates/proto/src/generated/responses.rs +++ b/crates/proto/src/generated/responses.rs @@ -201,7 +201,7 @@ pub struct ListNotesResponse { pub struct GetAccountDetailsResponse { /// Account info (with details for on-chain accounts) #[prost(message, optional, tag = "1")] - pub account: ::core::option::Option, + pub details: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/crates/rpc-proto/proto/responses.proto b/crates/rpc-proto/proto/responses.proto index c6bbe7a32..a64d643d9 100644 --- a/crates/rpc-proto/proto/responses.proto +++ b/crates/rpc-proto/proto/responses.proto @@ -161,7 +161,7 @@ message ListNotesResponse { message GetAccountDetailsResponse { // Account info (with details for on-chain accounts) - account.AccountInfo account = 1; + account.AccountInfo details = 1; } message GetBlockByNumberResponse { diff --git a/crates/store/src/server/api.rs b/crates/store/src/server/api.rs index 85fa23d32..eff120592 100644 --- a/crates/store/src/server/api.rs +++ b/crates/store/src/server/api.rs @@ -335,7 +335,7 @@ impl api_server::Api for StoreApi { .map_err(internal_error)?; Ok(Response::new(GetAccountDetailsResponse { - account: Some((&account_info).into()), + details: Some((&account_info).into()), })) } diff --git a/proto/responses.proto b/proto/responses.proto index c6bbe7a32..a64d643d9 100644 --- a/proto/responses.proto +++ b/proto/responses.proto @@ -161,7 +161,7 @@ message ListNotesResponse { message GetAccountDetailsResponse { // Account info (with details for on-chain accounts) - account.AccountInfo account = 1; + account.AccountInfo details = 1; } message GetBlockByNumberResponse { From 9567cf40c6af63c7207e03f3aadb3492ea65bf8e Mon Sep 17 00:00:00 2001 From: Santiago Pittella <87827390+SantiagoPittella@users.noreply.github.com> Date: Mon, 9 Sep 2024 17:12:02 -0300 Subject: [PATCH 07/37] fix: `AccountStub`->`AccountHeader`, `AccountStorageType`->`AccountStorageMode`, docs and miden-base using `next` (#489) * fix: replace AccountStub with AccountHeader, replace AccountStorageType with AccountStorageMode, update docs, update miden-base to use next branch * fix: update changelog --- CHANGELOG.md | 1 + Cargo.lock | 132 ++++++++---------- Cargo.toml | 6 +- bin/faucet/src/client.rs | 4 +- bin/node/src/commands/genesis/inputs.rs | 4 +- bin/node/src/commands/genesis/mod.rs | 22 +-- config/genesis.toml | 4 +- .../block-producer/src/test_utils/account.rs | 4 +- crates/proto/src/generated/account.rs | 3 - crates/proto/src/generated/block.rs | 2 - crates/proto/src/generated/digest.rs | 1 - crates/proto/src/generated/merkle.rs | 1 - crates/proto/src/generated/mmr.rs | 1 - crates/proto/src/generated/note.rs | 7 +- crates/proto/src/generated/requests.rs | 17 --- crates/proto/src/generated/responses.rs | 24 +--- crates/proto/src/generated/smt.rs | 5 - crates/proto/src/generated/transaction.rs | 2 - crates/rpc-proto/proto/note.proto | 2 +- crates/rpc-proto/proto/responses.proto | 2 +- crates/rpc/src/server/api.rs | 2 +- crates/store/src/errors.rs | 2 +- crates/store/src/genesis.rs | 2 +- crates/store/src/server/api.rs | 2 +- crates/store/src/state.rs | 2 +- proto/note.proto | 2 +- proto/responses.proto | 2 +- 27 files changed, 87 insertions(+), 171 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6afef8bfc..a081145bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## v0.6.0 (TBD) +- [BREAKING] Renamed `off-chain` and `on-chain` to `private` and `public` respectively for the account storage modes (#489). - Optimized state synchronizations by removing unnecessary fetching and parsing of note details (#462). - [BREAKING] Changed `GetAccountDetailsResponse` field to `details` (#481). diff --git a/Cargo.lock b/Cargo.lock index 0646fa13c..33f0b1396 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -214,19 +214,13 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "adler2" version = "2.0.0" @@ -336,9 +330,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" [[package]] name = "arrayref" @@ -394,9 +388,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" dependencies = [ "proc-macro2", "quote", @@ -473,17 +467,17 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", - "miniz_oxide 0.7.4", + "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -599,9 +593,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773d90827bc3feecfb67fab12e24de0749aad83c74b9504ecde46237b5cd24e2" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" [[package]] name = "byteorder" @@ -626,9 +620,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.15" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" dependencies = [ "jobserver", "libc", @@ -687,9 +681,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.16" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -697,9 +691,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", @@ -762,9 +756,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -1032,7 +1026,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" dependencies = [ "crc32fast", - "miniz_oxide 0.8.0", + "miniz_oxide", ] [[package]] @@ -1148,9 +1142,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "glob" @@ -1331,9 +1325,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" dependencies = [ "bytes", "futures-channel", @@ -1793,9 +1787,8 @@ dependencies = [ [[package]] name = "miden-lib" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddd27a34d4919f143fc35b43724d832a94da70c6ade4a8e7b35d2ca2af03bdc" +version = "0.6.0" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#36416cedee53a475ee33ec6222e101cf5811e0b8" dependencies = [ "miden-assembly", "miden-objects", @@ -1982,9 +1975,8 @@ dependencies = [ [[package]] name = "miden-objects" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20fbba068de2a21c5196c83f435c3ca69f7c283acb55cabc2e645a6bdfbbf00" +version = "0.6.0" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#36416cedee53a475ee33ec6222e101cf5811e0b8" dependencies = [ "miden-assembly", "miden-core", @@ -2054,9 +2046,8 @@ dependencies = [ [[package]] name = "miden-tx" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14decd5735786f2cd2c0b4be56f198bec825f1c3c1ed9fb9ffb72b241a5b95f7" +version = "0.6.0" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#36416cedee53a475ee33ec6222e101cf5811e0b8" dependencies = [ "miden-lib", "miden-objects", @@ -2133,15 +2124,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.8.0" @@ -2535,9 +2517,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13db3d3fde688c61e2446b4d843bc27a7e8af269a69440c0308021dc92333cc" +checksum = "3b2ecbe40f08db5c006b5764a2645f7f3f141ce756412ac9e1dd6087e6d32995" dependencies = [ "bytes", "prost-derive", @@ -2545,9 +2527,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb182580f71dd070f88d01ce3de9f4da5021db7115d2e1c3605a754153b77c1" +checksum = "f8650aabb6c35b860610e9cff5dc1af886c9e25073b7b1712a68972af4281302" dependencies = [ "bytes", "heck", @@ -2566,9 +2548,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18bec9b0adc4eba778b33684b7ba3e7137789434769ee3ce3930463ef904cfca" +checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" dependencies = [ "anyhow", "itertools 0.13.0", @@ -2579,9 +2561,9 @@ dependencies = [ [[package]] name = "prost-reflect" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55a6a9143ae25c25fa7b6a48d6cc08b10785372060009c25140a4e7c340e95af" +checksum = "4b7535b02f0e5efe3e1dbfcb428be152226ed0c66cad9541f2274c8ba8d4cd40" dependencies = [ "logos", "miette", @@ -2592,9 +2574,9 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee5168b05f49d4b0ca581206eb14a7b22fafd963efe729ac48eb03266e25cc2" +checksum = "60caa6738c7369b940c3d49246a8d1749323674c65cb13010134f5c9bad5b519" dependencies = [ "prost", ] @@ -2826,9 +2808,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.35" +version = "0.38.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" +checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36" dependencies = [ "bitflags", "errno", @@ -2905,18 +2887,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -2925,9 +2907,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.127" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", @@ -3085,9 +3067,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "supports-color" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9829b314621dfc575df4e409e79f9d6a66a3bd707ab73f23cb4aa3a854ac854f" +checksum = "8775305acf21c96926c900ad056abeef436701108518cf890020387236ac5a77" dependencies = [ "is_ci", ] @@ -3297,9 +3279,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -3308,9 +3290,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -4140,9 +4122,9 @@ dependencies = [ [[package]] name = "winter-utils" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0568612a95bcae3c94fb14da2686f8279ca77723dbdf1e97cf3673798faf6485" +checksum = "c3d71ec2c97685c7e7460a30e27f955d26b8426e7c2db0ddb55a6e0537141f53" dependencies = [ "rayon", ] diff --git a/Cargo.toml b/Cargo.toml index b21db9431..0e302f4d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ readme = "README.md" [workspace.dependencies] miden-air = { version = "0.10", default-features = false } -miden-lib = { version = "0.5" } +miden-lib = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next"} miden-node-block-producer = { path = "crates/block-producer", version = "0.6" } miden-node-faucet = { path = "bin/faucet", version = "0.6" } miden-node-proto = { path = "crates/proto", version = "0.6" } @@ -35,10 +35,10 @@ miden-node-rpc-proto = { path = "crates/rpc-proto", version = "0.6" } miden-node-store = { path = "crates/store", version = "0.6" } miden-node-test-macro = { path = "crates/test-macro" } miden-node-utils = { path = "crates/utils", version = "0.6" } -miden-objects = { version = "0.5" } +miden-objects = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } miden-processor = { version = "0.10" } miden-stdlib = { version = "0.10", default-features = false } -miden-tx = { version = "0.5" } +miden-tx = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } prost = { version = "0.13" } thiserror = { version = "1.0" } tonic = { version = "0.12" } diff --git a/bin/faucet/src/client.rs b/bin/faucet/src/client.rs index 4f20f79f0..c6edf5076 100644 --- a/bin/faucet/src/client.rs +++ b/bin/faucet/src/client.rs @@ -9,7 +9,7 @@ use miden_node_proto::generated::{ rpc::api_client::ApiClient, }; use miden_objects::{ - accounts::{Account, AccountDelta, AccountId, AccountStorageType, AuthSecretKey}, + accounts::{Account, AccountDelta, AccountId, AccountStorageMode, AuthSecretKey}, assets::{FungibleAsset, TokenSymbol}, crypto::{ dsa::rpo_falcon512::SecretKey, @@ -238,7 +238,7 @@ fn build_account(config: FaucetConfig) -> Result<(Account, Word, SecretKey), Fau config.decimals, Felt::try_from(config.max_supply) .map_err(|err| FaucetError::InternalServerError(err.to_string()))?, - AccountStorageType::OffChain, + AccountStorageMode::Private, auth_scheme, ) .map_err(|err| FaucetError::AccountCreationError(err.to_string()))?; diff --git a/bin/node/src/commands/genesis/inputs.rs b/bin/node/src/commands/genesis/inputs.rs index 6ac3acf52..32a54e7d1 100644 --- a/bin/node/src/commands/genesis/inputs.rs +++ b/bin/node/src/commands/genesis/inputs.rs @@ -61,7 +61,7 @@ impl Default for GenesisInput { auth_scheme: AuthSchemeInput::RpoFalcon512, auth_seed: "0xb123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" .to_string(), - storage_mode: "off-chain".to_string(), + storage_mode: "private".to_string(), }), AccountInput::BasicFungibleFaucet(BasicFungibleFaucetInputs { init_seed: "0xc123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" @@ -72,7 +72,7 @@ impl Default for GenesisInput { token_symbol: "POL".to_string(), decimals: 12, max_supply: 1000000, - storage_mode: "on-chain".to_string(), + storage_mode: "public".to_string(), }), ]), } diff --git a/bin/node/src/commands/genesis/mod.rs b/bin/node/src/commands/genesis/mod.rs index 5ec68c476..23d244af4 100644 --- a/bin/node/src/commands/genesis/mod.rs +++ b/bin/node/src/commands/genesis/mod.rs @@ -12,7 +12,7 @@ use miden_lib::{ use miden_node_store::genesis::GenesisState; use miden_node_utils::config::load_config; use miden_objects::{ - accounts::{Account, AccountData, AccountStorageType, AccountType, AuthSecretKey}, + accounts::{Account, AccountData, AccountStorageMode, AccountType, AuthSecretKey}, assets::TokenSymbol, crypto::{ dsa::rpo_falcon512::SecretKey, @@ -135,7 +135,7 @@ fn create_accounts( let (auth_scheme, auth_secret_key) = parse_auth_inputs(inputs.auth_scheme, &inputs.auth_seed)?; - let storage_mode = parse_storage_mode(&inputs.storage_mode)?; + let storage_mode: AccountStorageMode = inputs.storage_mode.as_str().try_into()?; let (account, account_seed) = create_basic_wallet( init_seed, @@ -153,7 +153,7 @@ fn create_accounts( let (auth_scheme, auth_secret_key) = parse_auth_inputs(inputs.auth_scheme, &inputs.auth_seed)?; - let storage_mode = parse_storage_mode(&inputs.storage_mode)?; + let storage_mode: AccountStorageMode = inputs.storage_mode.as_str().try_into()?; let (account, account_seed) = create_basic_fungible_faucet( init_seed, @@ -208,14 +208,6 @@ fn parse_auth_inputs( } } -fn parse_storage_mode(storage_mode: &str) -> Result { - match storage_mode.to_lowercase().as_str() { - "on-chain" => Ok(AccountStorageType::OnChain), - "off-chain" => Ok(AccountStorageType::OffChain), - mode => Err(anyhow!("The provided value for storage_type ({mode}) does not match the expected values (on-chain, off-chain)")) - } -} - // TESTS // ================================================================================================ @@ -247,7 +239,7 @@ mod tests { init_seed = "0xa123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" auth_scheme = "RpoFalcon512" auth_seed = "0xb123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - storage_mode = "off-chain" + storage_mode = "private" [[accounts]] type = "BasicFungibleFaucet" @@ -257,7 +249,7 @@ mod tests { token_symbol = "POL" decimals = 12 max_supply = 1000000 - storage_mode = "on-chain" + storage_mode = "public" "#, )?; @@ -279,8 +271,8 @@ mod tests { let a1 = AccountData::read(a1_file_path).unwrap(); // assert that the accounts have the corresponding storage mode - assert!(!a0.account.is_on_chain()); - assert!(a1.account.is_on_chain()); + assert!(!a0.account.is_public()); + assert!(a1.account.is_public()); let genesis_file_contents = fs::read(genesis_dat_file_path).unwrap(); let genesis_state = GenesisState::read_from_bytes(&genesis_file_contents).unwrap(); diff --git a/config/genesis.toml b/config/genesis.toml index 310628857..0ee00bbda 100644 --- a/config/genesis.toml +++ b/config/genesis.toml @@ -4,14 +4,14 @@ timestamp = 1672531200 [[accounts]] type = "BasicWallet" -storage_mode = "off-chain" +storage_mode = "private" init_seed = "0xa123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" auth_scheme = "RpoFalcon512" auth_seed = "0xb123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" [[accounts]] type = "BasicFungibleFaucet" -storage_mode = "on-chain" +storage_mode = "public" init_seed = "0xc123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" auth_scheme = "RpoFalcon512" auth_seed = "0xd123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" diff --git a/crates/block-producer/src/test_utils/account.rs b/crates/block-producer/src/test_utils/account.rs index c4f92b6be..af0d614c0 100644 --- a/crates/block-producer/src/test_utils/account.rs +++ b/crates/block-producer/src/test_utils/account.rs @@ -1,7 +1,7 @@ use std::{collections::HashMap, ops::Not, sync::LazyLock}; use miden_objects::{ - accounts::{get_account_seed, AccountStorageType, AccountType}, + accounts::{get_account_seed, AccountStorageMode, AccountType}, Hasher, }; @@ -37,7 +37,7 @@ impl MockPrivateAccount { let account_seed = get_account_seed( init_seed, AccountType::RegularAccountUpdatableCode, - AccountStorageType::OffChain, + AccountStorageMode::Private, Digest::default(), Digest::default(), ) diff --git a/crates/proto/src/generated/account.rs b/crates/proto/src/generated/account.rs index d01e9f0da..bcf609958 100644 --- a/crates/proto/src/generated/account.rs +++ b/crates/proto/src/generated/account.rs @@ -1,5 +1,4 @@ // This file is @generated by prost-build. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] #[prost(skip_debug)] pub struct AccountId { @@ -9,7 +8,6 @@ pub struct AccountId { #[prost(fixed64, tag = "1")] pub id: u64, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct AccountSummary { #[prost(message, optional, tag = "1")] @@ -19,7 +17,6 @@ pub struct AccountSummary { #[prost(uint32, tag = "3")] pub block_num: u32, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AccountInfo { #[prost(message, optional, tag = "1")] diff --git a/crates/proto/src/generated/block.rs b/crates/proto/src/generated/block.rs index fec751fb8..ebb676425 100644 --- a/crates/proto/src/generated/block.rs +++ b/crates/proto/src/generated/block.rs @@ -1,5 +1,4 @@ // This file is @generated by prost-build. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct BlockHeader { /// specifies the version of the protocol. @@ -33,7 +32,6 @@ pub struct BlockHeader { #[prost(fixed32, tag = "10")] pub timestamp: u32, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct BlockInclusionProof { #[prost(message, optional, tag = "1")] diff --git a/crates/proto/src/generated/digest.rs b/crates/proto/src/generated/digest.rs index e6dde1693..d6d3c235a 100644 --- a/crates/proto/src/generated/digest.rs +++ b/crates/proto/src/generated/digest.rs @@ -1,6 +1,5 @@ // This file is @generated by prost-build. /// A hash digest, the result of a hash function. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] #[prost(skip_debug)] pub struct Digest { diff --git a/crates/proto/src/generated/merkle.rs b/crates/proto/src/generated/merkle.rs index 2d2676abb..0aed4fbdc 100644 --- a/crates/proto/src/generated/merkle.rs +++ b/crates/proto/src/generated/merkle.rs @@ -1,5 +1,4 @@ // This file is @generated by prost-build. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MerklePath { #[prost(message, repeated, tag = "1")] diff --git a/crates/proto/src/generated/mmr.rs b/crates/proto/src/generated/mmr.rs index 338c8199a..f53ebe2d3 100644 --- a/crates/proto/src/generated/mmr.rs +++ b/crates/proto/src/generated/mmr.rs @@ -1,5 +1,4 @@ // This file is @generated by prost-build. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MmrDelta { #[prost(uint64, tag = "1")] diff --git a/crates/proto/src/generated/note.rs b/crates/proto/src/generated/note.rs index dc8d3171e..563532b7d 100644 --- a/crates/proto/src/generated/note.rs +++ b/crates/proto/src/generated/note.rs @@ -1,5 +1,4 @@ // This file is @generated by prost-build. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct NoteMetadata { #[prost(message, optional, tag = "1")] @@ -13,7 +12,6 @@ pub struct NoteMetadata { #[prost(fixed64, tag = "5")] pub aux: u64, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Note { #[prost(fixed32, tag = "1")] @@ -26,12 +24,11 @@ pub struct Note { pub metadata: ::core::option::Option, #[prost(message, optional, tag = "5")] pub merkle_path: ::core::option::Option, - /// This field will be present when the note is on-chain. + /// This field will be present when the note is public. /// details contain the `Note` in a serialized format. #[prost(bytes = "vec", optional, tag = "6")] pub details: ::core::option::Option<::prost::alloc::vec::Vec>, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct NoteInclusionInBlockProof { #[prost(message, optional, tag = "1")] @@ -43,7 +40,6 @@ pub struct NoteInclusionInBlockProof { #[prost(message, optional, tag = "4")] pub merkle_path: ::core::option::Option, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct NoteSyncRecord { #[prost(uint32, tag = "1")] @@ -55,7 +51,6 @@ pub struct NoteSyncRecord { #[prost(message, optional, tag = "4")] pub merkle_path: ::core::option::Option, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct NoteAuthenticationInfo { /// Proof of each note's inclusion in a block. diff --git a/crates/proto/src/generated/requests.rs b/crates/proto/src/generated/requests.rs index 4250a49dd..b912e0442 100644 --- a/crates/proto/src/generated/requests.rs +++ b/crates/proto/src/generated/requests.rs @@ -1,12 +1,10 @@ // This file is @generated by prost-build. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ApplyBlockRequest { #[prost(bytes = "vec", tag = "1")] pub block: ::prost::alloc::vec::Vec, } /// Returns a list of nullifiers that match the specified prefixes and are recorded in the node. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CheckNullifiersByPrefixRequest { /// Number of bits used for nullifier prefix. Currently the only supported value is 16. @@ -17,7 +15,6 @@ pub struct CheckNullifiersByPrefixRequest { #[prost(uint32, repeated, tag = "2")] pub nullifiers: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CheckNullifiersRequest { #[prost(message, repeated, tag = "1")] @@ -27,7 +24,6 @@ pub struct CheckNullifiersRequest { /// path and current forest which validate the block's inclusion in the chain. /// /// The Merkle path is an MMR proof for the block's leaf, based on the current chain length. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetBlockHeaderByNumberRequest { /// The block number of the target block. @@ -44,7 +40,6 @@ pub struct GetBlockHeaderByNumberRequest { /// Specifies state updates the client is intersted in. The server will return the first block which /// contains a note matching `note_tags` or the chain tip. And the corresponding updates to /// `nullifiers` and `account_ids` for that block range. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SyncStateRequest { /// Last block known by the client. The response will contain data starting from the next block, @@ -71,7 +66,6 @@ pub struct SyncStateRequest { /// /// Specifies note tags that client is intersted in. The server will return the first block which /// contains a note matching `note_tags` or the chain tip. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SyncNoteRequest { /// Last block known by the client. The response will contain data starting from the next block, @@ -82,7 +76,6 @@ pub struct SyncNoteRequest { #[prost(fixed32, repeated, tag = "2")] pub note_tags: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetBlockInputsRequest { /// ID of the account against which a transaction is executed. @@ -95,7 +88,6 @@ pub struct GetBlockInputsRequest { #[prost(message, repeated, tag = "3")] pub unauthenticated_notes: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetTransactionInputsRequest { #[prost(message, optional, tag = "1")] @@ -105,45 +97,37 @@ pub struct GetTransactionInputsRequest { #[prost(message, repeated, tag = "3")] pub unauthenticated_notes: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SubmitProvenTransactionRequest { /// Transaction encoded using miden's native format #[prost(bytes = "vec", tag = "1")] pub transaction: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetNotesByIdRequest { /// List of NoteId's to be queried from the database #[prost(message, repeated, tag = "1")] pub note_ids: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetNoteAuthenticationInfoRequest { /// List of NoteId's to be queried from the database #[prost(message, repeated, tag = "1")] pub note_ids: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct ListNullifiersRequest {} -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct ListAccountsRequest {} -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct ListNotesRequest {} /// Returns the latest state of an account with the specified ID. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetAccountDetailsRequest { /// Account ID to get details. #[prost(message, optional, tag = "1")] pub account_id: ::core::option::Option, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetBlockByNumberRequest { /// The block number of the target block. @@ -152,7 +136,6 @@ pub struct GetBlockByNumberRequest { } /// Returns delta of the account states in the range from `from_block_num` (exclusive) to /// `to_block_num` (inclusive). -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetAccountStateDeltaRequest { /// ID of the account for which the delta is requested. diff --git a/crates/proto/src/generated/responses.rs b/crates/proto/src/generated/responses.rs index 02b456e7f..7afa7c899 100644 --- a/crates/proto/src/generated/responses.rs +++ b/crates/proto/src/generated/responses.rs @@ -1,22 +1,18 @@ // This file is @generated by prost-build. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct ApplyBlockResponse {} -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CheckNullifiersResponse { /// Each requested nullifier has its corresponding nullifier proof at the same position. #[prost(message, repeated, tag = "1")] pub proofs: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CheckNullifiersByPrefixResponse { /// List of nullifiers matching the prefixes specified in the request. #[prost(message, repeated, tag = "1")] pub nullifiers: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetBlockHeaderByNumberResponse { /// The requested block header @@ -29,7 +25,6 @@ pub struct GetBlockHeaderByNumberResponse { #[prost(fixed32, optional, tag = "3")] pub chain_length: ::core::option::Option, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct NullifierUpdate { #[prost(message, optional, tag = "1")] @@ -37,7 +32,6 @@ pub struct NullifierUpdate { #[prost(fixed32, tag = "2")] pub block_num: u32, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SyncStateResponse { /// Number of the latest block in the chain @@ -63,7 +57,6 @@ pub struct SyncStateResponse { #[prost(message, repeated, tag = "8")] pub nullifiers: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SyncNoteResponse { /// Number of the latest block in the chain @@ -83,7 +76,6 @@ pub struct SyncNoteResponse { pub notes: ::prost::alloc::vec::Vec, } /// An account returned as a response to the GetBlockInputs -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AccountBlockInputRecord { #[prost(message, optional, tag = "1")] @@ -94,7 +86,6 @@ pub struct AccountBlockInputRecord { pub proof: ::core::option::Option, } /// A nullifier returned as a response to the GetBlockInputs -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct NullifierBlockInputRecord { #[prost(message, optional, tag = "1")] @@ -102,7 +93,6 @@ pub struct NullifierBlockInputRecord { #[prost(message, optional, tag = "2")] pub opening: ::core::option::Option, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetBlockInputsResponse { /// The latest block header @@ -124,7 +114,6 @@ pub struct GetBlockInputsResponse { >, } /// An account returned as a response to the GetTransactionInputs -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct AccountTransactionInputRecord { #[prost(message, optional, tag = "1")] @@ -134,7 +123,6 @@ pub struct AccountTransactionInputRecord { pub account_hash: ::core::option::Option, } /// A nullifier returned as a response to the GetTransactionInputs -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct NullifierTransactionInputRecord { #[prost(message, optional, tag = "1")] @@ -143,7 +131,6 @@ pub struct NullifierTransactionInputRecord { #[prost(fixed32, tag = "2")] pub block_num: u32, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetTransactionInputsResponse { #[prost(message, optional, tag = "1")] @@ -155,62 +142,53 @@ pub struct GetTransactionInputsResponse { #[prost(fixed32, tag = "4")] pub block_height: u32, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct SubmitProvenTransactionResponse { /// The node's current block height #[prost(fixed32, tag = "1")] pub block_height: u32, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetNotesByIdResponse { /// Lists Note's returned by the database #[prost(message, repeated, tag = "1")] pub notes: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetNoteAuthenticationInfoResponse { #[prost(message, optional, tag = "1")] pub proofs: ::core::option::Option, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListNullifiersResponse { /// Lists all nullifiers of the current chain #[prost(message, repeated, tag = "1")] pub nullifiers: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListAccountsResponse { /// Lists all accounts of the current chain #[prost(message, repeated, tag = "1")] pub accounts: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListNotesResponse { /// Lists all notes of the current chain #[prost(message, repeated, tag = "1")] pub notes: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetAccountDetailsResponse { - /// Account info (with details for on-chain accounts) + /// Account info (with details for public accounts) #[prost(message, optional, tag = "1")] pub details: ::core::option::Option, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetBlockByNumberResponse { /// The requested `Block` data encoded using miden native format #[prost(bytes = "vec", optional, tag = "1")] pub block: ::core::option::Option<::prost::alloc::vec::Vec>, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetAccountStateDeltaResponse { /// The calculated `AccountStateDelta` encoded using miden native format diff --git a/crates/proto/src/generated/smt.rs b/crates/proto/src/generated/smt.rs index 552ce9e32..c4aaf2d77 100644 --- a/crates/proto/src/generated/smt.rs +++ b/crates/proto/src/generated/smt.rs @@ -1,6 +1,5 @@ // This file is @generated by prost-build. /// An entry in a leaf. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct SmtLeafEntry { #[prost(message, optional, tag = "1")] @@ -8,14 +7,12 @@ pub struct SmtLeafEntry { #[prost(message, optional, tag = "2")] pub value: ::core::option::Option, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SmtLeafEntries { #[prost(message, repeated, tag = "1")] pub entries: ::prost::alloc::vec::Vec, } /// A leaf in an SMT, sitting at depth 64. A leaf can contain 0, 1 or multiple leaf entries. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SmtLeaf { #[prost(oneof = "smt_leaf::Leaf", tags = "1, 2, 3")] @@ -23,7 +20,6 @@ pub struct SmtLeaf { } /// Nested message and enum types in `SmtLeaf`. pub mod smt_leaf { - #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Leaf { #[prost(uint64, tag = "1")] @@ -35,7 +31,6 @@ pub mod smt_leaf { } } /// The opening of a leaf in an SMT. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SmtOpening { #[prost(message, optional, tag = "1")] diff --git a/crates/proto/src/generated/transaction.rs b/crates/proto/src/generated/transaction.rs index 443f71d35..ca77a09b3 100644 --- a/crates/proto/src/generated/transaction.rs +++ b/crates/proto/src/generated/transaction.rs @@ -1,11 +1,9 @@ // This file is @generated by prost-build. -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct TransactionId { #[prost(message, optional, tag = "1")] pub id: ::core::option::Option, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct TransactionSummary { #[prost(message, optional, tag = "1")] diff --git a/crates/rpc-proto/proto/note.proto b/crates/rpc-proto/proto/note.proto index 24d7579a2..d424f696b 100644 --- a/crates/rpc-proto/proto/note.proto +++ b/crates/rpc-proto/proto/note.proto @@ -20,7 +20,7 @@ message Note { digest.Digest note_id = 3; NoteMetadata metadata = 4; merkle.MerklePath merkle_path = 5; - // This field will be present when the note is on-chain. + // This field will be present when the note is public. // details contain the `Note` in a serialized format. optional bytes details = 6; } diff --git a/crates/rpc-proto/proto/responses.proto b/crates/rpc-proto/proto/responses.proto index a64d643d9..7342294ff 100644 --- a/crates/rpc-proto/proto/responses.proto +++ b/crates/rpc-proto/proto/responses.proto @@ -160,7 +160,7 @@ message ListNotesResponse { } message GetAccountDetailsResponse { - // Account info (with details for on-chain accounts) + // Account info (with details for public accounts) account.AccountInfo details = 1; } diff --git a/crates/rpc/src/server/api.rs b/crates/rpc/src/server/api.rs index acf8e0d9f..4ee3ed578 100644 --- a/crates/rpc/src/server/api.rs +++ b/crates/rpc/src/server/api.rs @@ -190,7 +190,7 @@ impl api_server::Api for RpcApi { self.block_producer.clone().submit_proven_transaction(request).await } - /// Returns details for public (on-chain) account by id. + /// Returns details for public (public) account by id. #[instrument( target = "miden-rpc", name = "rpc:get_account_details", diff --git a/crates/store/src/errors.rs b/crates/store/src/errors.rs index f2aca5c15..2736cb563 100644 --- a/crates/store/src/errors.rs +++ b/crates/store/src/errors.rs @@ -68,7 +68,7 @@ pub enum DatabaseError { AccountNotFoundInDb(AccountId), #[error("Account {0} is not on the chain")] AccountNotOnChain(AccountId), - #[error("Failed to apply block because of on-chain account final hashes mismatch (expected {expected}, \ + #[error("Failed to apply block because of public account final hashes mismatch (expected {expected}, \ but calculated is {calculated}")] ApplyBlockFailedAccountHashesMismatch { expected: RpoDigest, diff --git a/crates/store/src/genesis.rs b/crates/store/src/genesis.rs index 0f8e9c361..8052c5cdc 100644 --- a/crates/store/src/genesis.rs +++ b/crates/store/src/genesis.rs @@ -31,7 +31,7 @@ impl GenesisState { .accounts .iter() .map(|account| { - let account_update_details = if account.id().is_on_chain() { + let account_update_details = if account.id().is_public() { AccountUpdateDetails::New(account.clone()) } else { AccountUpdateDetails::Private diff --git a/crates/store/src/server/api.rs b/crates/store/src/server/api.rs index eff120592..47b5922f3 100644 --- a/crates/store/src/server/api.rs +++ b/crates/store/src/server/api.rs @@ -313,7 +313,7 @@ impl api_server::Api for StoreApi { })) } - /// Returns details for public (on-chain) account by id. + /// Returns details for public (public) account by id. #[instrument( target = "miden-store", name = "store:get_account_details", diff --git a/crates/store/src/state.rs b/crates/store/src/state.rs index f20dd9dec..b36e1884a 100644 --- a/crates/store/src/state.rs +++ b/crates/store/src/state.rs @@ -669,7 +669,7 @@ impl State { self.db.select_notes().await } - /// Returns details for public (on-chain) account. + /// Returns details for public (public) account. pub async fn get_account_details(&self, id: AccountId) -> Result { self.db.select_account(id).await } diff --git a/proto/note.proto b/proto/note.proto index 24d7579a2..d424f696b 100644 --- a/proto/note.proto +++ b/proto/note.proto @@ -20,7 +20,7 @@ message Note { digest.Digest note_id = 3; NoteMetadata metadata = 4; merkle.MerklePath merkle_path = 5; - // This field will be present when the note is on-chain. + // This field will be present when the note is public. // details contain the `Note` in a serialized format. optional bytes details = 6; } diff --git a/proto/responses.proto b/proto/responses.proto index a64d643d9..7342294ff 100644 --- a/proto/responses.proto +++ b/proto/responses.proto @@ -160,7 +160,7 @@ message ListNotesResponse { } message GetAccountDetailsResponse { - // Account info (with details for on-chain accounts) + // Account info (with details for public accounts) account.AccountInfo details = 1; } From 2540ae9f0bc702f5348784029ba9d74a6dc791ab Mon Sep 17 00:00:00 2001 From: Saurabh Shrihar <121215809+sshrihar@users.noreply.github.com> Date: Wed, 11 Sep 2024 14:09:26 +0400 Subject: [PATCH 08/37] ci: update deployment and packaging (#482) - builds packages - packages are deployed via S3 --- .github/actions/ssm_execute/action.yml | 77 ++++++++ .github/workflows/amd_deb_packager.yml | 1 - .github/workflows/arm_deb_packager.yml | 71 ++++++- .github/workflows/deploy.yml | 149 --------------- .github/workflows/deploy_devnet.yml | 21 --- .github/workflows/deploy_package.yml | 136 +++++++++++++ .github/workflows/deploy_testnet.yml | 22 --- .github/workflows/deploy_workflow.yml | 252 ------------------------- README.md | 6 +- bin/node/Dockerfile | 2 +- 10 files changed, 282 insertions(+), 455 deletions(-) create mode 100644 .github/actions/ssm_execute/action.yml delete mode 100644 .github/workflows/deploy.yml delete mode 100644 .github/workflows/deploy_devnet.yml create mode 100644 .github/workflows/deploy_package.yml delete mode 100644 .github/workflows/deploy_testnet.yml delete mode 100644 .github/workflows/deploy_workflow.yml diff --git a/.github/actions/ssm_execute/action.yml b/.github/actions/ssm_execute/action.yml new file mode 100644 index 000000000..933fee59c --- /dev/null +++ b/.github/actions/ssm_execute/action.yml @@ -0,0 +1,77 @@ +name: 'execute_ec2' +description: 'Execute commands on EC2 instance' +inputs: + instance_id: + required: true + description: "Instance ID to execute ssm commands on" + command: + required: true + description: "Set of commands to execute on the instance" + check_timeout: + default: "10" + description: "Timeout to check for output. After n seconds the output is printed from shell." + total_timeout: + description: "Total timeout for the command execution" + default: "1800" + +outputs: + cmd_result: + description: "Output from executed command" + value: ${{ steps.poll_output.outputs.cmd_result }} + +runs: + using: "composite" + steps: + - name: Execute_Command + id: execute_cmd + shell: bash + run: | + formatted_command=$(echo "${{ inputs.command }}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/\n/ && /g') + echo "Executing command: $formatted_command" + COMMAND_ID=$(aws ssm send-command \ + --instance-ids ${{ inputs.instance_id }} \ + --document-name "AWS-RunShellScript" \ + --parameters '{"commands":["'"$formatted_command"'"]}' \ + --output text \ + --query "Command.CommandId") + echo "command_id=$COMMAND_ID" >> $GITHUB_OUTPUT + continue-on-error: true + + - name: Poll command status and retrieve live logs + id: poll_output + shell: bash + run: | + start_time=$(date +%s) + timeout=${{ inputs.total_timeout }} + + while true; do + STATUS=$(aws ssm list-command-invocations \ + --command-id ${{ steps.execute_cmd.outputs.command_id }} \ + --details \ + --query "CommandInvocations[0].Status" \ + --output text) + echo "Command Status: $STATUS" + + OUTPUT=$(aws ssm list-command-invocations \ + --command-id ${{ steps.execute_cmd.outputs.command_id }} \ + --details \ + --query "CommandInvocations[0].CommandPlugins[0].Output" \ + --output text) + echo "Command Output: $OUTPUT" + + if [ "$STATUS" == "Success" ]; then + echo "Command completed successfully." + break + elif [ "$STATUS" == "Failed" ] || [ "$STATUS" == "Cancelled" ]; then + echo "Command failed with status: $STATUS" + break + else + elapsed_time=$(( $(date +%s) - start_time )) + if [ "$elapsed_time" -gt "$timeout" ]; then + echo "Timeout reached. Command execution took more than $timeout seconds." + exit 1 + fi + sleep ${{ inputs.check_timeout }} + fi + done + echo "cmd_result=$(echo $OUTPUT)" >> $GITHUB_OUTPUT diff --git a/.github/workflows/amd_deb_packager.yml b/.github/workflows/amd_deb_packager.yml index da07558ec..ea290aebe 100644 --- a/.github/workflows/amd_deb_packager.yml +++ b/.github/workflows/amd_deb_packager.yml @@ -112,7 +112,6 @@ jobs: env: ARCH: amd64 - - name: shasum the package run: cd packaging/deb/ && sha256sum miden-node-${{ env.GIT_TAG }}-${{ env.ARCH }}.deb > miden-node-${{ env.GIT_TAG }}-${{ env.ARCH }}.deb.checksum env: diff --git a/.github/workflows/arm_deb_packager.yml b/.github/workflows/arm_deb_packager.yml index d4e0620cb..9f38c4037 100644 --- a/.github/workflows/arm_deb_packager.yml +++ b/.github/workflows/arm_deb_packager.yml @@ -4,12 +4,20 @@ on: workflow_dispatch: release: types: [released, prereleased] + push: + branches: + - next jobs: - build: + build_package: permissions: id-token: write contents: write + outputs: + target: ${{ steps.build_type_vars_setup.outputs.target }} + tag: ${{ steps.build_type_vars_setup.outputs.tag }} + account_id: ${{ steps.build_type_vars_setup.outputs.account_id }} + instance_id: ${{ steps.build_type_vars_setup.outputs.instance_id }} runs-on: labels: ubuntu22-arm-4core steps: @@ -17,13 +25,23 @@ jobs: uses: actions/checkout@main with: fetch-depth: 0 - ##### TAG Variable ##### + - name: Adding TAG to ENV - run: echo "GIT_TAG=`echo $(git describe --tags --abbrev=0)`" >> $GITHUB_ENV + run: | + if [[ ${{ github.event_name }} == "release" || ${{ github.event_name }} == "prereleased" ]]; then + echo "GIT_TAG=`echo $(git describe --tags --abbrev=0)`" >> $GITHUB_ENV + else + echo "GIT_TAG=next" >> $GITHUB_ENV + fi + - name: adding version run: | - NUMERIC_VERSION=$( echo ${{ env.GIT_TAG }} | sed 's/[^0-9.]//g' ) - echo "VERSION=$NUMERIC_VERSION" >> $GITHUB_ENV + if [[ ${{ github.event_name }} == "release" || ${{ github.event_name }} == "prereleased" ]]; then + NUMERIC_VERSION=$( echo ${{ env.GIT_TAG }} | sed 's/[^0-9.]//g' ) + echo "VERSION=$NUMERIC_VERSION" >> $GITHUB_ENV + else + echo "VERSION=0.1" >> $GITHUB_ENV + fi - name: cleaning repo run: cargo clean @@ -124,7 +142,7 @@ jobs: env: ARCH: arm64 - - name: release miden-node Packages + - name: release miden-node Packages for testnet uses: softprops/action-gh-release@v1 with: tag_name: ${{ env.GIT_TAG }} @@ -134,3 +152,44 @@ jobs: packaging/deb/miden-node**.deb.checksum packaging/deb/miden-faucet**.deb packaging/deb/miden-faucet**.deb.checksum + if: ${{ github.event_name == 'release' || github.event_name == 'prereleased' }} + + - name: release miden-node Packages for devnet + uses: actions/upload-artifact@v3 + with: + name: devnet_package + path: | + packaging/deb/miden-node-${{ env.GIT_TAG }}-${{ env.ARCH }}.deb + packaging/deb/miden-node-${{ env.GIT_TAG }}-${{ env.ARCH }}.deb.checksum + packaging/deb/miden-faucet-${{ env.GIT_TAG }}-${{ env.ARCH }}.deb + packaging/deb/miden-faucet-${{ env.GIT_TAG }}-${{ env.ARCH }}.deb.checksum + env: + ARCH: arm64 + if: ${{ github.event_name == 'push' }} + + - name: Determine build type + id: build_type_vars_setup + run: | + if [[ ${{ github.event_name }} == "release" || ${{ github.event_name }} == "prereleased" ]]; then + echo "target=testnet" >> $GITHUB_OUTPUT + echo "tag=${{ env.GIT_TAG }}" >> $GITHUB_OUTPUT + echo "account_id=MIDEN_DEV_ACCOUNT_ID" >> $GITHUB_OUTPUT + echo "instance_id=TESTNET_INSTANCE_TF" >> $GITHUB_OUTPUT + else + echo "target=devnet" >> $GITHUB_OUTPUT + echo "tag=next" >> $GITHUB_OUTPUT + echo "account_id=MIDEN_DEV_ACCOUNT_ID" >> $GITHUB_OUTPUT + echo "instance_id=DEVNET_INSTANCE_TF" >> $GITHUB_OUTPUT + fi + + + deploy: + name: Deploy to ${{ needs.build_package.outputs.target }} + needs: build_package + uses: ./.github/workflows/deploy_package.yml + with: + target: ${{ needs.build_package.outputs.target }} + tag: ${{ needs.build_package.outputs.tag }} + account_id: ${{ needs.build_package.outputs.account_id }} + instance_id: ${{ needs.build_package.outputs.instance_id }} + secrets: inherit diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index e4b5b4a45..000000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,149 +0,0 @@ -# Deploy the miden node for testnet and devnet. -# -# testnet is deployed manually using `workflow_dispatch`, and devnet is deployed -# on every push to the `next` branch. -# -# All previous node data is removed during deployment i.e. an update restarts the -# node from genesis again. -name: Node deployment - -on: - workflow_dispatch: - inputs: - network: - required: true - default: 'devnet' - type: choice - options: - - devnet - - testnet - -permissions: - id-token: write - contents: read - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - # Configure the `NETWORK` env variable based on the trigger type. - # - # This is then used by subsequent steps to switch on devnet | testnet, - # instead of switching on trigger type which is less readible. - - name: Configure for testnet - if: ${{ inputs.network == 'testnet' }} - env: - INSTANCE_ID: ${{ secrets.TESTNET_INSTANCE_ID }} - run: | - echo "NETWORK=testnet" >> $GITHUB_ENV - echo "INSTANCE_ID=$INSTANCE_ID" >> $GITHUB_ENV - - - name: Configure for devnet - if: ${{ inputs.network == 'devnet' }} - env: - INSTANCE_ID: ${{ secrets.DEVNET_INSTANCE_ID }} - run: | - echo "NETWORK=devnet" >> $GITHUB_ENV - echo "INSTANCE_ID=$INSTANCE_ID" >> $GITHUB_ENV - - # Configure AWS credentials based on network. - - name: Configure testnet AWS credentials - if: env.NETWORK == 'testnet' - uses: aws-actions/configure-aws-credentials@v1 - with: - role-to-assume: arn:aws:iam::211125515935:role/Miden-GithubActionsRole - aws-region: us-west-1 - - - name: Configure devnet AWS credentials - if: env.NETWORK == 'devnet' - uses: aws-actions/configure-aws-credentials@v1 - with: - role-to-assume: arn:aws:iam::657556092833:role/Miden-GithubActionsRole - aws-region: us-west-1 - - - name: Stop services - run: | - aws ssm send-command \ - --instance-ids ${{ env.INSTANCE_ID }} \ - --document-name "AWS-RunShellScript" \ - --comment "Stop Miden services" \ - --parameters commands='[ - "sudo systemctl stop miden-node", - "sudo systemctl stop miden-faucet" - ]' \ - --output text - - - name: Install prerequisites - run: | - aws ssm send-command \ - --instance-ids ${{ env.INSTANCE_ID }} \ - --document-name "AWS-RunShellScript" \ - --comment "Install prerequisites" \ - --parameters commands='[ - "sudo yum update -y", - "sudo yum install -y git gcc openssl-devel bzip2-devel libffi-devel make", - "sudo yum groupinstall -y \"Development Tools\"", - "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y", - "source $HOME/.cargo/env", - "rustup update", - "sudo yum install -y clang cmake" - ]' \ - --output text - - - name: Install testnet - if: env.NETWORK == 'testnet' - run: | - aws ssm send-command \ - --instance-ids ${{ env.INSTANCE_ID }} \ - --document-name "AWS-RunShellScript" \ - --comment "Install Miden on testnet" \ - --parameters commands='[ - "cargo install miden-node miden-faucet --locked --features testing" - ]' \ - --output text - - - name: Install devnet - if: env.NETWORK == 'devnet' - run: | - aws ssm send-command \ - --instance-ids ${{ env.INSTANCE_ID }} \ - --document-name "AWS-RunShellScript" \ - --comment "Install Miden on devnet" \ - --parameters commands='[ - "cargo install --git https://github.com/0xPolygonMiden/miden-node miden-node --branch next --bin miden-node --locked --features testing", - "cargo install --git https://github.com/0xPolygonMiden/miden-node miden-faucet --branch next --bin miden-faucet --locked --features testing" - ]' \ - --output text - - - name: Configure - run: | - aws ssm send-command \ - --instance-ids ${{ env.INSTANCE_ID }} \ - --document-name "AWS-RunShellScript" \ - --comment "Configure Miden services" \ - --parameters commands='[ - "rm -rf ~/miden-node; mkdir ~/miden-node", - "rm -rf ~/miden-faucet; mkdir ~/miden-faucet", - "miden-node init -c ~/miden-node/miden-node.toml -g ~/miden-node/genesis.toml", - "miden-node make-genesis -i ~/miden-node/genesis.toml -o ~/miden-node/genesis.dat", - "miden-faucet init -c ~/miden-faucet/miden-faucet.toml", - "cat > /etc/systemd/system/miden-node.service << 'END_OF_CAT' ... END_OF_CAT", - "cat > /etc/systemd/system/miden-facuet.service << 'END_OF_CAT' ... END_OF_CAT" - ]' \ - --output text - - - name: Start services - run: | - aws ssm send-command \ - --instance-ids ${{ env.INSTANCE_ID }} \ - --document-name "AWS-RunShellScript" \ - --comment "Start Miden services" \ - --parameters commands='[ - "sudo systemctl daemon-reload", - "sudo systemctl enable miden-node", - "sudo systemctl enable miden-faucet", - "sudo systemctl start miden-node", - "sleep 5", - "sudo systemctl start miden-faucet" - ]' \ - --output text diff --git a/.github/workflows/deploy_devnet.yml b/.github/workflows/deploy_devnet.yml deleted file mode 100644 index ae12722a2..000000000 --- a/.github/workflows/deploy_devnet.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: devnet deploy - -on: - push: - branches: - - next - workflow_dispatch: - -permissions: - id-token: write - contents: write - -jobs: - deploy: - name: Deploy to testnet - uses: ./.github/workflows/deploy_workflow.yml - with: - build_prefix: --branch next - secrets: - account_id: "${{ secrets.MIDEN_DEV_ACCOUNT_ID }}" - instance_id: "${{ secrets.DEVNET_INSTANCE_ID }}" diff --git a/.github/workflows/deploy_package.yml b/.github/workflows/deploy_package.yml new file mode 100644 index 000000000..53530896b --- /dev/null +++ b/.github/workflows/deploy_package.yml @@ -0,0 +1,136 @@ +on: + workflow_call: + inputs: + target: + type: string + default: "devnet" + tag: + type: string + default: "next" + oidcrole: + type: string + default: midendev + account_id: + type: string + instance_id: + type: string + +permissions: + id-token: write + contents: write + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: eu-west-1 + role-to-assume: "arn:aws:iam::${{ secrets[inputs.account_id] }}:role/${{ inputs.oidcrole }}-GithubActionsRole" + role-session-name: GithubActionsSession + + - name: Checkout Code Repository for reusable action + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Install awscli + uses: ./.github/actions/ssm_execute + with: + instance_id: ${{ secrets[inputs.instance_id] }} + command: | + sudo apt udpate; \ + sudo apt install awscli -y + if: ${{ inputs.target == 'devnet' }} + + - name: Execute Architecture for instance + id: get_arch + uses: ./.github/actions/ssm_execute + with: + instance_id: ${{ secrets[inputs.instance_id] }} + command: | + uname -m + + - name: Determine architecture + run: | + if [[ "${{ steps.get_arch.outputs.cmd_result }}" =~ ^x86 ]]; then + echo "package_postfix=amd64.deb" >> $GITHUB_ENV + else + echo "package_postfix=arm64.deb" >> $GITHUB_ENV + fi + + - name: Stop miden services + uses: ./.github/actions/ssm_execute + with: + instance_id: ${{ secrets[inputs.instance_id] }} + command: | + sudo systemctl stop miden-node; sudo systemctl stop miden-faucet; sudo apt remove miden-node miden-faucet -y; sudo rm -f miden-* + + - name: Package download testnet + uses: ./.github/actions/ssm_execute + with: + instance_id: ${{ secrets[inputs.instance_id] }} + command: | + wget https://github.com/0xPolygonMiden/miden-node/releases/download/${{ inputs.tag }}/miden-faucet-${{ inputs.tag }}-${{ env.package_postfix }}; \ + wget https://github.com/0xPolygonMiden/miden-node/releases/download/${{ inputs.tag }}/miden-node-${{ inputs.tag }}-${{ env.package_postfix }} + if: ${{ inputs.target == 'testnet' }} + + - name: Download package to github runner + uses: actions/download-artifact@v3 + with: + name: devnet_package + if: ${{ inputs.target == 'devnet' }} + + - name: Upload packages to S3 + run: | + # Copy miden-node package to S3 + aws s3 cp ${{ runner.workspace }}/miden-node/miden-node-${{ inputs.tag }}-${{ env.package_postfix }} \ + s3://release-artifacts-${{ secrets[inputs.account_id] }}/miden-node-${{ inputs.tag }}-${{ env.package_postfix }} + # Copy miden-faucet package to S3 + aws s3 cp ${{ runner.workspace }}/miden-node/miden-faucet-${{ inputs.tag }}-${{ env.package_postfix }} \ + s3://release-artifacts-${{ secrets[inputs.account_id] }}/miden-faucet-${{ inputs.tag }}-${{ env.package_postfix }} + if: ${{ inputs.target == 'devnet' }} + + - name: Download package to devnet + uses: ./.github/actions/ssm_execute + with: + instance_id: ${{ secrets[inputs.instance_id] }} + command: | + aws s3 cp s3://release-artifacts-${{ secrets[inputs.account_id] }}/miden-node-${{ inputs.tag }}-${{ env.package_postfix }} miden-node-${{ inputs.tag }}-${{ env.package_postfix }}; \ + aws s3 cp s3://release-artifacts-${{ secrets[inputs.account_id] }}/miden-faucet-${{ inputs.tag }}-${{ env.package_postfix }} miden-faucet-${{ inputs.tag }}-${{ env.package_postfix }} + if: ${{ inputs.target == 'devnet' }} + + - name: Package install on ${{ inputs.target }} + uses: ./.github/actions/ssm_execute + with: + instance_id: ${{ secrets[inputs.instance_id] }} + command: | + dpkg -i miden-node-${{ inputs.tag }}-${{ env.package_postfix }}; \ + dpkg -i miden-faucet-${{ inputs.tag }}-${{ env.package_postfix }} + + - name: Configure environment + uses: ./.github/actions/ssm_execute + with: + instance_id: ${{ secrets[inputs.instance_id] }} + command: | + sudo chown -R miden /opt/miden; \ + sudo /usr/bin/miden-node init -c /etc/miden/miden-node.toml -g /opt/miden/miden-node/genesis.toml; \ + sudo /usr/bin/miden-node make-genesis -i /opt/miden/miden-node/genesis.toml -o /opt/miden/miden-node/genesis.dat --force; \ + sudo /usr/bin/miden-faucet init -c /opt/miden/miden-faucet/miden-faucet.toml + + - name: Start miden node service + uses: ./.github/actions/ssm_execute + with: + instance_id: ${{ secrets[inputs.instance_id] }} + command: | + sudo systemctl daemon-reload; \ + sudo systemctl start miden-node + + - name: Start miden faucet service + uses: ./.github/actions/ssm_execute + with: + instance_id: ${{ secrets[inputs.instance_id] }} + command: | + sudo systemctl daemon-reload; \ + sudo systemctl start miden-faucet diff --git a/.github/workflows/deploy_testnet.yml b/.github/workflows/deploy_testnet.yml deleted file mode 100644 index 482a55b16..000000000 --- a/.github/workflows/deploy_testnet.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: testnet deploy - -on: - workflow_dispatch: - inputs: - release_id: - description: The tag of the release to trigger the workflow - required: true - -permissions: - id-token: write - contents: write - -jobs: - deploy: - name: Deploy to testnet - uses: ./.github/workflows/deploy_workflow.yml - with: - build_prefix: "--tag ${{ inputs.release_id }}" - secrets: - account_id: "${{ secrets.MIDEN_DEV_ACCOUNT_ID }}" - instance_id: "${{ secrets.TESTNET_INSTANCE_ID }}" diff --git a/.github/workflows/deploy_workflow.yml b/.github/workflows/deploy_workflow.yml deleted file mode 100644 index 387f912cf..000000000 --- a/.github/workflows/deploy_workflow.yml +++ /dev/null @@ -1,252 +0,0 @@ -on: - workflow_call: - inputs: - build_prefix: - type: string - features: - type: string - default: "testing" - secrets: - account_id: - required: true - instance_id: - required: true - -permissions: - id-token: write - contents: write - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: eu-west-1 - role-to-assume: arn:aws:iam::${{ secrets.account_id }}:role/midendev-GithubActionsRole - role-session-name: GithubActionsSession - - - name: Stop services - id: stop_services - run: | - COMMAND_ID=$(aws ssm send-command \ - --instance-ids ${{ secrets.instance_id }} \ - --document-name "AWS-RunShellScript" \ - --parameters '{"commands":["sudo systemctl stop miden-node", "sudo systemctl stop miden-faucet"]}' \ - --output text \ - --query "Command.CommandId") - echo "command_id=$COMMAND_ID" >> $GITHUB_OUTPUT - - - name: Check stop services command status and retrieve output - run: | - while true; do - STATUS=$(aws ssm list-command-invocations \ - --command-id ${{ steps.stop_services.outputs.command_id }} \ - --details \ - --query "CommandInvocations[0].Status" \ - --output text) - echo "Command Status: $STATUS" - - OUTPUT=$(aws ssm list-command-invocations \ - --command-id ${{ steps.stop_services.outputs.command_id }} \ - --details \ - --query "CommandInvocations[0].CommandPlugins[0].Output" \ - --output text) - echo "Command Output: $OUTPUT" - - if [ "$STATUS" == "Success" ]; then - echo "Command completed successfully." - break - elif [ "$STATUS" == "Failed" ] || [ "$STATUS" == "Cancelled" ]; then - echo "Command failed with status: $STATUS" - exit 1 - else - sleep 10 # Wait for 30 seconds before checking again - fi - done - - - name: Install prerequisites - id: install_prereq - run: | - COMMAND_ID=$(aws ssm send-command \ - --instance-ids ${{ secrets.instance_id }} \ - --document-name "AWS-RunShellScript" \ - --parameters '{"commands":[ - "sudo apt-get update -y", - "sudo apt-get install -y git gcc openssl libbz2-dev libffi7 make", - "sudo apt install -y build-essential", - "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y", - "source $HOME/.cargo/env", - "rustup update", - "sudo apt-get install -y clang cmake", - "sudo rm -rf /opt/miden/miden-node", - "sudo mkdir /opt/miden/miden-node" - ]}' \ - --output text \ - --query "Command.CommandId") - echo "command_id=$COMMAND_ID" >> $GITHUB_OUTPUT - - - name: Poll command status and retrieve live logs from install prereqs - run: | - while true; do - STATUS=$(aws ssm list-command-invocations \ - --command-id ${{ steps.install_prereq.outputs.command_id }} \ - --details \ - --query "CommandInvocations[0].Status" \ - --output text) - echo "Command Status: $STATUS" - - OUTPUT=$(aws ssm list-command-invocations \ - --command-id ${{ steps.install_prereq.outputs.command_id }} \ - --details \ - --query "CommandInvocations[0].CommandPlugins[0].Output" \ - --output text) - echo "Command Output: $OUTPUT" - - if [ "$STATUS" == "Success" ]; then - echo "Command completed successfully." - break - elif [ "$STATUS" == "Failed" ] || [ "$STATUS" == "Cancelled" ]; then - echo "Command failed with status: $STATUS" - exit 1 - else - sleep 10 # Wait for 30 seconds before checking again - fi - done - - - name: Cargo Install - id: cargo_install - run: | - COMMAND_ID=$(aws ssm send-command \ - --instance-ids ${{ secrets.instance_id }} \ - --document-name "AWS-RunShellScript" \ - --parameters '{"commands":[ - "/home/ssm-user/.cargo/bin/cargo install --git https://github.com/0xPolygonMiden/miden-node miden-node ${{ inputs.build_prefix }} --bin miden-node --locked --features ${{ inputs.features }}", - "/home/ssm-user/.cargo/bin/cargo install --git https://github.com/0xPolygonMiden/miden-node miden-faucet ${{ inputs.build_prefix }} --bin miden-faucet --locked --features ${{ inputs.features }}" - ]}' \ - --output text \ - --query "Command.CommandId") - echo "command_id=$COMMAND_ID" >> $GITHUB_OUTPUT - - - name: Poll command status and retrieve live logs - run: | - while true; do - STATUS=$(aws ssm list-command-invocations \ - --command-id ${{ steps.cargo_install.outputs.command_id }} \ - --details \ - --query "CommandInvocations[0].Status" \ - --output text) - echo "Command Status: $STATUS" - - OUTPUT=$(aws ssm list-command-invocations \ - --command-id ${{ steps.cargo_install.outputs.command_id }} \ - --details \ - --query "CommandInvocations[0].CommandPlugins[0].Output" \ - --output text) - echo "Command Output: $OUTPUT" - - if [ "$STATUS" == "Success" ]; then - echo "Command completed successfully." - break - elif [ "$STATUS" == "Failed" ] || [ "$STATUS" == "Cancelled" ]; then - echo "Command failed with status: $STATUS" - exit 1 - else - sleep 60 - fi - done - - - name: Configure environment - id: configure_environment - run: | - COMMAND_ID=$(aws ssm send-command \ - --instance-ids ${{ secrets.instance_id }} \ - --document-name "AWS-RunShellScript" \ - --parameters '{"commands":[ - "sudo cp -rp /root/.cargo/bin/miden-node /usr/bin/miden-node && sudo chmod a+x /usr/bin/miden-node", - "sudo cp -rp /root/.cargo/bin/miden-faucet /usr/bin/miden-faucet && sudo chmod a+x /usr/bin/miden-faucet", - "sudo /usr/bin/miden-node init -c /etc/miden/miden-node.toml -g /opt/miden/miden-node/genesis.toml", - "sudo /usr/bin/miden-node make-genesis -i /opt/miden/miden-node/genesis.toml -o /opt/miden/miden-node/genesis.dat", - "sudo chown -R miden:miden /opt/miden/miden-node", - "sudo /usr/bin/miden-faucet init -c /opt/miden/miden-faucet/miden-faucet.toml", - "sudo chown -R miden:miden /opt/miden/miden-faucet" - ]}' \ - --output text \ - --query "Command.CommandId") - echo "command_id=$COMMAND_ID" >> $GITHUB_OUTPUT - - - name: Check configure environment command status and retrieve output - run: | - while true; do - STATUS=$(aws ssm list-command-invocations \ - --command-id ${{ steps.configure_environment.outputs.command_id }} \ - --details \ - --query "CommandInvocations[0].Status" \ - --output text) - echo "Command Status: $STATUS" - - OUTPUT=$(aws ssm list-command-invocations \ - --command-id ${{ steps.configure_environment.outputs.command_id }} \ - --details \ - --query "CommandInvocations[0].CommandPlugins[0].Output" \ - --output text) - echo "Command Output: $OUTPUT" - - if [ "$STATUS" == "Success" ]; then - echo "Command completed successfully." - break - elif [ "$STATUS" == "Failed" ] || [ "$STATUS" == "Cancelled" ]; then - echo "Command failed with status: $STATUS" - exit 1 - else - sleep 10 - fi - done - - - - name: Start services - id: start_services - run: | - COMMAND_ID=$(aws ssm send-command \ - --instance-ids ${{ secrets.instance_id }} \ - --document-name "AWS-RunShellScript" \ - --parameters '{"commands":[ - "sudo systemctl daemon-reload", - "sudo systemctl enable miden-node", - "sudo systemctl enable miden-faucet", - "sudo systemctl start miden-node", - "sleep 5", - "sudo systemctl start miden-faucet" - ]}' \ - --output text \ - --query "Command.CommandId") - echo "command_id=$COMMAND_ID" >> $GITHUB_OUTPUT - - - name: Check Start services command status and retrieve output - run: | - while true; do - STATUS=$(aws ssm list-command-invocations \ - --command-id ${{ steps.start_services.outputs.command_id }} \ - --details \ - --query "CommandInvocations[0].Status" \ - --output text) - echo "Command Status: $STATUS" - - OUTPUT=$(aws ssm list-command-invocations \ - --command-id ${{ steps.start_services.outputs.command_id }} \ - --details \ - --query "CommandInvocations[0].CommandPlugins[0].Output" \ - --output text) - echo "Command Output: $OUTPUT" - - if [ "$STATUS" == "Success" ]; then - echo "Command completed successfully." - break - elif [ "$STATUS" == "Failed" ] || [ "$STATUS" == "Cancelled" ]; then - echo "Command failed with status: $STATUS" - exit 1 - else - sleep 10 - fi - done diff --git a/README.md b/README.md index cf14b3a89..4afd274f5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/0xPolygonMiden/miden-node/blob/main/LICENSE) [![test](https://github.com/0xPolygonMiden/miden-node/actions/workflows/test.yml/badge.svg)](https://github.com/0xPolygonMiden/miden-node/actions/workflows/test.yml) -[![RUST_VERSION](https://img.shields.io/badge/rustc-1.78+-lightgray.svg)](https://www.rust-lang.org/tools/install) +[![RUST_VERSION](https://img.shields.io/badge/rustc-1.80+-lightgray.svg)](https://www.rust-lang.org/tools/install) [![crates.io](https://img.shields.io/crates/v/miden-node)](https://crates.io/crates/miden-node) This repository holds the Miden node; that is, the software which processes transactions and creates blocks for the Miden rollup. @@ -56,9 +56,9 @@ sudo dpkg -i $package_name.deb > ``` > can be used so long as the checksum file and the package file are in the same folder. -### Intall using `cargo` +### Install using `cargo` -Install Rust version **1.78** or greater using the official Rust installation [instructions](https://www.rust-lang.org/tools/install). +Install Rust version **1.80** or greater using the official Rust installation [instructions](https://www.rust-lang.org/tools/install). Depending on the platform, you may need to install additional libraries. For example, on Ubuntu 22.04 the following command ensures that all required libraries are installed. diff --git a/bin/node/Dockerfile b/bin/node/Dockerfile index 9add73b81..577e5e61b 100644 --- a/bin/node/Dockerfile +++ b/bin/node/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.78-slim-bookworm AS builder +FROM rust:1.80-slim-bookworm AS builder RUN apt-get update && \ apt-get -y upgrade && \ From a6809493f7a143c1ab2d72f8216b3941e35accb9 Mon Sep 17 00:00:00 2001 From: Mirko <48352201+Mirko-von-Leipzig@users.noreply.github.com> Date: Wed, 11 Sep 2024 12:10:01 +0200 Subject: [PATCH 09/37] fix: infinite recursion in Digest::try_into (#490) TryFrom implementation called `T::try_into` instead of `(*T)::try_into()` causing an infinite loop. This was introduced as part of a manual clippy fix where `x.clone().try_into()` was manually changed to `x.try_into()` instead of the suggested `(*x).try_into()`. --- crates/proto/src/domain/digest.rs | 54 +++++++++++++++---------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/crates/proto/src/domain/digest.rs b/crates/proto/src/domain/digest.rs index 288620944..6be724a00 100644 --- a/crates/proto/src/domain/digest.rs +++ b/crates/proto/src/domain/digest.rs @@ -3,7 +3,7 @@ use std::fmt::{Debug, Display, Formatter}; use hex::{FromHex, ToHex}; use miden_objects::{notes::NoteId, Digest, Felt, StarkField}; -use crate::{errors::ConversionError, generated::digest}; +use crate::{errors::ConversionError, generated::digest as proto}; // CONSTANTS // ================================================================================================ @@ -13,19 +13,19 @@ pub const DIGEST_DATA_SIZE: usize = 32; // FORMATTING // ================================================================================================ -impl Display for digest::Digest { +impl Display for proto::Digest { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str(&self.encode_hex::()) } } -impl Debug for digest::Digest { +impl Debug for proto::Digest { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { Display::fmt(self, f) } } -impl ToHex for &digest::Digest { +impl ToHex for &proto::Digest { fn encode_hex>(&self) -> T { (*self).encode_hex() } @@ -35,7 +35,7 @@ impl ToHex for &digest::Digest { } } -impl ToHex for digest::Digest { +impl ToHex for proto::Digest { fn encode_hex>(&self) -> T { let mut data: Vec = Vec::with_capacity(DIGEST_DATA_SIZE); data.extend(format!("{:016x}", self.d0).chars()); @@ -55,7 +55,7 @@ impl ToHex for digest::Digest { } } -impl FromHex for digest::Digest { +impl FromHex for proto::Digest { type Error = ConversionError; fn from_hex>(hex: T) -> Result { @@ -74,7 +74,7 @@ impl FromHex for digest::Digest { let d2 = u64::from_be_bytes(data[16..24].try_into().unwrap()); let d3 = u64::from_be_bytes(data[24..32].try_into().unwrap()); - Ok(digest::Digest { d0, d1, d2, d3 }) + Ok(proto::Digest { d0, d1, d2, d3 }) }, } } @@ -83,7 +83,7 @@ impl FromHex for digest::Digest { // INTO // ================================================================================================ -impl From<[u64; 4]> for digest::Digest { +impl From<[u64; 4]> for proto::Digest { fn from(value: [u64; 4]) -> Self { Self { d0: value[0], @@ -94,13 +94,13 @@ impl From<[u64; 4]> for digest::Digest { } } -impl From<&[u64; 4]> for digest::Digest { +impl From<&[u64; 4]> for proto::Digest { fn from(value: &[u64; 4]) -> Self { (*value).into() } } -impl From<[Felt; 4]> for digest::Digest { +impl From<[Felt; 4]> for proto::Digest { fn from(value: [Felt; 4]) -> Self { Self { d0: value[0].as_int(), @@ -111,13 +111,13 @@ impl From<[Felt; 4]> for digest::Digest { } } -impl From<&[Felt; 4]> for digest::Digest { +impl From<&[Felt; 4]> for proto::Digest { fn from(value: &[Felt; 4]) -> Self { (*value).into() } } -impl From for digest::Digest { +impl From for proto::Digest { fn from(value: Digest) -> Self { Self { d0: value[0].as_int(), @@ -128,19 +128,19 @@ impl From for digest::Digest { } } -impl From<&Digest> for digest::Digest { +impl From<&Digest> for proto::Digest { fn from(value: &Digest) -> Self { (*value).into() } } -impl From<&NoteId> for digest::Digest { +impl From<&NoteId> for proto::Digest { fn from(value: &NoteId) -> Self { (*value).inner().into() } } -impl From for digest::Digest { +impl From for proto::Digest { fn from(value: NoteId) -> Self { value.inner().into() } @@ -149,16 +149,16 @@ impl From for digest::Digest { // FROM DIGEST // ================================================================================================ -impl From for [u64; 4] { - fn from(value: digest::Digest) -> Self { +impl From for [u64; 4] { + fn from(value: proto::Digest) -> Self { [value.d0, value.d1, value.d2, value.d3] } } -impl TryFrom for [Felt; 4] { +impl TryFrom for [Felt; 4] { type Error = ConversionError; - fn try_from(value: digest::Digest) -> Result { + fn try_from(value: proto::Digest) -> Result { if ![value.d0, value.d1, value.d2, value.d3] .iter() .all(|v| *v < ::MODULUS) @@ -175,27 +175,27 @@ impl TryFrom for [Felt; 4] { } } -impl TryFrom for Digest { +impl TryFrom for Digest { type Error = ConversionError; - fn try_from(value: digest::Digest) -> Result { + fn try_from(value: proto::Digest) -> Result { Ok(Self::new(value.try_into()?)) } } -impl TryFrom<&digest::Digest> for [Felt; 4] { +impl TryFrom<&proto::Digest> for [Felt; 4] { type Error = ConversionError; - fn try_from(value: &digest::Digest) -> Result { - value.try_into() + fn try_from(value: &proto::Digest) -> Result { + (*value).try_into() } } -impl TryFrom<&digest::Digest> for Digest { +impl TryFrom<&proto::Digest> for Digest { type Error = ConversionError; - fn try_from(value: &digest::Digest) -> Result { - value.try_into() + fn try_from(value: &proto::Digest) -> Result { + (*value).try_into() } } From 2b24ef7982201dfc179b312fe95eadf905afe4be Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Fri, 13 Sep 2024 09:33:59 +0500 Subject: [PATCH 10/37] Updated to the latest `next` branch of `miden-objects` (#494) * fix: update to the latest `miden-objects` * refactor: remove use of `std::iter` --- Cargo.lock | 6 +++--- bin/faucet/src/client.rs | 14 +++++++------- crates/store/src/db/tests.rs | 11 ++++++----- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33f0b1396..645e54f0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1788,7 +1788,7 @@ dependencies = [ [[package]] name = "miden-lib" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#36416cedee53a475ee33ec6222e101cf5811e0b8" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#7c05c8e108f2a33c60a977493bb368924ac89cf1" dependencies = [ "miden-assembly", "miden-objects", @@ -1976,7 +1976,7 @@ dependencies = [ [[package]] name = "miden-objects" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#36416cedee53a475ee33ec6222e101cf5811e0b8" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#7c05c8e108f2a33c60a977493bb368924ac89cf1" dependencies = [ "miden-assembly", "miden-core", @@ -2047,7 +2047,7 @@ dependencies = [ [[package]] name = "miden-tx" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#36416cedee53a475ee33ec6222e101cf5811e0b8" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#7c05c8e108f2a33c60a977493bb368924ac89cf1" dependencies = [ "miden-lib", "miden-objects", diff --git a/bin/faucet/src/client.rs b/bin/faucet/src/client.rs index c6edf5076..595709b5c 100644 --- a/bin/faucet/src/client.rs +++ b/bin/faucet/src/client.rs @@ -22,8 +22,9 @@ use miden_objects::{ BlockHeader, Felt, Word, }; use miden_tx::{ - auth::BasicAuthenticator, utils::Serializable, DataStore, DataStoreError, ProvingOptions, - TransactionExecutor, TransactionInputs, TransactionProver, + auth::BasicAuthenticator, utils::Serializable, DataStore, DataStoreError, + LocalTransactionProver, ProvingOptions, TransactionExecutor, TransactionInputs, + TransactionProver, }; use rand::{rngs::StdRng, thread_rng, Rng}; use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; @@ -123,14 +124,13 @@ impl FaucetClient { &mut self, executed_tx: ExecutedTransaction, ) -> Result { - let transaction_prover = TransactionProver::new(ProvingOptions::default()); + let transaction_prover = LocalTransactionProver::new(ProvingOptions::default()); let delta = executed_tx.account_delta().clone(); - let proven_transaction = - transaction_prover.prove_transaction(executed_tx).map_err(|err| { - FaucetError::InternalServerError(format!("Failed to prove transaction: {}", err)) - })?; + let proven_transaction = transaction_prover.prove(executed_tx).map_err(|err| { + FaucetError::InternalServerError(format!("Failed to prove transaction: {}", err)) + })?; let request = SubmitProvenTransactionRequest { transaction: proven_transaction.to_bytes(), diff --git a/crates/store/src/db/tests.rs b/crates/store/src/db/tests.rs index f0621a1f6..af5dcba7e 100644 --- a/crates/store/src/db/tests.rs +++ b/crates/store/src/db/tests.rs @@ -1,5 +1,3 @@ -use std::collections::BTreeMap; - use miden_lib::transaction::TransactionKernel; use miden_node_proto::domain::accounts::AccountSummary; use miden_objects::{ @@ -11,7 +9,7 @@ use miden_objects::{ }, delta::AccountUpdateDetails, Account, AccountCode, AccountDelta, AccountId, AccountStorage, AccountStorageDelta, - AccountVaultDelta, + AccountVaultDelta, StorageSlot, }, assets::{Asset, AssetVault, FungibleAsset, NonFungibleAsset, NonFungibleAssetDetails}, block::{BlockAccountUpdate, BlockNoteIndex, BlockNoteTree}, @@ -335,7 +333,10 @@ fn test_sql_public_account_details() { let non_fungible_faucet_id = AccountId::try_from(ACCOUNT_ID_NON_FUNGIBLE_FAUCET_ON_CHAIN).unwrap(); - let mut storage = AccountStorage::new(vec![], BTreeMap::new()).unwrap(); + let mut storage = AccountStorage::new( + std::iter::repeat(StorageSlot::Value(Word::default())).take(6).collect(), + ) + .unwrap(); storage.set_item(1, num_to_word(1)).unwrap(); storage.set_item(3, num_to_word(3)).unwrap(); storage.set_item(5, num_to_word(5)).unwrap(); @@ -431,7 +432,7 @@ fn test_sql_public_account_details() { assert_eq!(account_read.nonce(), account.nonce()); // Cleared item was not serialized, check it and apply delta only with clear item second time: - assert_eq!(account_read.storage().get_item(3), RpoDigest::default()); + assert_eq!(account_read.storage().get_item(3), Ok(RpoDigest::default())); let storage_delta = AccountStorageDelta::from_iters([3], [], []); account_read From 3b142832a109f210176592acb4f276e7a82fa853 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Thu, 12 Sep 2024 22:49:53 -0700 Subject: [PATCH 11/37] chore: added back tokio dependencies to the root Cargo.toml --- Cargo.lock | 26 +++++++++++++------------- Cargo.toml | 2 ++ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0e3bc8d35..ed7fff673 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -330,9 +330,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.87" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" +checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356" [[package]] name = "arrayref" @@ -1788,7 +1788,7 @@ dependencies = [ [[package]] name = "miden-lib" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#7c05c8e108f2a33c60a977493bb368924ac89cf1" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#f4fce94f1be0f7fab29164ccefa90317aae92425" dependencies = [ "miden-assembly", "miden-objects", @@ -1979,7 +1979,7 @@ dependencies = [ [[package]] name = "miden-objects" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#7c05c8e108f2a33c60a977493bb368924ac89cf1" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#f4fce94f1be0f7fab29164ccefa90317aae92425" dependencies = [ "miden-assembly", "miden-core", @@ -2050,7 +2050,7 @@ dependencies = [ [[package]] name = "miden-tx" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#7c05c8e108f2a33c60a977493bb368924ac89cf1" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#f4fce94f1be0f7fab29164ccefa90317aae92425" dependencies = [ "miden-lib", "miden-objects", @@ -2311,9 +2311,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "owo-colors" -version = "4.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f" +checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" [[package]] name = "parking_lot" @@ -2687,9 +2687,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" dependencies = [ "bitflags", ] @@ -2811,9 +2811,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.36" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags", "errno", @@ -3596,9 +3596,9 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-linebreak" diff --git a/Cargo.toml b/Cargo.toml index 0e302f4d7..7e2f0c5cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,8 @@ miden-stdlib = { version = "0.10", default-features = false } miden-tx = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } prost = { version = "0.13" } thiserror = { version = "1.0" } +tokio = { version = "1.40" } +tokio-stream = { version = "0.1" } tonic = { version = "0.12" } tracing = { version = "0.1" } tracing-subscriber = { version = "0.3", features = ["fmt", "json", "env-filter"] } From 9344a1d39fdbe9b8000cd3d2f6095b87910f779c Mon Sep 17 00:00:00 2001 From: igamigo Date: Fri, 13 Sep 2024 16:37:10 -0300 Subject: [PATCH 12/37] feat: Add kernel root to blocks (#496) * feat: Add kernel root to block code * chore: Fix format * Make genesis kernel root default * Use current TransactionKernel::assembler_root() as for new block headers? * chore: Changelog * Add miden-lib to dependencies * Update block.proto * Alias generated module * Regen proto * Revert to good comment --- CHANGELOG.md | 1 + Cargo.lock | 14 +++--- crates/block-producer/Cargo.toml | 1 + .../src/block_builder/prover/mod.rs | 4 +- crates/block-producer/src/test_utils/block.rs | 2 + crates/block-producer/src/test_utils/store.rs | 1 + crates/proto/src/domain/blocks.rs | 43 +++++++++++-------- crates/proto/src/generated/block.rs | 5 ++- crates/rpc-proto/proto/block.proto | 4 +- crates/store/src/db/tests.rs | 10 +++-- crates/store/src/genesis.rs | 1 + proto/block.proto | 4 +- 12 files changed, 56 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a95519ff..42ece710b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## v0.6.0 (TBD) +- [BREAKING] Added `kernel_root` to block header's protobuf message definitions (#496). - [BREAKING] Renamed `off-chain` and `on-chain` to `private` and `public` respectively for the account storage modes (#489). - Optimized state synchronizations by removing unnecessary fetching and parsing of note details (#462). - [BREAKING] Changed `GetAccountDetailsResponse` field to `details` (#481). diff --git a/Cargo.lock b/Cargo.lock index ed7fff673..f1ac31eb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1733,9 +1733,9 @@ dependencies = [ [[package]] name = "miden-crypto" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6fad06fc3af260ed3c4235821daa2132813d993f96d446856036ae97e9606dd" +checksum = "8a69f8362ca496a79c88cf8e5b9b349bf9c6ed49fa867d0548e670afc1f3fca5" dependencies = [ "blake3", "cc", @@ -1788,7 +1788,7 @@ dependencies = [ [[package]] name = "miden-lib" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#f4fce94f1be0f7fab29164ccefa90317aae92425" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#679f7028505c2c324a22b997eef413be32b282e5" dependencies = [ "miden-assembly", "miden-objects", @@ -1979,7 +1979,7 @@ dependencies = [ [[package]] name = "miden-objects" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#f4fce94f1be0f7fab29164ccefa90317aae92425" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#679f7028505c2c324a22b997eef413be32b282e5" dependencies = [ "miden-assembly", "miden-core", @@ -1992,9 +1992,9 @@ dependencies = [ [[package]] name = "miden-processor" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01e7b212b152b69373e89b069a18cb01742ef2c3f9c328e7b24c44e44f022e52" +checksum = "04a128e20400086c9a985f4e5702e438ba781338fb0bdf9acff16d996c640087" dependencies = [ "miden-air", "miden-core", @@ -2050,7 +2050,7 @@ dependencies = [ [[package]] name = "miden-tx" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#f4fce94f1be0f7fab29164ccefa90317aae92425" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#679f7028505c2c324a22b997eef413be32b282e5" dependencies = [ "miden-lib", "miden-objects", diff --git a/crates/block-producer/Cargo.toml b/crates/block-producer/Cargo.toml index d9ec4e15e..1d1476fdf 100644 --- a/crates/block-producer/Cargo.toml +++ b/crates/block-producer/Cargo.toml @@ -18,6 +18,7 @@ tracing-forest = ["miden-node-utils/tracing-forest"] async-trait = { version = "0.1" } figment = { version = "0.10", features = ["toml", "env"] } itertools = { version = "0.13" } +miden-lib = { workspace = true } miden-node-proto = { workspace = true } miden-node-utils = { workspace = true } miden-objects = { workspace = true } diff --git a/crates/block-producer/src/block_builder/prover/mod.rs b/crates/block-producer/src/block_builder/prover/mod.rs index 8eea73a18..17f7d6424 100644 --- a/crates/block-producer/src/block_builder/prover/mod.rs +++ b/crates/block-producer/src/block_builder/prover/mod.rs @@ -1,5 +1,6 @@ use std::time::{SystemTime, UNIX_EPOCH}; +use miden_lib::transaction::TransactionKernel; use miden_objects::{assembly::Assembler, block::compute_tx_hash, BlockHeader, Digest}; use miden_processor::{execute, DefaultHost, ExecutionOptions, MemAdviceProvider, Program}; use miden_stdlib::StdLibrary; @@ -61,7 +62,7 @@ impl BlockProver { .expect("today is expected to be after 1970") .as_secs() .try_into() - .expect("timestamp must fit to `u32`"); + .expect("timestamp must fit in a `u32`"); Ok(BlockHeader::new( version, @@ -72,6 +73,7 @@ impl BlockProver { nullifier_root, note_root, tx_hash, + TransactionKernel::kernel_root(), proof_hash, timestamp, )) diff --git a/crates/block-producer/src/test_utils/block.rs b/crates/block-producer/src/test_utils/block.rs index fad8de3af..937379b09 100644 --- a/crates/block-producer/src/test_utils/block.rs +++ b/crates/block-producer/src/test_utils/block.rs @@ -66,6 +66,7 @@ pub async fn build_expected_block_header( note_created_smt.root(), Digest::default(), Digest::default(), + Digest::default(), 1, ) } @@ -162,6 +163,7 @@ impl MockBlockBuilder { note_created_smt_from_note_batches(created_notes.iter()).root(), Digest::default(), Digest::default(), + Digest::default(), 1, ); diff --git a/crates/block-producer/src/test_utils/store.rs b/crates/block-producer/src/test_utils/store.rs index 57535aa81..e33faab88 100644 --- a/crates/block-producer/src/test_utils/store.rs +++ b/crates/block-producer/src/test_utils/store.rs @@ -127,6 +127,7 @@ impl MockStoreSuccessBuilder { note_root, Digest::default(), Digest::default(), + Digest::default(), 1, ); diff --git a/crates/proto/src/domain/blocks.rs b/crates/proto/src/domain/blocks.rs index b46ab87fe..40f8b1032 100644 --- a/crates/proto/src/domain/blocks.rs +++ b/crates/proto/src/domain/blocks.rs @@ -2,13 +2,13 @@ use miden_objects::{crypto::merkle::MerklePath, BlockHeader}; use crate::{ errors::{ConversionError, MissingFieldHelper}, - generated::block, + generated::block as proto, }; // BLOCK HEADER // ================================================================================================ -impl From<&BlockHeader> for block::BlockHeader { +impl From<&BlockHeader> for proto::BlockHeader { fn from(header: &BlockHeader) -> Self { Self { version: header.version(), @@ -19,60 +19,65 @@ impl From<&BlockHeader> for block::BlockHeader { nullifier_root: Some(header.nullifier_root().into()), note_root: Some(header.note_root().into()), tx_hash: Some(header.tx_hash().into()), + kernel_root: Some(header.kernel_root().into()), proof_hash: Some(header.proof_hash().into()), timestamp: header.timestamp(), } } } -impl From for block::BlockHeader { +impl From for proto::BlockHeader { fn from(header: BlockHeader) -> Self { (&header).into() } } -impl TryFrom<&block::BlockHeader> for BlockHeader { +impl TryFrom<&proto::BlockHeader> for BlockHeader { type Error = ConversionError; - fn try_from(value: &block::BlockHeader) -> Result { + fn try_from(value: &proto::BlockHeader) -> Result { value.try_into() } } -impl TryFrom for BlockHeader { +impl TryFrom for BlockHeader { type Error = ConversionError; - fn try_from(value: block::BlockHeader) -> Result { + fn try_from(value: proto::BlockHeader) -> Result { Ok(BlockHeader::new( value.version, value .prev_hash - .ok_or(block::BlockHeader::missing_field(stringify!(prev_hash)))? + .ok_or(proto::BlockHeader::missing_field(stringify!(prev_hash)))? .try_into()?, value.block_num, value .chain_root - .ok_or(block::BlockHeader::missing_field(stringify!(chain_root)))? + .ok_or(proto::BlockHeader::missing_field(stringify!(chain_root)))? .try_into()?, value .account_root - .ok_or(block::BlockHeader::missing_field(stringify!(account_root)))? + .ok_or(proto::BlockHeader::missing_field(stringify!(account_root)))? .try_into()?, value .nullifier_root - .ok_or(block::BlockHeader::missing_field(stringify!(nullifier_root)))? + .ok_or(proto::BlockHeader::missing_field(stringify!(nullifier_root)))? .try_into()?, value .note_root - .ok_or(block::BlockHeader::missing_field(stringify!(note_root)))? + .ok_or(proto::BlockHeader::missing_field(stringify!(note_root)))? .try_into()?, value .tx_hash - .ok_or(block::BlockHeader::missing_field(stringify!(tx_hash)))? + .ok_or(proto::BlockHeader::missing_field(stringify!(tx_hash)))? + .try_into()?, + value + .kernel_root + .ok_or(proto::BlockHeader::missing_field(stringify!(kernel_root)))? .try_into()?, value .proof_hash - .ok_or(block::BlockHeader::missing_field(stringify!(proof_hash)))? + .ok_or(proto::BlockHeader::missing_field(stringify!(proof_hash)))? .try_into()?, value.timestamp, )) @@ -87,7 +92,7 @@ pub struct BlockInclusionProof { pub chain_length: u32, } -impl From for block::BlockInclusionProof { +impl From for proto::BlockInclusionProof { fn from(value: BlockInclusionProof) -> Self { Self { block_header: Some(value.block_header.into()), @@ -97,18 +102,18 @@ impl From for block::BlockInclusionProof { } } -impl TryFrom for BlockInclusionProof { +impl TryFrom for BlockInclusionProof { type Error = ConversionError; - fn try_from(value: block::BlockInclusionProof) -> Result { + fn try_from(value: proto::BlockInclusionProof) -> Result { let result = Self { block_header: value .block_header - .ok_or(block::BlockInclusionProof::missing_field("block_header"))? + .ok_or(proto::BlockInclusionProof::missing_field("block_header"))? .try_into()?, mmr_path: (&value .mmr_path - .ok_or(block::BlockInclusionProof::missing_field("mmr_path"))?) + .ok_or(proto::BlockInclusionProof::missing_field("mmr_path"))?) .try_into()?, chain_length: value.chain_length, }; diff --git a/crates/proto/src/generated/block.rs b/crates/proto/src/generated/block.rs index ebb676425..2c0898b1f 100644 --- a/crates/proto/src/generated/block.rs +++ b/crates/proto/src/generated/block.rs @@ -28,8 +28,11 @@ pub struct BlockHeader { /// a hash of a STARK proof attesting to the correct state transition. #[prost(message, optional, tag = "9")] pub proof_hash: ::core::option::Option, + /// a commitment to all transaction kernels supported by this block. + #[prost(message, optional, tag = "10")] + pub kernel_root: ::core::option::Option, /// the time when the block was created. - #[prost(fixed32, tag = "10")] + #[prost(fixed32, tag = "11")] pub timestamp: u32, } #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/crates/rpc-proto/proto/block.proto b/crates/rpc-proto/proto/block.proto index 85117e751..616f927b4 100644 --- a/crates/rpc-proto/proto/block.proto +++ b/crates/rpc-proto/proto/block.proto @@ -23,8 +23,10 @@ message BlockHeader { digest.Digest tx_hash = 8; // a hash of a STARK proof attesting to the correct state transition. digest.Digest proof_hash = 9; + // a commitment to all transaction kernels supported by this block. + digest.Digest kernel_root = 10; // the time when the block was created. - fixed32 timestamp = 10; + fixed32 timestamp = 11; } message BlockInclusionProof { diff --git a/crates/store/src/db/tests.rs b/crates/store/src/db/tests.rs index af5dcba7e..9ad93bf87 100644 --- a/crates/store/src/db/tests.rs +++ b/crates/store/src/db/tests.rs @@ -40,7 +40,8 @@ fn create_block(conn: &mut Connection, block_num: u32) { num_to_rpo_digest(7), num_to_rpo_digest(8), num_to_rpo_digest(9), - 10_u8.into(), + num_to_rpo_digest(10), + 11_u8.into(), ); let transaction = conn.transaction().unwrap(); @@ -735,9 +736,9 @@ fn test_db_block_header() { num_to_rpo_digest(7), num_to_rpo_digest(8), num_to_rpo_digest(9), - 10_u8.into(), + num_to_rpo_digest(10), + 11_u8.into(), ); - // test insertion let transaction = conn.transaction().unwrap(); sql::insert_block_header(&transaction, &block_header).unwrap(); @@ -767,7 +768,8 @@ fn test_db_block_header() { num_to_rpo_digest(17), num_to_rpo_digest(18), num_to_rpo_digest(19), - 20_u8.into(), + num_to_rpo_digest(20), + 21_u8.into(), ); let transaction = conn.transaction().unwrap(); diff --git a/crates/store/src/genesis.rs b/crates/store/src/genesis.rs index 8052c5cdc..a77a56a29 100644 --- a/crates/store/src/genesis.rs +++ b/crates/store/src/genesis.rs @@ -62,6 +62,7 @@ impl GenesisState { *EmptySubtreeRoots::entry(NOTE_LEAF_DEPTH, 0), Digest::default(), Digest::default(), + Digest::default(), self.timestamp, ); diff --git a/proto/block.proto b/proto/block.proto index 85117e751..616f927b4 100644 --- a/proto/block.proto +++ b/proto/block.proto @@ -23,8 +23,10 @@ message BlockHeader { digest.Digest tx_hash = 8; // a hash of a STARK proof attesting to the correct state transition. digest.Digest proof_hash = 9; + // a commitment to all transaction kernels supported by this block. + digest.Digest kernel_root = 10; // the time when the block was created. - fixed32 timestamp = 10; + fixed32 timestamp = 11; } message BlockInclusionProof { From d394970e02c855bc44cd25313526a31fa8c41296 Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Mon, 16 Sep 2024 20:58:09 +0500 Subject: [PATCH 13/37] Refactoring of the block/batch note trees (#475) * fix(WIP): update note tree depth in block kernel, update test * refactor: updated to the latest `miden-objects` * refactor: improve block kernel readability * fix: return back assertion in test * fix: compilation error * fix: update to the latest `miden-objects` * fix: update to the latest `miden-objects` * refactor: remove use of `std::iter` * chore: update `Cargo.lock` * chore: update `Cargo.lock` * chore: update `Cargo.lock` --- Cargo.lock | 6 +-- Cargo.toml | 6 +-- .../prover/asm/block_kernel.masm | 20 ++++--- .../src/block_builder/prover/block_witness.rs | 4 +- .../src/block_builder/prover/tests.rs | 52 +++++++++++-------- crates/block-producer/src/errors.rs | 5 +- crates/block-producer/src/test_utils/block.rs | 6 +-- crates/block-producer/src/test_utils/store.rs | 8 +-- crates/proto/src/domain/notes.rs | 4 +- crates/proto/src/errors.rs | 4 +- crates/store/src/db/mod.rs | 4 +- crates/store/src/db/sql.rs | 9 ++-- crates/store/src/db/tests.rs | 14 ++--- crates/store/src/errors.rs | 4 +- crates/store/src/genesis.rs | 5 +- crates/store/src/state.rs | 4 +- 16 files changed, 83 insertions(+), 72 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f1ac31eb1..709cd69dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1788,7 +1788,7 @@ dependencies = [ [[package]] name = "miden-lib" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#679f7028505c2c324a22b997eef413be32b282e5" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=polydez-note-tree-refactor#48e5f4743c4ff2e842296a963be25fc8b071d0f6" dependencies = [ "miden-assembly", "miden-objects", @@ -1979,7 +1979,7 @@ dependencies = [ [[package]] name = "miden-objects" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#679f7028505c2c324a22b997eef413be32b282e5" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=polydez-note-tree-refactor#48e5f4743c4ff2e842296a963be25fc8b071d0f6" dependencies = [ "miden-assembly", "miden-core", @@ -2050,7 +2050,7 @@ dependencies = [ [[package]] name = "miden-tx" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#679f7028505c2c324a22b997eef413be32b282e5" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=polydez-note-tree-refactor#48e5f4743c4ff2e842296a963be25fc8b071d0f6" dependencies = [ "miden-lib", "miden-objects", diff --git a/Cargo.toml b/Cargo.toml index 7e2f0c5cc..5afc96980 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ readme = "README.md" [workspace.dependencies] miden-air = { version = "0.10", default-features = false } -miden-lib = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next"} +miden-lib = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "polydez-note-tree-refactor"} miden-node-block-producer = { path = "crates/block-producer", version = "0.6" } miden-node-faucet = { path = "bin/faucet", version = "0.6" } miden-node-proto = { path = "crates/proto", version = "0.6" } @@ -35,10 +35,10 @@ miden-node-rpc-proto = { path = "crates/rpc-proto", version = "0.6" } miden-node-store = { path = "crates/store", version = "0.6" } miden-node-test-macro = { path = "crates/test-macro" } miden-node-utils = { path = "crates/utils", version = "0.6" } -miden-objects = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } +miden-objects = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "polydez-note-tree-refactor" } miden-processor = { version = "0.10" } miden-stdlib = { version = "0.10", default-features = false } -miden-tx = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } +miden-tx = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "polydez-note-tree-refactor" } prost = { version = "0.13" } thiserror = { version = "1.0" } tokio = { version = "1.40" } diff --git a/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm b/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm index ccf704641..023f2c39a 100644 --- a/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm +++ b/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm @@ -8,6 +8,7 @@ use.std::collections::smt use.std::collections::mmr const.ACCOUNT_TREE_DEPTH=64 +const.BLOCK_NOTES_BATCH_TREE_DEPTH=6 const.CHAIN_MMR_PTR=1000 #! Compute the account root @@ -46,12 +47,12 @@ end #! Compute the note root. #! -#! Each batch contains a tree of depth 13 for its created notes. The block's created notes tree is created -#! by aggregating up to 2^8 tree roots coming from the batches contained in the block. +#! Each batch contains a tree of depth 10 for its created notes. The block's created notes tree is created +#! by aggregating up to 2^6 tree roots coming from the batches contained in the block. #! -#! `SMT_EMPTY_ROOT` must be `E21`, the root of the empty tree of depth 21. If less than 2^8 batches are -#! contained in the block, `E13` is used as the padding value; this is derived from the fact that -#! `SMT_EMPTY_ROOT` is `E21`, and that our tree has depth 8. +#! `SMT_EMPTY_ROOT` must be `E16`, the root of the empty tree of depth 16. If less than 2^6 batches are +#! contained in the block, `E10` is used as the padding value; this is derived from the fact that +#! `SMT_EMPTY_ROOT` is `E16`, and that our tree has depth 6. #! #! Stack: [num_notes_updated, SMT_EMPTY_ROOT, #! batch_note_root_idx_0, BATCH_NOTE_TREE_ROOT_0, @@ -66,9 +67,14 @@ proc.compute_note_root while.true #=> [note_roots_left_to_update, ROOT_i, batch_note_root_idx_i, BATCH_NOTE_TREE_ROOT_i, ... ] + # Move counter down for next iteration + movdn.9 + #=> [ROOT_i, batch_note_root_idx_i, BATCH_NOTE_TREE_ROOT_i, note_roots_left_to_update, ... ] + # Prepare stack for mtree_set - movdn.9 movup.4 push.8 - #=> [depth=8, batch_note_root_idx_i, ROOT_i, BATCH_NOTE_TREE_ROOT_i, note_roots_left_to_update, ... ] + movup.4 push.BLOCK_NOTES_BATCH_TREE_DEPTH + #=> [depth=batch_tree_depth, batch_note_root_idx_i, ROOT_i, + # BATCH_NOTE_TREE_ROOT_i, note_roots_left_to_update, ... ] mtree_set dropw #=> [ROOT_{i+1}, note_roots_left_to_update, ... ] diff --git a/crates/block-producer/src/block_builder/prover/block_witness.rs b/crates/block-producer/src/block_builder/prover/block_witness.rs index 39ae3caf7..9bbe473c8 100644 --- a/crates/block-producer/src/block_builder/prover/block_witness.rs +++ b/crates/block-producer/src/block_builder/prover/block_witness.rs @@ -7,7 +7,7 @@ use miden_objects::{ notes::Nullifier, transaction::TransactionId, vm::{AdviceInputs, StackInputs}, - BlockHeader, Digest, Felt, BLOCK_NOTES_TREE_DEPTH, MAX_BATCHES_PER_BLOCK, ZERO, + BlockHeader, Digest, Felt, BLOCK_NOTE_TREE_DEPTH, MAX_BATCHES_PER_BLOCK, ZERO, }; use crate::{ @@ -221,7 +221,7 @@ impl BlockWitness { stack_inputs.push(batch_index); } - let empty_root = EmptySubtreeRoots::entry(BLOCK_NOTES_TREE_DEPTH, 0); + let empty_root = EmptySubtreeRoots::entry(BLOCK_NOTE_TREE_DEPTH, 0); stack_inputs.extend(*empty_root); stack_inputs.push( Felt::try_from(self.batch_created_notes_roots.len() as u64) diff --git a/crates/block-producer/src/block_builder/prover/tests.rs b/crates/block-producer/src/block_builder/prover/tests.rs index 624f1ae39..96959f4a8 100644 --- a/crates/block-producer/src/block_builder/prover/tests.rs +++ b/crates/block-producer/src/block_builder/prover/tests.rs @@ -8,14 +8,13 @@ use miden_objects::{ delta::AccountUpdateDetails, AccountId, }, - block::BlockAccountUpdate, + block::{BlockAccountUpdate, BlockNoteIndex, BlockNoteTree}, crypto::merkle::{ - EmptySubtreeRoots, LeafIndex, MerklePath, Mmr, MmrPeaks, SimpleSmt, Smt, SmtLeaf, SmtProof, - SMT_DEPTH, + EmptySubtreeRoots, LeafIndex, MerklePath, Mmr, MmrPeaks, Smt, SmtLeaf, SmtProof, SMT_DEPTH, }, notes::{NoteExecutionHint, NoteHeader, NoteMetadata, NoteTag, NoteType, Nullifier}, transaction::{OutputNote, ProvenTransaction}, - Felt, BLOCK_NOTES_TREE_DEPTH, ONE, ZERO, + Felt, BATCH_NOTE_TREE_DEPTH, BLOCK_NOTE_TREE_DEPTH, ONE, ZERO, }; use self::block_witness::AccountUpdateWitness; @@ -451,7 +450,7 @@ async fn test_compute_note_root_empty_batches_success() { // Compare roots // --------------------------------------------------------------------------------------------- - let created_notes_empty_root = EmptySubtreeRoots::entry(BLOCK_NOTES_TREE_DEPTH, 0); + let created_notes_empty_root = EmptySubtreeRoots::entry(BLOCK_NOTE_TREE_DEPTH, 0); assert_eq!(block_header.note_root(), *created_notes_empty_root); } @@ -486,7 +485,7 @@ async fn test_compute_note_root_empty_notes_success() { // Compare roots // --------------------------------------------------------------------------------------------- - let created_notes_empty_root = EmptySubtreeRoots::entry(BLOCK_NOTES_TREE_DEPTH, 0); + let created_notes_empty_root = EmptySubtreeRoots::entry(BLOCK_NOTE_TREE_DEPTH, 0); assert_eq!(block_header.note_root(), *created_notes_empty_root); } @@ -560,30 +559,37 @@ async fn test_compute_note_root_success() { let block_prover = BlockProver::new(); let block_header = block_prover.prove(block_witness).unwrap(); - // Create SMT by hand to get new root + // Create block note tree to get new root // --------------------------------------------------------------------------------------------- - // The current logic is hardcoded to a depth of 21 - // Specifically, we assume the block has up to 2^8 batches, and each batch up to 2^12 created - // notes, where each note is stored at depth 13 in the batch as 2 contiguous nodes: note - // hash, then metadata. - assert_eq!(BLOCK_NOTES_TREE_DEPTH, 21); - - // The first 2 txs were put in the first batch; the 3rd was put in the second. It will lie in - // the second subtree of depth 12 - let notes_smt = SimpleSmt::::with_leaves(vec![ - (0u64, notes_created[0].id().into()), - (1u64, notes_created[0].metadata().into()), - (2u64, notes_created[1].id().into()), - (3u64, notes_created[1].metadata().into()), - (2u64.pow(13), notes_created[2].id().into()), - (2u64.pow(13) + 1, notes_created[2].metadata().into()), + // The current logic is hardcoded to a depth of 6 + // Specifically, we assume the block has up to 2^6 batches, and each batch up to 2^10 created + // notes, where each note is stored at depth 10 in the batch tree. + const _: () = assert!(BLOCK_NOTE_TREE_DEPTH - BATCH_NOTE_TREE_DEPTH == 6); + + // The first 2 txs were put in the first batch; the 3rd was put in the second + let note_tree = BlockNoteTree::with_entries([ + ( + BlockNoteIndex::new(0, 0).unwrap(), + notes_created[0].id(), + *notes_created[0].metadata(), + ), + ( + BlockNoteIndex::new(0, 1).unwrap(), + notes_created[1].id(), + *notes_created[1].metadata(), + ), + ( + BlockNoteIndex::new(1, 0).unwrap(), + notes_created[2].id(), + *notes_created[2].metadata(), + ), ]) .unwrap(); // Compare roots // --------------------------------------------------------------------------------------------- - assert_eq!(block_header.note_root(), notes_smt.root()); + assert_eq!(block_header.note_root(), note_tree.root()); } // NULLIFIER ROOT TESTS diff --git a/crates/block-producer/src/errors.rs b/crates/block-producer/src/errors.rs index 55399d4a2..6b32dc549 100644 --- a/crates/block-producer/src/errors.rs +++ b/crates/block-producer/src/errors.rs @@ -5,8 +5,7 @@ use miden_objects::{ crypto::merkle::{MerkleError, MmrError}, notes::{NoteId, Nullifier}, transaction::{ProvenTransaction, TransactionId}, - AccountDeltaError, Digest, TransactionInputError, BLOCK_NOTES_BATCH_TREE_DEPTH, - MAX_NOTES_PER_BATCH, + AccountDeltaError, Digest, TransactionInputError, MAX_BATCHES_PER_BLOCK, MAX_NOTES_PER_BATCH, }; use miden_processor::ExecutionError; use thiserror::Error; @@ -186,7 +185,7 @@ pub enum BuildBlockError { InconsistentNullifiers(Vec), #[error("unauthenticated transaction notes not found in the store or in outputs of other transactions in the block: {0:?}")] UnauthenticatedNotesNotFound(Vec), - #[error("too many batches in block. Got: {0}, max: 2^{}", BLOCK_NOTES_BATCH_TREE_DEPTH)] + #[error("too many batches in block. Got: {0}, max: {MAX_BATCHES_PER_BLOCK}")] TooManyBatchesInBlock(usize), #[error("Failed to merge transaction delta into account {account_id}: {error}")] AccountUpdateError { diff --git a/crates/block-producer/src/test_utils/block.rs b/crates/block-producer/src/test_utils/block.rs index 937379b09..a8678eea6 100644 --- a/crates/block-producer/src/test_utils/block.rs +++ b/crates/block-producer/src/test_utils/block.rs @@ -182,7 +182,7 @@ pub(crate) fn flatten_output_notes<'a>( ) -> impl Iterator { batches.enumerate().flat_map(|(batch_idx, batch)| { batch.iter().enumerate().map(move |(note_idx_in_batch, note)| { - (BlockNoteIndex::new(batch_idx, note_idx_in_batch), note) + (BlockNoteIndex::new(batch_idx, note_idx_in_batch).unwrap(), note) }) }) } @@ -190,8 +190,8 @@ pub(crate) fn flatten_output_notes<'a>( pub(crate) fn note_created_smt_from_note_batches<'a>( batches: impl Iterator, ) -> BlockNoteTree { - let note_leaf_iterator = flatten_output_notes(batches) - .map(|(index, note)| (index, note.id().into(), *note.metadata())); + let note_leaf_iterator = + flatten_output_notes(batches).map(|(index, note)| (index, note.id(), *note.metadata())); BlockNoteTree::with_entries(note_leaf_iterator).unwrap() } diff --git a/crates/block-producer/src/test_utils/store.rs b/crates/block-producer/src/test_utils/store.rs index e33faab88..bf1e89328 100644 --- a/crates/block-producer/src/test_utils/store.rs +++ b/crates/block-producer/src/test_utils/store.rs @@ -137,8 +137,8 @@ impl MockStoreSuccessBuilder { note.id(), NoteInclusionProof::new( block_num, - index.to_absolute_index(), - block_note_tree.get_note_path(index).unwrap(), + index.leaf_index_value(), + block_note_tree.get_note_path(index), ) .expect("Failed to create `NoteInclusionProof`"), ) @@ -225,8 +225,8 @@ impl ApplyBlock for MockStoreSuccess { note.id(), NoteInclusionProof::new( header.block_num(), - note_index.to_absolute_index(), - note_tree.get_note_path(note_index).unwrap_or_default(), + note_index.leaf_index_value(), + note_tree.get_note_path(note_index), ) .expect("Failed to build `NoteInclusionProof`"), ); diff --git a/crates/proto/src/domain/notes.rs b/crates/proto/src/domain/notes.rs index abc655d8d..10cb5db4f 100644 --- a/crates/proto/src/domain/notes.rs +++ b/crates/proto/src/domain/notes.rs @@ -58,7 +58,7 @@ impl From<(&NoteId, &NoteInclusionProof)> for NoteInclusionInBlockProofPb { Self { note_id: Some(note_id.into()), block_num: proof.location().block_num(), - note_index_in_block: proof.location().node_index_in_block(), + note_index_in_block: proof.location().node_index_in_block().into(), merkle_path: Some(Into::into(proof.note_path())), } } @@ -80,7 +80,7 @@ impl TryFrom<&NoteInclusionInBlockProofPb> for (NoteId, NoteInclusionProof) { .into(), NoteInclusionProof::new( proof.block_num, - proof.note_index_in_block, + proof.note_index_in_block.try_into()?, proof .merkle_path .as_ref() diff --git a/crates/proto/src/errors.rs b/crates/proto/src/errors.rs index a97490f58..7f06c7017 100644 --- a/crates/proto/src/errors.rs +++ b/crates/proto/src/errors.rs @@ -1,4 +1,4 @@ -use std::any::type_name; +use std::{any::type_name, num::TryFromIntError}; use miden_objects::crypto::merkle::{SmtLeafError, SmtProofError}; use thiserror::Error; @@ -13,6 +13,8 @@ pub enum ConversionError { SmtLeafError(#[from] SmtLeafError), #[error("SMT proof error: {0}")] SmtProofError(#[from] SmtProofError), + #[error("Integer conversion error: {0}")] + TryFromIntError(#[from] TryFromIntError), #[error("Too much data, expected {expected}, got {got}")] TooMuchData { expected: usize, got: usize }, #[error("Not enough data, expected {expected}, got {got}")] diff --git a/crates/store/src/db/mod.rs b/crates/store/src/db/mod.rs index 5191344e7..a43dd4d39 100644 --- a/crates/store/src/db/mod.rs +++ b/crates/store/src/db/mod.rs @@ -72,7 +72,7 @@ impl From for NotePb { fn from(note: NoteRecord) -> Self { Self { block_num: note.block_num, - note_index: note.note_index.to_absolute_index(), + note_index: note.note_index.leaf_index_value().into(), note_id: Some(note.note_id.into()), metadata: Some(note.metadata.into()), merkle_path: Some(Into::into(¬e.merkle_path)), @@ -108,7 +108,7 @@ pub struct NoteSyncRecord { impl From for NoteSyncRecordPb { fn from(note: NoteSyncRecord) -> Self { Self { - note_index: note.note_index.to_absolute_index(), + note_index: note.note_index.leaf_index_value().into(), note_id: Some(note.note_id.into()), metadata: Some(note.metadata.into()), merkle_path: Some(Into::into(¬e.merkle_path)), diff --git a/crates/store/src/db/sql.rs b/crates/store/src/db/sql.rs index 0e3ea4a4d..0ef7094bc 100644 --- a/crates/store/src/db/sql.rs +++ b/crates/store/src/db/sql.rs @@ -466,7 +466,7 @@ pub fn select_notes(conn: &mut Connection) -> Result> { notes.push(NoteRecord { block_num: row.get(0)?, - note_index: BlockNoteIndex::new(row.get(1)?, row.get(2)?), + note_index: BlockNoteIndex::new(row.get(1)?, row.get(2)?)?, note_id, metadata, details, @@ -592,7 +592,7 @@ pub fn select_notes_since_block_by_tag_and_sender( let mut res = Vec::new(); while let Some(row) = rows.next()? { let block_num = row.get(0)?; - let note_index = BlockNoteIndex::new(row.get(1)?, row.get(2)?); + let note_index = BlockNoteIndex::new(row.get(1)?, row.get(2)?)?; let note_id_data = row.get_ref(3)?.as_blob()?; let note_id = RpoDigest::read_from_bytes(note_id_data)?; let note_type = row.get::<_, u8>(4)?; @@ -683,13 +683,14 @@ pub fn select_notes_by_id(conn: &mut Connection, note_ids: &[NoteId]) -> Result< notes.push(NoteRecord { block_num: row.get(0)?, - note_index: BlockNoteIndex::new(row.get(1)?, row.get(2)?), + note_index: BlockNoteIndex::new(row.get(1)?, row.get(2)?)?, details, note_id: note_id.into(), metadata, merkle_path, }) } + Ok(notes) } @@ -732,7 +733,7 @@ pub fn select_note_inclusion_proofs( let batch_index = row.get(2)?; let note_index = row.get(3)?; - let node_index_in_block = BlockNoteIndex::new(batch_index, note_index).to_absolute_index(); + let node_index_in_block = BlockNoteIndex::new(batch_index, note_index)?.leaf_index_value(); let merkle_path_data = row.get_ref(4)?.as_blob()?; let merkle_path = MerklePath::read_from_bytes(merkle_path_data)?; diff --git a/crates/store/src/db/tests.rs b/crates/store/src/db/tests.rs index 9ad93bf87..dad6eaacb 100644 --- a/crates/store/src/db/tests.rs +++ b/crates/store/src/db/tests.rs @@ -167,7 +167,7 @@ fn test_sql_select_notes() { for i in 0..10 { let note = NoteRecord { block_num, - note_index: BlockNoteIndex::new(0, i as usize), + note_index: BlockNoteIndex::new(0, i as usize).unwrap(), note_id: num_to_rpo_digest(i as u64), metadata: NoteMetadata::new( ACCOUNT_ID_OFF_CHAIN_SENDER.try_into().unwrap(), @@ -207,7 +207,7 @@ fn test_sql_select_notes_different_execution_hints() { let note_none = NoteRecord { block_num, - note_index: BlockNoteIndex::new(0, 0), + note_index: BlockNoteIndex::new(0, 0).unwrap(), note_id: num_to_rpo_digest(0), metadata: NoteMetadata::new( ACCOUNT_ID_OFF_CHAIN_SENDER.try_into().unwrap(), @@ -231,7 +231,7 @@ fn test_sql_select_notes_different_execution_hints() { let note_always = NoteRecord { block_num, - note_index: BlockNoteIndex::new(0, 1), + note_index: BlockNoteIndex::new(0, 1).unwrap(), note_id: num_to_rpo_digest(1), metadata: NoteMetadata::new( ACCOUNT_ID_OFF_CHAIN_SENDER.try_into().unwrap(), @@ -255,7 +255,7 @@ fn test_sql_select_notes_different_execution_hints() { let note_after_block = NoteRecord { block_num, - note_index: BlockNoteIndex::new(0, 2), + note_index: BlockNoteIndex::new(0, 2).unwrap(), note_id: num_to_rpo_digest(2), metadata: NoteMetadata::new( ACCOUNT_ID_OFF_CHAIN_SENDER.try_into().unwrap(), @@ -853,7 +853,7 @@ fn test_notes() { assert!(res.is_empty()); // test insertion - let note_index = BlockNoteIndex::new(0, 2); + let note_index = BlockNoteIndex::new(0, 2).unwrap(); let note_id = num_to_rpo_digest(3); let tag = 5u32; let sender = AccountId::new_unchecked(Felt::new(ACCOUNT_ID_OFF_CHAIN_SENDER)); @@ -861,10 +861,10 @@ fn test_notes() { NoteMetadata::new(sender, NoteType::Public, tag.into(), NoteExecutionHint::none(), ZERO) .unwrap(); - let values = [(note_index, note_id, note_metadata)]; + let values = [(note_index, note_id.into(), note_metadata)]; let notes_db = BlockNoteTree::with_entries(values.iter().cloned()).unwrap(); let details = Some(vec![1, 2, 3]); - let merkle_path = notes_db.get_note_path(note_index).unwrap(); + let merkle_path = notes_db.get_note_path(note_index); let note = NoteRecord { block_num: block_num_1, diff --git a/crates/store/src/errors.rs b/crates/store/src/errors.rs index 2736cb563..900837188 100644 --- a/crates/store/src/errors.rs +++ b/crates/store/src/errors.rs @@ -48,6 +48,8 @@ pub enum DatabaseError { IoError(#[from] io::Error), #[error("Account error: {0}")] AccountError(#[from] AccountError), + #[error("Block error: {0}")] + BlockError(#[from] BlockError), #[error("Note error: {0}")] NoteError(#[from] NoteError), #[error("Migration error: {0}")] @@ -167,8 +169,6 @@ pub enum ApplyBlockError { NewBlockInvalidNullifierRoot, #[error("Duplicated nullifiers {0:?}")] DuplicatedNullifiers(Vec), - #[error("Unable to create proof for note: {0}")] - UnableToCreateProofForNote(MerkleError), #[error("Block applying was broken because of closed channel on database side: {0}")] BlockApplyingBrokenBecauseOfClosedChannel(RecvError), #[error("Failed to create notes tree: {0}")] diff --git a/crates/store/src/genesis.rs b/crates/store/src/genesis.rs index a77a56a29..5bfea4f8f 100644 --- a/crates/store/src/genesis.rs +++ b/crates/store/src/genesis.rs @@ -2,9 +2,8 @@ use miden_objects::{ accounts::{delta::AccountUpdateDetails, Account}, block::{Block, BlockAccountUpdate}, crypto::merkle::{EmptySubtreeRoots, MmrPeaks, SimpleSmt, Smt}, - notes::NOTE_LEAF_DEPTH, utils::serde::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}, - BlockHeader, Digest, ACCOUNT_TREE_DEPTH, GENESIS_BLOCK, + BlockHeader, Digest, ACCOUNT_TREE_DEPTH, BLOCK_NOTE_TREE_DEPTH, GENESIS_BLOCK, }; use crate::errors::GenesisError; @@ -59,7 +58,7 @@ impl GenesisState { MmrPeaks::new(0, Vec::new()).unwrap().hash_peaks(), account_smt.root(), Smt::default().root(), - *EmptySubtreeRoots::entry(NOTE_LEAF_DEPTH, 0), + *EmptySubtreeRoots::entry(BLOCK_NOTE_TREE_DEPTH, 0), Digest::default(), Digest::default(), Digest::default(), diff --git a/crates/store/src/state.rs b/crates/store/src/state.rs index b36e1884a..0ae2b8bb8 100644 --- a/crates/store/src/state.rs +++ b/crates/store/src/state.rs @@ -283,9 +283,7 @@ impl State { note => return Err(ApplyBlockError::InvalidOutputNoteType(note.clone())), }; - let merkle_path = note_tree - .get_note_path(note_index) - .map_err(ApplyBlockError::UnableToCreateProofForNote)?; + let merkle_path = note_tree.get_note_path(note_index); Ok(NoteRecord { block_num, From f263955301044b0838e2a702890d377fca6be5e0 Mon Sep 17 00:00:00 2001 From: Tomas Rodriguez Dala <43424983+tomyrd@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:43:32 -0300 Subject: [PATCH 14/37] fix: update `miden-base` branch (#497) --- Cargo.lock | 6 +++--- Cargo.toml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 709cd69dc..7a97bfe3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1788,7 +1788,7 @@ dependencies = [ [[package]] name = "miden-lib" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=polydez-note-tree-refactor#48e5f4743c4ff2e842296a963be25fc8b071d0f6" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#76a6635593ca168eda4517061ee0b4b845ad1c0f" dependencies = [ "miden-assembly", "miden-objects", @@ -1979,7 +1979,7 @@ dependencies = [ [[package]] name = "miden-objects" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=polydez-note-tree-refactor#48e5f4743c4ff2e842296a963be25fc8b071d0f6" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#76a6635593ca168eda4517061ee0b4b845ad1c0f" dependencies = [ "miden-assembly", "miden-core", @@ -2050,7 +2050,7 @@ dependencies = [ [[package]] name = "miden-tx" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=polydez-note-tree-refactor#48e5f4743c4ff2e842296a963be25fc8b071d0f6" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#76a6635593ca168eda4517061ee0b4b845ad1c0f" dependencies = [ "miden-lib", "miden-objects", diff --git a/Cargo.toml b/Cargo.toml index 5afc96980..7e2f0c5cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ readme = "README.md" [workspace.dependencies] miden-air = { version = "0.10", default-features = false } -miden-lib = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "polydez-note-tree-refactor"} +miden-lib = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next"} miden-node-block-producer = { path = "crates/block-producer", version = "0.6" } miden-node-faucet = { path = "bin/faucet", version = "0.6" } miden-node-proto = { path = "crates/proto", version = "0.6" } @@ -35,10 +35,10 @@ miden-node-rpc-proto = { path = "crates/rpc-proto", version = "0.6" } miden-node-store = { path = "crates/store", version = "0.6" } miden-node-test-macro = { path = "crates/test-macro" } miden-node-utils = { path = "crates/utils", version = "0.6" } -miden-objects = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "polydez-note-tree-refactor" } +miden-objects = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } miden-processor = { version = "0.10" } miden-stdlib = { version = "0.10", default-features = false } -miden-tx = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "polydez-note-tree-refactor" } +miden-tx = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } prost = { version = "0.13" } thiserror = { version = "1.0" } tokio = { version = "1.40" } From 881b6e59d04dfb95755a5eb047e2a52f46a47615 Mon Sep 17 00:00:00 2001 From: igamigo Date: Tue, 17 Sep 2024 19:47:05 -0300 Subject: [PATCH 15/37] chore: Update to miden-base's next (#498) * chore: Update to miden-base's next * chore: Lints * Correct genesis block kernel root * Remove error trace on faucet --- Cargo.lock | 30 +++++++++++++++--------------- bin/faucet/src/config.rs | 12 +++--------- config/miden-faucet.toml | 1 - crates/store/src/db/tests.rs | 2 +- crates/store/src/genesis.rs | 3 ++- 5 files changed, 21 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a97bfe3e..089948783 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -330,15 +330,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" @@ -620,9 +620,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.18" +version = "1.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" +checksum = "45bcde016d64c21da4be18b655631e5ab6d3107607e71a73a9f53eb48aae23fb" dependencies = [ "jobserver", "libc", @@ -1345,9 +1345,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1788,7 +1788,7 @@ dependencies = [ [[package]] name = "miden-lib" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#76a6635593ca168eda4517061ee0b4b845ad1c0f" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#c1fe049db8c512d14b749a5a2e3b22001fd10b5a" dependencies = [ "miden-assembly", "miden-objects", @@ -1979,7 +1979,7 @@ dependencies = [ [[package]] name = "miden-objects" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#76a6635593ca168eda4517061ee0b4b845ad1c0f" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#c1fe049db8c512d14b749a5a2e3b22001fd10b5a" dependencies = [ "miden-assembly", "miden-core", @@ -2050,7 +2050,7 @@ dependencies = [ [[package]] name = "miden-tx" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#76a6635593ca168eda4517061ee0b4b845ad1c0f" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#c1fe049db8c512d14b749a5a2e3b22001fd10b5a" dependencies = [ "miden-lib", "miden-objects", @@ -3327,9 +3327,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" dependencies = [ "indexmap 2.5.0", "serde", @@ -3608,9 +3608,9 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] diff --git a/bin/faucet/src/config.rs b/bin/faucet/src/config.rs index e19eafa2b..16ce094eb 100644 --- a/bin/faucet/src/config.rs +++ b/bin/faucet/src/config.rs @@ -1,7 +1,4 @@ -use std::{ - fmt::{Display, Formatter}, - path::PathBuf, -}; +use std::fmt::{Display, Formatter}; use miden_node_utils::config::{Endpoint, DEFAULT_FAUCET_SERVER_PORT, DEFAULT_NODE_RPC_PORT}; use serde::{Deserialize, Serialize}; @@ -18,8 +15,6 @@ pub struct FaucetConfig { pub node_url: String, /// Timeout for RPC requests in milliseconds pub timeout_ms: u64, - /// Location to store database files - pub database_filepath: PathBuf, /// Possible options on the amount of asset that should be dispersed on each faucet request pub asset_amount_options: Vec, /// Token symbol of the generated fungible asset @@ -39,8 +34,8 @@ impl FaucetConfig { impl Display for FaucetConfig { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!( - "{{ endpoint: \"{}\", database_filepath: {:?}, asset_amount_options: {:?}, token_symbol: {}, decimals: {}, max_supply: {} }}", - self.endpoint, self.database_filepath, self.asset_amount_options, self.token_symbol, self.decimals, self.max_supply + "{{ endpoint: \"{}\", asset_amount_options: {:?}, token_symbol: {}, decimals: {}, max_supply: {} }}", + self.endpoint, self.asset_amount_options, self.token_symbol, self.decimals, self.max_supply )) } } @@ -51,7 +46,6 @@ impl Default for FaucetConfig { endpoint: Endpoint::localhost(DEFAULT_FAUCET_SERVER_PORT), node_url: Endpoint::localhost(DEFAULT_NODE_RPC_PORT).to_string(), timeout_ms: 10000, - database_filepath: PathBuf::from("store.sqlite3"), asset_amount_options: vec![100, 500, 1000], token_symbol: "POL".to_string(), decimals: 8, diff --git a/config/miden-faucet.toml b/config/miden-faucet.toml index 514ed98aa..a9fdc1428 100644 --- a/config/miden-faucet.toml +++ b/config/miden-faucet.toml @@ -1,5 +1,4 @@ endpoint = { host = "localhost", port = 8080 } -database_filepath = "store.sqlite3" node_url = "http://localhost:57291" timeout_ms = 10000 diff --git a/crates/store/src/db/tests.rs b/crates/store/src/db/tests.rs index dad6eaacb..f33d258bb 100644 --- a/crates/store/src/db/tests.rs +++ b/crates/store/src/db/tests.rs @@ -990,5 +990,5 @@ pub fn mock_account_code() -> AccountCode { add end "; - AccountCode::compile(account_code, TransactionKernel::assembler()).unwrap() + AccountCode::compile(account_code, TransactionKernel::assembler(), false).unwrap() } diff --git a/crates/store/src/genesis.rs b/crates/store/src/genesis.rs index 5bfea4f8f..a19c6c882 100644 --- a/crates/store/src/genesis.rs +++ b/crates/store/src/genesis.rs @@ -1,3 +1,4 @@ +use miden_lib::transaction::TransactionKernel; use miden_objects::{ accounts::{delta::AccountUpdateDetails, Account}, block::{Block, BlockAccountUpdate}, @@ -60,7 +61,7 @@ impl GenesisState { Smt::default().root(), *EmptySubtreeRoots::entry(BLOCK_NOTE_TREE_DEPTH, 0), Digest::default(), - Digest::default(), + TransactionKernel::kernel_root(), Digest::default(), self.timestamp, ); From 0cd2228d24e859fa16a670c4b6cf2c08fb84324a Mon Sep 17 00:00:00 2001 From: Christina <156356273+cratiu222@users.noreply.github.com> Date: Wed, 18 Sep 2024 13:34:39 +0300 Subject: [PATCH 16/37] docs: fix typos (#500) --- README.md | 2 +- crates/proto/src/generated/requests.rs | 6 +++--- crates/rpc-proto/proto/requests.proto | 6 +++--- proto/requests.proto | 6 +++--- scripts/check-changelog.sh | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 4afd274f5..6067d32b9 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This repository holds the Miden node; that is, the software which processes tran ### Status -The Miden node is still under heavy development and the project can be considered to be in an _alpha_ stage. Many features are yet to be implemented and there is a number of limitations which we will lift in the near future. +The Miden node is still under heavy development and the project can be considered to be in an _alpha_ stage. Many features are yet to be implemented and there are a number of limitations which we will lift in the near future. At this point, we are developing the Miden node for a centralized operator. As such, the work does not yet include components such as P2P networking and consensus. These will be added in the future. diff --git a/crates/proto/src/generated/requests.rs b/crates/proto/src/generated/requests.rs index b912e0442..e0b1dc089 100644 --- a/crates/proto/src/generated/requests.rs +++ b/crates/proto/src/generated/requests.rs @@ -28,7 +28,7 @@ pub struct CheckNullifiersRequest { pub struct GetBlockHeaderByNumberRequest { /// The block number of the target block. /// - /// If not provided, means latest know block. + /// If not provided, means latest known block. #[prost(uint32, optional, tag = "1")] pub block_num: ::core::option::Option, /// Whether or not to return authentication data for the block header. @@ -37,7 +37,7 @@ pub struct GetBlockHeaderByNumberRequest { } /// State synchronization request. /// -/// Specifies state updates the client is intersted in. The server will return the first block which +/// Specifies state updates the client is interested in. The server will return the first block which /// contains a note matching `note_tags` or the chain tip. And the corresponding updates to /// `nullifiers` and `account_ids` for that block range. #[derive(Clone, PartialEq, ::prost::Message)] @@ -64,7 +64,7 @@ pub struct SyncStateRequest { } /// Note synchronization request. /// -/// Specifies note tags that client is intersted in. The server will return the first block which +/// Specifies note tags that client is interested in. The server will return the first block which /// contains a note matching `note_tags` or the chain tip. #[derive(Clone, PartialEq, ::prost::Message)] pub struct SyncNoteRequest { diff --git a/crates/rpc-proto/proto/requests.proto b/crates/rpc-proto/proto/requests.proto index 07dbe0752..a9c210a2b 100644 --- a/crates/rpc-proto/proto/requests.proto +++ b/crates/rpc-proto/proto/requests.proto @@ -29,7 +29,7 @@ message CheckNullifiersRequest { message GetBlockHeaderByNumberRequest { // The block number of the target block. // - // If not provided, means latest know block. + // If not provided, means latest known block. optional uint32 block_num = 1; // Whether or not to return authentication data for the block header. optional bool include_mmr_proof = 2; @@ -37,7 +37,7 @@ message GetBlockHeaderByNumberRequest { // State synchronization request. // -// Specifies state updates the client is intersted in. The server will return the first block which +// Specifies state updates the client is interested in. The server will return the first block which // contains a note matching `note_tags` or the chain tip. And the corresponding updates to // `nullifiers` and `account_ids` for that block range. message SyncStateRequest { @@ -63,7 +63,7 @@ message SyncStateRequest { // Note synchronization request. // -// Specifies note tags that client is intersted in. The server will return the first block which +// Specifies note tags that client is interested in. The server will return the first block which // contains a note matching `note_tags` or the chain tip. message SyncNoteRequest { // Last block known by the client. The response will contain data starting from the next block, diff --git a/proto/requests.proto b/proto/requests.proto index 07dbe0752..a9c210a2b 100644 --- a/proto/requests.proto +++ b/proto/requests.proto @@ -29,7 +29,7 @@ message CheckNullifiersRequest { message GetBlockHeaderByNumberRequest { // The block number of the target block. // - // If not provided, means latest know block. + // If not provided, means latest known block. optional uint32 block_num = 1; // Whether or not to return authentication data for the block header. optional bool include_mmr_proof = 2; @@ -37,7 +37,7 @@ message GetBlockHeaderByNumberRequest { // State synchronization request. // -// Specifies state updates the client is intersted in. The server will return the first block which +// Specifies state updates the client is interested in. The server will return the first block which // contains a note matching `note_tags` or the chain tip. And the corresponding updates to // `nullifiers` and `account_ids` for that block range. message SyncStateRequest { @@ -63,7 +63,7 @@ message SyncStateRequest { // Note synchronization request. // -// Specifies note tags that client is intersted in. The server will return the first block which +// Specifies note tags that client is interested in. The server will return the first block which // contains a note matching `note_tags` or the chain tip. message SyncNoteRequest { // Last block known by the client. The response will contain data starting from the next block, diff --git a/scripts/check-changelog.sh b/scripts/check-changelog.sh index dbf14cdbb..7d7529daa 100755 --- a/scripts/check-changelog.sh +++ b/scripts/check-changelog.sh @@ -13,7 +13,7 @@ else if git diff --exit-code "origin/${BASE_REF}" -- "${CHANGELOG_FILE}"; then >&2 echo "Changes should come with an entry in the \"CHANGELOG.md\" file. This behavior can be overridden by using the \"no changelog\" label, which is used for changes -that are trivial / explicitely stated not to require a changelog entry." +that are trivial / explicitly stated not to require a changelog entry." exit 1 fi From 790751c69e62077a80115fa9be76301ef3a2b802 Mon Sep 17 00:00:00 2001 From: Mirko <48352201+Mirko-von-Leipzig@users.noreply.github.com> Date: Thu, 19 Sep 2024 09:47:28 +0200 Subject: [PATCH 17/37] feat: add build metadata to `--version` (#495) This is intended to help with debugging non-release versions. Metadata includes git SHA and branch, rust version and architecture. --- CHANGELOG.md | 1 + Cargo.lock | 196 ++++++++++++++++++++++++++++++++ bin/faucet/Cargo.toml | 4 +- bin/faucet/build.rs | 13 ++- bin/faucet/src/main.rs | 21 +++- bin/node/Cargo.toml | 6 +- bin/node/build.rs | 9 ++ bin/node/src/main.rs | 20 +++- crates/utils/Cargo.toml | 8 ++ crates/utils/src/lib.rs | 1 + crates/utils/src/version/mod.rs | 184 ++++++++++++++++++++++++++++++ 11 files changed, 455 insertions(+), 8 deletions(-) create mode 100644 bin/node/build.rs create mode 100644 crates/utils/src/version/mod.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 42ece710b..2bbb3df8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - [BREAKING] Renamed `off-chain` and `on-chain` to `private` and `public` respectively for the account storage modes (#489). - Optimized state synchronizations by removing unnecessary fetching and parsing of note details (#462). - [BREAKING] Changed `GetAccountDetailsResponse` field to `details` (#481). +- Improve `--version` by adding build metadata (#495). ## 0.5.1 (2024-09-12) diff --git a/Cargo.lock b/Cargo.lock index 089948783..9a42d2ea9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -618,6 +618,38 @@ dependencies = [ "bytes", ] +[[package]] +name = "camino" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.23", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cc" version = "1.1.20" @@ -813,6 +845,41 @@ dependencies = [ "typenum", ] +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn", +] + [[package]] name = "deadpool" version = "0.12.1" @@ -862,6 +929,37 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "derive_builder" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" +dependencies = [ + "derive_builder_core", + "syn", +] + [[package]] name = "derive_more" version = "0.99.18" @@ -1140,6 +1238,18 @@ dependencies = [ "wasi", ] +[[package]] +name = "getset" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f636605b743120a8d32ed92fc27b6cde1a769f8f936c065151eb66f88ded513c" +dependencies = [ + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "gimli" version = "0.31.0" @@ -1366,6 +1476,12 @@ dependencies = [ "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.5.0" @@ -1974,6 +2090,8 @@ dependencies = [ "tracing", "tracing-forest", "tracing-subscriber", + "vergen", + "vergen-gitcl", ] [[package]] @@ -2282,6 +2400,15 @@ dependencies = [ "libc", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + [[package]] name = "object" version = "0.36.4" @@ -2476,6 +2603,28 @@ dependencies = [ "syn", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -2881,6 +3030,9 @@ name = "semver" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] [[package]] name = "semver-parser" @@ -3204,7 +3356,9 @@ checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "libc", "num-conv", + "num_threads", "powerfmt", "serde", "time-core", @@ -3656,6 +3810,48 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vergen" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c32e7318e93a9ac53693b6caccfb05ff22e04a44c7cf8a279051f24c09da286f" +dependencies = [ + "anyhow", + "cargo_metadata", + "derive_builder", + "getset", + "regex", + "rustc_version 0.4.1", + "rustversion", + "vergen-lib", +] + +[[package]] +name = "vergen-gitcl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bbdc9746577cb4767f218d320ee0b623d415e8130332f8f562b910b61cc2c4e" +dependencies = [ + "anyhow", + "derive_builder", + "rustversion", + "time", + "vergen", + "vergen-lib", +] + +[[package]] +name = "vergen-lib" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e06bee42361e43b60f363bad49d63798d0f42fb1768091812270eca00c784720" +dependencies = [ + "anyhow", + "derive_builder", + "getset", + "rustversion", +] + [[package]] name = "version_check" version = "0.9.5" diff --git a/bin/faucet/Cargo.toml b/bin/faucet/Cargo.toml index fc3f39978..f08e37729 100644 --- a/bin/faucet/Cargo.toml +++ b/bin/faucet/Cargo.toml @@ -21,7 +21,7 @@ actix-cors = "0.7" actix-web = "4.8" actix-web-static-files = "4.0" async-mutex = "1.4" -clap = { version = "4.5", features = ["derive"] } +clap = { version = "4.5", features = ["derive", "string"] } derive_more = "0.99" figment = { version = "0.10", features = ["toml", "env"] } miden-lib = { workspace = true, features = ["concurrent"] } @@ -39,4 +39,6 @@ tonic = { workspace = true } tracing = { workspace = true } [build-dependencies] +# Required to inject build metadata. +miden-node-utils = { workspace = true, features = ["vergen"] } static-files = "0.2" diff --git a/bin/faucet/build.rs b/bin/faucet/build.rs index c73a75b49..712bc2199 100644 --- a/bin/faucet/build.rs +++ b/bin/faucet/build.rs @@ -1,6 +1,7 @@ use std::str::FromStr; -fn main() -> std::io::Result<()> { +/// Embeds static faucet website files and generates build metadata for --version. +fn main() { // The location of our static faucet website files. let static_dir = std::path::PathBuf::from_str(std::env!("CARGO_MANIFEST_DIR")) .unwrap() @@ -8,5 +9,13 @@ fn main() -> std::io::Result<()> { .join("static"); println!("cargo::rerun-if-changed={}", static_dir.to_str().expect("Valid utf-8")); // This makes the static files available as an embedded resource. - static_files::resource_dir(static_dir).build() + static_files::resource_dir(static_dir).build().expect("Resources should build"); + + // Configures environment variables for build metadata intended for extended version + // information. + if let Err(e) = miden_node_utils::version::vergen() { + // Don't let an error here bring down the build. Build metadata will be empty which isn't a + // critical failure. + println!("cargo:warning=Failed to embed build metadata: {e:?}"); + } } diff --git a/bin/faucet/src/main.rs b/bin/faucet/src/main.rs index b29297e13..3247a4f31 100644 --- a/bin/faucet/src/main.rs +++ b/bin/faucet/src/main.rs @@ -13,7 +13,7 @@ use actix_web::{ }; use clap::{Parser, Subcommand}; use errors::FaucetError; -use miden_node_utils::config::load_config; +use miden_node_utils::{config::load_config, version::LongVersion}; use state::FaucetState; use tracing::info; @@ -32,7 +32,7 @@ const FAUCET_CONFIG_FILE_PATH: &str = "miden-faucet.toml"; // ================================================================================================ #[derive(Parser)] -#[command(version, about, long_about = None)] +#[command(version, about, long_about = None, long_version = long_version().to_string())] pub struct Cli { #[command(subcommand)] pub command: Command, @@ -129,3 +129,20 @@ async fn main() -> Result<(), FaucetError> { mod static_resources { include!(concat!(env!("OUT_DIR"), "/generated.rs")); } + +/// Generates [LongVersion] using the metadata generated by build.rs. +fn long_version() -> LongVersion { + // Use optional to allow for build script embedding failure. + LongVersion { + version: env!("CARGO_PKG_VERSION"), + sha: option_env!("VERGEN_GIT_SHA").unwrap_or_default(), + branch: option_env!("VERGEN_GIT_BRANCH").unwrap_or_default(), + dirty: option_env!("VERGEN_GIT_DIRTY").unwrap_or_default(), + features: option_env!("VERGEN_CARGO_FEATURES").unwrap_or_default(), + rust_version: option_env!("VERGEN_RUSTC_SEMVER").unwrap_or_default(), + host: option_env!("VERGEN_RUSTC_HOST_TRIPLE").unwrap_or_default(), + target: option_env!("VERGEN_CARGO_TARGET_TRIPLE").unwrap_or_default(), + opt_level: option_env!("VERGEN_CARGO_OPT_LEVEL").unwrap_or_default(), + debug: option_env!("VERGEN_CARGO_DEBUG").unwrap_or_default(), + } +} diff --git a/bin/node/Cargo.toml b/bin/node/Cargo.toml index 902f54f5b..d544f285f 100644 --- a/bin/node/Cargo.toml +++ b/bin/node/Cargo.toml @@ -19,7 +19,7 @@ tracing-forest = ["miden-node-block-producer/tracing-forest"] [dependencies] anyhow = { version = "1.0" } -clap = { version = "4.5", features = ["derive"] } +clap = { version = "4.5", features = ["derive", "string"] } miden-lib = { workspace = true, features = ["concurrent"] } miden-node-block-producer = { workspace = true } miden-node-rpc = { workspace = true } @@ -36,3 +36,7 @@ tracing-subscriber = { workspace = true } [dev-dependencies] figment = { version = "0.10", features = ["toml", "env", "test"] } miden-node-utils = { workspace = true, features = ["tracing-forest"] } + +[build-dependencies] +# Required to inject build metadata. +miden-node-utils = { workspace = true, features = ["vergen"] } diff --git a/bin/node/build.rs b/bin/node/build.rs new file mode 100644 index 000000000..ae41be148 --- /dev/null +++ b/bin/node/build.rs @@ -0,0 +1,9 @@ +fn main() { + // Configures environment variables for build metadata intended for extended version + // information. + if let Err(e) = miden_node_utils::version::vergen() { + // Don't let an error here bring down the build. Build metadata will be empty which isn't a + // critical failure. + println!("cargo:warning=Failed to embed build metadata: {e:?}"); + } +} diff --git a/bin/node/src/main.rs b/bin/node/src/main.rs index 1e04356c0..1ce93c60b 100644 --- a/bin/node/src/main.rs +++ b/bin/node/src/main.rs @@ -6,7 +6,7 @@ use commands::{init::init_config_files, start::start_node}; use miden_node_block_producer::server::BlockProducer; use miden_node_rpc::server::Rpc; use miden_node_store::server::Store; -use miden_node_utils::config::load_config; +use miden_node_utils::{config::load_config, version::LongVersion}; mod commands; mod config; @@ -22,7 +22,7 @@ const DEFAULT_GENESIS_INPUTS_PATH: &str = "genesis.toml"; // ================================================================================================ #[derive(Parser)] -#[command(version, about, long_about = None)] +#[command(version, about, long_about = None, long_version = long_version().to_string())] pub struct Cli { #[command(subcommand)] pub command: Command, @@ -137,3 +137,19 @@ async fn main() -> anyhow::Result<()> { }, } } + +/// Generates [LongVersion] using the metadata generated by build.rs. +fn long_version() -> LongVersion { + LongVersion { + version: env!("CARGO_PKG_VERSION"), + sha: option_env!("VERGEN_GIT_SHA").unwrap_or_default(), + branch: option_env!("VERGEN_GIT_BRANCH").unwrap_or_default(), + dirty: option_env!("VERGEN_GIT_DIRTY").unwrap_or_default(), + features: option_env!("VERGEN_CARGO_FEATURES").unwrap_or_default(), + rust_version: option_env!("VERGEN_RUSTC_SEMVER").unwrap_or_default(), + host: option_env!("VERGEN_RUSTC_HOST_TRIPLE").unwrap_or_default(), + target: option_env!("VERGEN_CARGO_TARGET_TRIPLE").unwrap_or_default(), + opt_level: option_env!("VERGEN_CARGO_OPT_LEVEL").unwrap_or_default(), + debug: option_env!("VERGEN_CARGO_DEBUG").unwrap_or_default(), + } +} diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml index 9f6a8fe6e..e3b4494d5 100644 --- a/crates/utils/Cargo.toml +++ b/crates/utils/Cargo.toml @@ -11,6 +11,10 @@ authors.workspace = true homepage.workspace = true repository.workspace = true +[features] +# Enables depedencies intended for build script generation of version metadata. +vergen = ["dep:vergen", "dep:vergen-gitcl"] + [dependencies] anyhow = { version = "1.0" } figment = { version = "0.10", features = ["toml", "env"] } @@ -22,3 +26,7 @@ tonic = { workspace = true } tracing = { workspace = true } tracing-forest = { version = "0.1", optional = true, features = ["chrono"] } tracing-subscriber = { workspace = true } +# Optional dependencies enabled by `vergen` feature. +# This must match the version expected by `vergen-gitcl`. +vergen = { "version" = "9.0", optional = true } +vergen-gitcl = { version = "1.0", features = ["cargo", "rustc"], optional = true } diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index 0e5191d74..b098bf2d8 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -2,3 +2,4 @@ pub mod config; pub mod errors; pub mod formatting; pub mod logging; +pub mod version; diff --git a/crates/utils/src/version/mod.rs b/crates/utils/src/version/mod.rs new file mode 100644 index 000000000..18f2c5036 --- /dev/null +++ b/crates/utils/src/version/mod.rs @@ -0,0 +1,184 @@ +#[cfg(feature = "vergen")] +pub use vergen::vergen; + +/// Contains build metadata which can be formatted into a pretty --version +/// output using its Display implementation. +/// +/// The build metadata can be embedded at compile time using the `vergen` function +/// available from the `vergen` feature. See that functions description for a list +/// of the environment variables emitted which map nicely to [LongVersion]. +/// +/// Unfortunately these values must be transferred manually by the end user since the +/// env variables are only available once the caller's build script has run - which is +/// after this crate is compiled. +pub struct LongVersion { + pub version: &'static str, + pub sha: &'static str, + pub branch: &'static str, + pub dirty: &'static str, + pub features: &'static str, + pub rust_version: &'static str, + pub host: &'static str, + pub target: &'static str, + pub opt_level: &'static str, + pub debug: &'static str, +} + +impl std::fmt::Display for LongVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let Self { + version, + mut sha, + mut branch, + dirty, + features, + rust_version, + host, + target, + opt_level, + debug, + } = self; + + let dirty = match *dirty { + "true" => "-dirty", + _ => "", + }; + + // This is the default value set by `vergen` when these values are missing. + // The git values can be missing for a published crate, and while we do attempt + // to set default values in the build.rs, its still possible for these to be skipped + // e.g. when cargo publish --allow-dirty is used. + if branch == "VERGEN_IDEMPOTENT_OUTPUT" { + branch = ""; + } + if sha == "VERGEN_IDEMPOTENT_OUTPUT" { + sha = ""; + } + + f.write_fmt(format_args!( + "{version} + +SHA: {sha}{dirty} +branch: {branch} +features: {features} +rust version: {rust_version} +target arch: {target} +host arch: {host} +opt-level: {opt_level} +debug: {debug} +" + )) + } +} + +#[cfg(feature = "vergen")] +mod vergen { + use std::path::PathBuf; + + use anyhow::{Context, Result}; + + /// Emits environment variables for build metadata intended for extended version information. + /// + /// The following environment variables are emitted: + /// + /// - `VERGEN_GIT_BRANCH` + /// - `VERGEN_GIT_SHA` + /// - `VERGEN_GIT_DIRTY` + /// - `VERGEN_RUSTC_SEMVER` + /// - `VERGEN_RUSTC_HOST_TRIPLE` + /// - `VERGEN_CARGO_TARGET_TRIPLE` + /// - `VERGEN_CARGO_FEATURES` + /// - `VERGEN_CARGO_OPT_LEVEL` + /// - `VERGEN_CARGO_DEBUG` + pub fn vergen() -> Result<()> { + if let Some(sha) = published_git_sha().context("Checking for published vcs info")? { + // git data is not available if in a published state, so we set them manually. + println!("cargo::rustc-env=VERGEN_GIT_SHA={sha}"); + println!("cargo::rustc-env=VERGEN_GIT_BRANCH=NA (published)"); + println!("cargo::rustc-env=VERGEN_GIT_DIRTY="); + + vergen_gitcl::Emitter::new() + } else { + // In a non-published state so we can expect git instructions to work. + let mut emitter = vergen_gitcl::Emitter::new(); + emitter + .add_instructions(&git_instructions()?) + .context("Adding git instructions")?; + + emitter + } + .add_instructions(&cargo_instructions()?) + .context("Adding cargo instructions")? + .add_instructions(&rustc_instructions()?) + .context("Adding rustc instructions")? + .emit() + } + + /// Normal git info is lost on `cargo publish`, which instead adds a file containing the SHA1 + /// hash. + /// + /// This function returns the short SHA value. If present, this indicates this we're in a + /// published state. + fn published_git_sha() -> Result> { + let cargo_vcs_info = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(".cargo_vcs_info.json"); + if cargo_vcs_info.exists() { + // The file is small so reading to string is acceptable. + let contents = std::fs::read_to_string(cargo_vcs_info).context("Reading vcs info")?; + + // File format: + // { + // "git": { + // "sha1": "9d48046e9654d93a86212e77d6c92f14c95de44b" + // }, + // "path_in_vcs": "bin/node" + // } + let offset = contents.find(r#""sha1""#).context("Searching for sha1 property")? + + r#""sha1""#.len(); + + let sha1 = contents[offset + 1..] + .chars() + // Find and skip opening quote. + .skip_while(|&c| c != '"') + .skip(1) + // Take until closing quote. + .take_while(|&c| c != '"') + // Short SHA format is 7 digits. + .take(7) + .collect(); + + Ok(Some(sha1)) + } else { + Ok(None) + } + } + + fn git_instructions() -> Result { + const INCLUDE_UNTRACKED: bool = true; + const SHORT_SHA: bool = true; + + vergen_gitcl::GitclBuilder::default() + .branch(true) + .dirty(INCLUDE_UNTRACKED) + .sha(SHORT_SHA) + .build() + .context("Building git instructions") + } + + fn cargo_instructions() -> Result { + vergen_gitcl::CargoBuilder::default() + .debug(true) + .features(true) + .target_triple(true) + .opt_level(true) + .build() + .context("Building git instructions") + } + + fn rustc_instructions() -> Result { + vergen_gitcl::RustcBuilder::default() + .semver(true) + .host_triple(true) + .build() + .context("Building rustc instructions") + } +} From 973c6ef9c180a1328cf4e904170e8ec0904d5d93 Mon Sep 17 00:00:00 2001 From: Santiago Pittella <87827390+SantiagoPittella@users.noreply.github.com> Date: Wed, 25 Sep 2024 03:52:10 -0300 Subject: [PATCH 18/37] docs: fix readme removing --path option from installing command (#505) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6067d32b9..614e749d4 100644 --- a/README.md +++ b/README.md @@ -82,13 +82,13 @@ You can also use `cargo` to compile the node from the source code if for some re ```sh # Install from a specific branch -cargo install --locked --path bin/miden --git https://github.com/0xPolygonMiden/miden-node --branch +cargo install --locked --git https://github.com/0xPolygonMiden/miden-node miden-node --branch # Install a specific tag -cargo install --locked --path bin/miden --git https://github.com/0xPolygonMiden/miden-node --tag +cargo install --locked --git https://github.com/0xPolygonMiden/miden-node miden-node --tag # Install a specific git revision -cargo install --locked --path bin/miden --git https://github.com/0xPolygonMiden/miden-node --rev +cargo install --locked --git https://github.com/0xPolygonMiden/miden-node miden-node --rev ``` More information on the various options can be found [here](https://doc.rust-lang.org/cargo/commands/cargo-install.html#install-options). From 10df0e28b8b48210aeeed0a6b049772d17d2b632 Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Fri, 27 Sep 2024 08:53:03 +0500 Subject: [PATCH 19/37] chore: added transaction number limit and updated tests to the limits introduced in `miden-objects` (#503) --- CHANGELOG.md | 1 + Cargo.lock | 213 ++++++++---------- .../block-producer/src/batch_builder/batch.rs | 13 +- .../src/batch_builder/tests/mod.rs | 9 +- .../src/block_builder/prover/tests.rs | 8 +- crates/block-producer/src/errors.rs | 23 +- crates/block-producer/src/server/mod.rs | 8 +- crates/block-producer/src/txqueue/mod.rs | 12 +- crates/proto/build.rs | 2 +- crates/proto/src/generated/block_producer.rs | 43 ++-- crates/proto/src/generated/rpc.rs | 70 +++--- crates/proto/src/generated/store.rs | 88 ++++---- crates/rpc/src/server/mod.rs | 10 +- crates/store/src/server/mod.rs | 10 +- 14 files changed, 271 insertions(+), 239 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bbb3df8f..d8f36a013 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Optimized state synchronizations by removing unnecessary fetching and parsing of note details (#462). - [BREAKING] Changed `GetAccountDetailsResponse` field to `details` (#481). - Improve `--version` by adding build metadata (#495). +- [BREAKING] Introduced additional limits for note/account number (#503). ## 0.5.1 (2024-09-12) diff --git a/Cargo.lock b/Cargo.lock index 9a42d2ea9..432510cf6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -388,9 +388,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.82" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", @@ -414,15 +414,15 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +checksum = "8f43644eed690f5374f1af436ecd6aea01cd201f6fbdf0178adaf6907afb2cec" dependencies = [ "async-trait", "axum-core", @@ -440,16 +440,16 @@ dependencies = [ "rustversion", "serde", "sync_wrapper 1.0.1", - "tower", + "tower 0.5.1", "tower-layer", "tower-service", ] [[package]] name = "axum-core" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +checksum = "5e6b8ba012a258d63c9adfa28b9ddcf66149da6f986c5b5452e629d5ee64bf00" dependencies = [ "async-trait", "bytes", @@ -460,7 +460,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper 0.1.2", + "sync_wrapper 1.0.1", "tower-layer", "tower-service", ] @@ -605,9 +605,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "bytestring" @@ -652,9 +652,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.20" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45bcde016d64c21da4be18b655631e5ab6d3107607e71a73a9f53eb48aae23fb" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" dependencies = [ "jobserver", "libc", @@ -713,9 +713,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" dependencies = [ "clap_builder", "clap_derive", @@ -723,9 +723,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" dependencies = [ "anstream", "anstyle", @@ -735,9 +735,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", @@ -1119,9 +1119,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.33" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", "miniz_oxide", @@ -1238,18 +1238,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "getset" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f636605b743120a8d32ed92fc27b6cde1a769f8f936c065151eb66f88ded513c" -dependencies = [ - "proc-macro-error2", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "gimli" version = "0.31.0" @@ -1435,9 +1423,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" dependencies = [ "bytes", "futures-channel", @@ -1448,7 +1436,6 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", - "tower", "tower-service", "tracing", ] @@ -1649,9 +1636,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libloading" @@ -1732,18 +1719,18 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "logos" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1ceb190eb9bdeecdd8f1ad6a71d6d632a50905948771718741b5461fb01e13" +checksum = "1c6b6e02facda28ca5fb8dbe4b152496ba3b1bd5a4b40bb2b1b2d8ad74e0f39b" dependencies = [ "logos-derive", ] [[package]] name = "logos-codegen" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90be66cb7bd40cb5cc2e9cfaf2d1133b04a3d93b72344267715010a466e0915a" +checksum = "b32eb6b5f26efacd015b000bfc562186472cd9b34bdba3f6b264e2a052676d10" dependencies = [ "beef", "fnv", @@ -1756,9 +1743,9 @@ dependencies = [ [[package]] name = "logos-derive" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45154231e8e96586b39494029e58f12f8ffcb5ecf80333a603a13aa205ea8cbd" +checksum = "3e5d0c5463c911ef55624739fc353238b4e310f0144be1f875dc42fec6bfd5ec" dependencies = [ "logos-codegen", ] @@ -1849,9 +1836,9 @@ dependencies = [ [[package]] name = "miden-crypto" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a69f8362ca496a79c88cf8e5b9b349bf9c6ed49fa867d0548e670afc1f3fca5" +checksum = "825fc5d2e4c951f45da54da2d0d23071918d966133f85dbc219694e0b9a1e141" dependencies = [ "blake3", "cc", @@ -1904,11 +1891,12 @@ dependencies = [ [[package]] name = "miden-lib" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#c1fe049db8c512d14b749a5a2e3b22001fd10b5a" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#c146bfd13484cbfd10b51d24845686b85b57fa21" dependencies = [ "miden-assembly", "miden-objects", "miden-stdlib", + "regex", ] [[package]] @@ -2097,7 +2085,7 @@ dependencies = [ [[package]] name = "miden-objects" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#c1fe049db8c512d14b749a5a2e3b22001fd10b5a" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#c146bfd13484cbfd10b51d24845686b85b57fa21" dependencies = [ "miden-assembly", "miden-core", @@ -2168,7 +2156,7 @@ dependencies = [ [[package]] name = "miden-tx" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#c1fe049db8c512d14b749a5a2e3b22001fd10b5a" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#c146bfd13484cbfd10b51d24845686b85b57fa21" dependencies = [ "miden-lib", "miden-objects", @@ -2568,9 +2556,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "powerfmt" @@ -2603,28 +2591,6 @@ dependencies = [ "syn", ] -[[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "proc-macro-error2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" -dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "proc-macro2" version = "1.0.86" @@ -2669,9 +2635,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2ecbe40f08db5c006b5764a2645f7f3f141ce756412ac9e1dd6087e6d32995" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" dependencies = [ "bytes", "prost-derive", @@ -2679,9 +2645,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8650aabb6c35b860610e9cff5dc1af886c9e25073b7b1712a68972af4281302" +checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15" dependencies = [ "bytes", "heck", @@ -2700,9 +2666,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" +checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" dependencies = [ "anyhow", "itertools 0.13.0", @@ -2726,9 +2692,9 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60caa6738c7369b940c3d49246a8d1749323674c65cb13010134f5c9bad5b519" +checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670" dependencies = [ "prost", ] @@ -2836,9 +2802,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" +checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b" dependencies = [ "bitflags", ] @@ -3074,9 +3040,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -3320,18 +3286,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", @@ -3481,9 +3447,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.21" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap 2.5.0", "serde", @@ -3494,9 +3460,9 @@ dependencies = [ [[package]] name = "tonic" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f6ba989e4b2c58ae83d862d3a3e27690b6e3ae630d0deb59f3697f32aa88ad" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" dependencies = [ "async-stream", "async-trait", @@ -3516,7 +3482,7 @@ dependencies = [ "socket2", "tokio", "tokio-stream", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", "tracing", @@ -3524,22 +3490,23 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4ee8877250136bd7e3d2331632810a4df4ea5e004656990d8d66d2f5ee8a67" +checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11" dependencies = [ "prettyplease", "proc-macro2", "prost-build", + "prost-types", "quote", "syn", ] [[package]] name = "tonic-web" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b904b18f914fe88913a9f0d750065b39c9c497e4b2aa05148f2c29a724145541" +checksum = "5299dd20801ad736dccb4a5ea0da7376e59cd98f213bf1c3d478cf53f4834b58" dependencies = [ "base64", "bytes", @@ -3575,6 +3542,20 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-http" version = "0.5.2" @@ -3771,15 +3752,15 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "url" @@ -3812,14 +3793,13 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vergen" -version = "9.0.0" +version = "9.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c32e7318e93a9ac53693b6caccfb05ff22e04a44c7cf8a279051f24c09da286f" +checksum = "349ed9e45296a581f455bc18039878f409992999bc1d5da12a6800eb18c8752f" dependencies = [ "anyhow", "cargo_metadata", "derive_builder", - "getset", "regex", "rustc_version 0.4.1", "rustversion", @@ -3828,9 +3808,9 @@ dependencies = [ [[package]] name = "vergen-gitcl" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bbdc9746577cb4767f218d320ee0b623d415e8130332f8f562b910b61cc2c4e" +checksum = "2a3a7f91caabecefc3c249fd864b11d4abe315c166fbdb568964421bccfd2b7a" dependencies = [ "anyhow", "derive_builder", @@ -3842,13 +3822,12 @@ dependencies = [ [[package]] name = "vergen-lib" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e06bee42361e43b60f363bad49d63798d0f42fb1768091812270eca00c784720" +checksum = "229eaddb0050920816cf051e619affaf18caa3dd512de8de5839ccbc8e53abb0" dependencies = [ "anyhow", "derive_builder", - "getset", "rustversion", ] @@ -4221,9 +4200,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -4266,9 +4245,9 @@ dependencies = [ [[package]] name = "winter-math" -version = "0.9.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "004f85bb051ce986ec0b9a2bd90aaf81b83e3c67464becfdf7db31f14c1019ba" +checksum = "5b0e685b3b872d82e58a86519294a814b7bc7a4d3cd2c93570a7d80c0c5a1aba" dependencies = [ "winter-utils", ] @@ -4321,9 +4300,9 @@ dependencies = [ [[package]] name = "winter-utils" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d71ec2c97685c7e7460a30e27f955d26b8426e7c2db0ddb55a6e0537141f53" +checksum = "961e81e9388877a25db1c034ba38253de2055f569633ae6a665d857a0556391b" dependencies = [ "rayon", ] diff --git a/crates/block-producer/src/batch_builder/batch.rs b/crates/block-producer/src/batch_builder/batch.rs index 8ab314e3b..e8a13fb36 100644 --- a/crates/block-producer/src/batch_builder/batch.rs +++ b/crates/block-producer/src/batch_builder/batch.rs @@ -10,7 +10,8 @@ use miden_objects::{ crypto::hash::blake::{Blake3Digest, Blake3_256}, notes::{NoteHeader, NoteId, Nullifier}, transaction::{InputNoteCommitment, OutputNote, TransactionId}, - AccountDeltaError, Digest, MAX_NOTES_PER_BATCH, + AccountDeltaError, Digest, MAX_ACCOUNTS_PER_BATCH, MAX_INPUT_NOTES_PER_BATCH, + MAX_OUTPUT_NOTES_PER_BATCH, }; use tracing::instrument; @@ -118,6 +119,10 @@ impl TransactionBatch { } } + if updated_accounts.len() > MAX_ACCOUNTS_PER_BATCH { + return Err(BuildBatchError::TooManyAccountsInBatch(txs)); + } + // Populate batch produced nullifiers and match output notes with corresponding // unauthenticated input notes in the same batch, which are removed from the unauthenticated // input notes set. @@ -150,9 +155,13 @@ impl TransactionBatch { input_notes.push(input_note) } + if input_notes.len() > MAX_INPUT_NOTES_PER_BATCH { + return Err(BuildBatchError::TooManyInputNotes(input_notes.len(), txs)); + } + let output_notes = output_notes.into_notes(); - if output_notes.len() > MAX_NOTES_PER_BATCH { + if output_notes.len() > MAX_OUTPUT_NOTES_PER_BATCH { return Err(BuildBatchError::TooManyNotesCreated(output_notes.len(), txs)); } diff --git a/crates/block-producer/src/batch_builder/tests/mod.rs b/crates/block-producer/src/batch_builder/tests/mod.rs index 651897fa8..1e0012f1c 100644 --- a/crates/block-producer/src/batch_builder/tests/mod.rs +++ b/crates/block-producer/src/batch_builder/tests/mod.rs @@ -303,12 +303,13 @@ async fn test_block_builder_fails_if_notes_are_missing() { let batch = TransactionBatch::new(txs.clone(), Default::default()).unwrap(); let build_block_result = batch_builder.block_builder.build_block(&[batch]).await; + + let mut expected_missing_notes = vec![notes[4].id(), notes[5].id()]; + expected_missing_notes.sort(); + assert_eq!( build_block_result, - Err(BuildBlockError::UnauthenticatedNotesNotFound(vec![ - notes[4].id(), - notes[5].id() - ])) + Err(BuildBlockError::UnauthenticatedNotesNotFound(expected_missing_notes)) ); } diff --git a/crates/block-producer/src/block_builder/prover/tests.rs b/crates/block-producer/src/block_builder/prover/tests.rs index 96959f4a8..09f98d787 100644 --- a/crates/block-producer/src/block_builder/prover/tests.rs +++ b/crates/block-producer/src/block_builder/prover/tests.rs @@ -43,7 +43,7 @@ fn test_block_witness_validation_inconsistent_account_ids() { let account_id_3 = AccountId::new_unchecked(Felt::new(ACCOUNT_ID_OFF_CHAIN_SENDER + 2)); let block_inputs_from_store: BlockInputs = { - let block_header = BlockHeader::mock(0, None, None, &[]); + let block_header = BlockHeader::mock(0, None, None, &[], Default::default()); let chain_peaks = MmrPeaks::new(0, Vec::new()).unwrap(); let accounts = BTreeMap::from_iter(vec![ @@ -107,7 +107,7 @@ fn test_block_witness_validation_inconsistent_account_hashes() { Digest::new([Felt::new(4u64), Felt::new(3u64), Felt::new(2u64), Felt::new(1u64)]); let block_inputs_from_store: BlockInputs = { - let block_header = BlockHeader::mock(0, None, None, &[]); + let block_header = BlockHeader::mock(0, None, None, &[], Default::default()); let chain_peaks = MmrPeaks::new(0, Vec::new()).unwrap(); let accounts = BTreeMap::from_iter(vec![ @@ -206,7 +206,7 @@ fn test_block_witness_multiple_batches_per_account() { )]); let block_inputs_from_store: BlockInputs = { - let block_header = BlockHeader::mock(0, None, None, &[]); + let block_header = BlockHeader::mock(0, None, None, &[], Default::default()); let chain_peaks = MmrPeaks::new(0, Vec::new()).unwrap(); let x_witness = AccountWitness { @@ -623,7 +623,7 @@ fn test_block_witness_validation_inconsistent_nullifiers() { Nullifier::from([101_u32.into(), 102_u32.into(), 103_u32.into(), 104_u32.into()]); let block_inputs_from_store: BlockInputs = { - let block_header = BlockHeader::mock(0, None, None, &[]); + let block_header = BlockHeader::mock(0, None, None, &[], Default::default()); let chain_peaks = MmrPeaks::new(0, Vec::new()).unwrap(); let accounts = batches diff --git a/crates/block-producer/src/errors.rs b/crates/block-producer/src/errors.rs index 6b32dc549..717a29268 100644 --- a/crates/block-producer/src/errors.rs +++ b/crates/block-producer/src/errors.rs @@ -5,7 +5,8 @@ use miden_objects::{ crypto::merkle::{MerkleError, MmrError}, notes::{NoteId, Nullifier}, transaction::{ProvenTransaction, TransactionId}, - AccountDeltaError, Digest, TransactionInputError, MAX_BATCHES_PER_BLOCK, MAX_NOTES_PER_BATCH, + AccountDeltaError, Digest, TransactionInputError, MAX_ACCOUNTS_PER_BATCH, + MAX_BATCHES_PER_BLOCK, MAX_INPUT_NOTES_PER_BATCH, MAX_OUTPUT_NOTES_PER_BATCH, }; use miden_processor::ExecutionError; use thiserror::Error; @@ -67,9 +68,25 @@ pub enum AddTransactionError { /// queue can re-queue them. #[derive(Debug, PartialEq, Eq, Error)] pub enum BuildBatchError { - #[error("Too many notes in the batch. Got: {0}, max: {}", MAX_NOTES_PER_BATCH)] + #[error( + "Too many input notes in the batch. Got: {0}, limit: {}", + MAX_INPUT_NOTES_PER_BATCH + )] + TooManyInputNotes(usize, Vec), + + #[error( + "Too many notes created in the batch. Got: {0}, limit: {}", + MAX_OUTPUT_NOTES_PER_BATCH + )] TooManyNotesCreated(usize, Vec), + #[error( + "Too many account updates in the batch. Got: {}, limit: {}", + .0.len(), + MAX_ACCOUNTS_PER_BATCH + )] + TooManyAccountsInBatch(Vec), + #[error("Failed to create notes SMT: {0}")] NotesSmtError(MerkleError, Vec), @@ -104,7 +121,9 @@ pub enum BuildBatchError { impl BuildBatchError { pub fn into_transactions(self) -> Vec { match self { + BuildBatchError::TooManyInputNotes(_, txs) => txs, BuildBatchError::TooManyNotesCreated(_, txs) => txs, + BuildBatchError::TooManyAccountsInBatch(txs) => txs, BuildBatchError::NotesSmtError(_, txs) => txs, BuildBatchError::NotePathsError(_, txs) => txs, BuildBatchError::DuplicateUnauthenticatedNote(_, txs) => txs, diff --git a/crates/block-producer/src/server/mod.rs b/crates/block-producer/src/server/mod.rs index 46a19f925..e81471804 100644 --- a/crates/block-producer/src/server/mod.rs +++ b/crates/block-producer/src/server/mod.rs @@ -28,9 +28,11 @@ type Api = api::BlockProducerApi< >; /// Represents an initialized block-producer component where the RPC connection is open, -/// but not yet actively responding to requests. Separating the connection binding -/// from the server spawning allows the caller to connect other components to the -/// store without resorting to sleeps or other mechanisms to spawn dependent components. +/// but not yet actively responding to requests. +/// +/// Separating the connection binding from the server spawning allows the caller to connect other +/// components to the store without resorting to sleeps or other mechanisms to spawn dependent +/// components. pub struct BlockProducer { api_service: api_server::ApiServer, listener: TcpListener, diff --git a/crates/block-producer/src/txqueue/mod.rs b/crates/block-producer/src/txqueue/mod.rs index a4c10d4e8..5f5f724c5 100644 --- a/crates/block-producer/src/txqueue/mod.rs +++ b/crates/block-producer/src/txqueue/mod.rs @@ -1,7 +1,7 @@ use std::{sync::Arc, time::Duration}; use async_trait::async_trait; -use miden_objects::MAX_NOTES_PER_BATCH; +use miden_objects::MAX_OUTPUT_NOTES_PER_BATCH; use tokio::{sync::RwLock, time}; use tracing::{debug, info, info_span, instrument, Instrument}; @@ -99,17 +99,19 @@ where while !txs.is_empty() { let mut batch = Vec::with_capacity(self.options.batch_size); - let mut notes_in_batch = 0; + let mut output_notes_in_batch = 0; while let Some(tx) = txs.pop() { - notes_in_batch += tx.output_notes().num_notes(); + output_notes_in_batch += tx.output_notes().num_notes(); debug_assert!( - tx.output_notes().num_notes() <= MAX_NOTES_PER_BATCH, + tx.output_notes().num_notes() <= MAX_OUTPUT_NOTES_PER_BATCH, "Sanity check, the number of output notes of a single transaction must never be larger than the batch maximum", ); - if notes_in_batch > MAX_NOTES_PER_BATCH || batch.len() == self.options.batch_size { + if output_notes_in_batch > MAX_OUTPUT_NOTES_PER_BATCH + || batch.len() == self.options.batch_size + { // Batch would be too big in number of notes or transactions. Push the tx back // to the list of available transactions and forward the current batch. txs.push(tx); diff --git a/crates/proto/build.rs b/crates/proto/build.rs index e08074c4a..5f9c13384 100644 --- a/crates/proto/build.rs +++ b/crates/proto/build.rs @@ -59,7 +59,7 @@ fn main() -> miette::Result<()> { .file_descriptor_set_path(&file_descriptor_path) .skip_protoc_run() .out_dir(&dst_dir) - .compile_with_config(prost_config, protos, includes) + .compile_protos_with_config(prost_config, protos, includes) .into_diagnostic()?; generate_mod_rs(&dst_dir).into_diagnostic()?; diff --git a/crates/proto/src/generated/block_producer.rs b/crates/proto/src/generated/block_producer.rs index 362af881b..fefbd4351 100644 --- a/crates/proto/src/generated/block_producer.rs +++ b/crates/proto/src/generated/block_producer.rs @@ -1,7 +1,13 @@ // This file is @generated by prost-build. /// Generated client implementations. pub mod api_client { - #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] use tonic::codegen::*; use tonic::codegen::http::Uri; #[derive(Debug, Clone)] @@ -97,8 +103,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -117,7 +122,13 @@ pub mod api_client { } /// Generated server implementations. pub mod api_server { - #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with ApiServer. #[async_trait] @@ -258,17 +269,19 @@ pub mod api_server { } _ => { Box::pin(async move { - Ok( - http::Response::builder() - .status(200) - .header("grpc-status", tonic::Code::Unimplemented as i32) - .header( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ) - .body(empty_body()) - .unwrap(), - ) + let mut response = http::Response::new(empty_body()); + let headers = response.headers_mut(); + headers + .insert( + tonic::Status::GRPC_STATUS, + (tonic::Code::Unimplemented as i32).into(), + ); + headers + .insert( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ); + Ok(response) }) } } diff --git a/crates/proto/src/generated/rpc.rs b/crates/proto/src/generated/rpc.rs index 3f35dceb2..d1840c5f3 100644 --- a/crates/proto/src/generated/rpc.rs +++ b/crates/proto/src/generated/rpc.rs @@ -1,7 +1,13 @@ // This file is @generated by prost-build. /// Generated client implementations. pub mod api_client { - #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] use tonic::codegen::*; use tonic::codegen::http::Uri; #[derive(Debug, Clone)] @@ -97,8 +103,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -121,8 +126,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -148,8 +152,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -174,8 +177,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -201,8 +203,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -225,8 +226,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -250,8 +250,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -274,8 +273,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -299,8 +297,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -321,8 +318,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -336,7 +332,13 @@ pub mod api_client { } /// Generated server implementations. pub mod api_server { - #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with ApiServer. #[async_trait] @@ -978,17 +980,19 @@ pub mod api_server { } _ => { Box::pin(async move { - Ok( - http::Response::builder() - .status(200) - .header("grpc-status", tonic::Code::Unimplemented as i32) - .header( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ) - .body(empty_body()) - .unwrap(), - ) + let mut response = http::Response::new(empty_body()); + let headers = response.headers_mut(); + headers + .insert( + tonic::Status::GRPC_STATUS, + (tonic::Code::Unimplemented as i32).into(), + ); + headers + .insert( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ); + Ok(response) }) } } diff --git a/crates/proto/src/generated/store.rs b/crates/proto/src/generated/store.rs index 6d32c3219..66c49e9d9 100644 --- a/crates/proto/src/generated/store.rs +++ b/crates/proto/src/generated/store.rs @@ -1,7 +1,13 @@ // This file is @generated by prost-build. /// Generated client implementations. pub mod api_client { - #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] use tonic::codegen::*; use tonic::codegen::http::Uri; #[derive(Debug, Clone)] @@ -95,8 +101,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -119,8 +124,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -145,8 +149,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -172,8 +175,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -199,8 +201,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -226,8 +227,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -253,8 +253,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -280,8 +279,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -304,8 +302,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -329,8 +326,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -353,8 +349,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -378,8 +373,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -400,8 +394,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -424,8 +417,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -446,8 +438,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -468,8 +459,7 @@ pub mod api_client { .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -483,7 +473,13 @@ pub mod api_client { } /// Generated server implementations. pub mod api_server { - #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with ApiServer. #[async_trait] @@ -1456,17 +1452,19 @@ pub mod api_server { } _ => { Box::pin(async move { - Ok( - http::Response::builder() - .status(200) - .header("grpc-status", tonic::Code::Unimplemented as i32) - .header( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ) - .body(empty_body()) - .unwrap(), - ) + let mut response = http::Response::new(empty_body()); + let headers = response.headers_mut(); + headers + .insert( + tonic::Status::GRPC_STATUS, + (tonic::Code::Unimplemented as i32).into(), + ); + headers + .insert( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ); + Ok(response) }) } } diff --git a/crates/rpc/src/server/mod.rs b/crates/rpc/src/server/mod.rs index 9745f7378..dcef246b7 100644 --- a/crates/rpc/src/server/mod.rs +++ b/crates/rpc/src/server/mod.rs @@ -11,10 +11,12 @@ use crate::{config::RpcConfig, COMPONENT}; mod api; -/// Represents an initialized rpc component where the RPC connection is open, -/// but not yet actively responding to requests. Separating the connection binding -/// from the server spawning allows the caller to connect other components to the -/// store without resorting to sleeps or other mechanisms to spawn dependent components. +/// Represents an initialized rpc component where the RPC connection is open, but not yet actively +/// responding to requests. +/// +/// Separating the connection binding from the server spawning allows the caller to connect other +/// components to the store without resorting to sleeps or other mechanisms to spawn dependent +/// components. pub struct Rpc { api_service: api_server::ApiServer, listener: TcpListener, diff --git a/crates/store/src/server/mod.rs b/crates/store/src/server/mod.rs index 0c912193b..f73c9e9fe 100644 --- a/crates/store/src/server/mod.rs +++ b/crates/store/src/server/mod.rs @@ -10,10 +10,12 @@ use crate::{blocks::BlockStore, config::StoreConfig, db::Db, state::State, COMPO mod api; -/// Represents an initialized store component where the RPC connection is open, -/// but not yet actively responding to requests. Separating the connection binding -/// from the server spawning allows the caller to connect other components to the -/// store without resorting to sleeps or other mechanisms to spawn dependent components. +/// Represents an initialized store component where the RPC connection is open, but not yet actively +/// responding to requests. +/// +/// Separating the connection binding from the server spawning allows the caller to connect other +/// components to the store without resorting to sleeps or other mechanisms to spawn dependent +/// components. pub struct Store { api_service: api_server::ApiServer, listener: TcpListener, From 8a9aa8b0a67ddcd5d7251dd05befe67718db174f Mon Sep 17 00:00:00 2001 From: igamigo Date: Mon, 30 Sep 2024 12:07:03 -0300 Subject: [PATCH 20/37] test: Add expiration number to proven tx builder (#507) * feat: Add expiration num to mock tx builder * Revery miden-base branch * Lints --- Cargo.lock | 6 +++--- crates/block-producer/src/test_utils/proven_tx.rs | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 432510cf6..b40e17d56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1891,7 +1891,7 @@ dependencies = [ [[package]] name = "miden-lib" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#c146bfd13484cbfd10b51d24845686b85b57fa21" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#7dbd6083f49fceee41e328807805ebaef0029aef" dependencies = [ "miden-assembly", "miden-objects", @@ -2085,7 +2085,7 @@ dependencies = [ [[package]] name = "miden-objects" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#c146bfd13484cbfd10b51d24845686b85b57fa21" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#7dbd6083f49fceee41e328807805ebaef0029aef" dependencies = [ "miden-assembly", "miden-core", @@ -2156,7 +2156,7 @@ dependencies = [ [[package]] name = "miden-tx" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#c146bfd13484cbfd10b51d24845686b85b57fa21" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#7dbd6083f49fceee41e328807805ebaef0029aef" dependencies = [ "miden-lib", "miden-objects", diff --git a/crates/block-producer/src/test_utils/proven_tx.rs b/crates/block-producer/src/test_utils/proven_tx.rs index 57804c5cf..cf804d8d7 100644 --- a/crates/block-producer/src/test_utils/proven_tx.rs +++ b/crates/block-producer/src/test_utils/proven_tx.rs @@ -16,6 +16,7 @@ pub struct MockProvenTxBuilder { account_id: AccountId, initial_account_hash: Digest, final_account_hash: Digest, + expiration_block_num: u32, output_notes: Option>, input_notes: Option>, nullifiers: Option>, @@ -37,6 +38,7 @@ impl MockProvenTxBuilder { account_id, initial_account_hash, final_account_hash, + expiration_block_num: u32::MAX, output_notes: None, input_notes: None, nullifiers: None, @@ -55,6 +57,12 @@ impl MockProvenTxBuilder { self } + pub fn expiration_block_num(mut self, expiration_block_num: u32) -> Self { + self.expiration_block_num = expiration_block_num; + + self + } + pub fn output_notes(mut self, notes: Vec) -> Self { self.output_notes = Some(notes); @@ -99,6 +107,7 @@ impl MockProvenTxBuilder { self.initial_account_hash, self.final_account_hash, Digest::default(), + self.expiration_block_num, ExecutionProof::new(Proof::new_dummy(), HashFunction::Blake3_192), ) .add_input_notes(self.input_notes.unwrap_or_default()) From a0150ee24ea94e180d81a7bf04170f65a7e24514 Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Thu, 3 Oct 2024 20:59:24 +0500 Subject: [PATCH 21/37] Dropped basic wallet account from genesis file (#510) * feat: remove wallet from genesis config * fix: print message * feat: remove support of basic wallet in genesis file * docs: update CHANGELOG.md * Update CHANGELOG.md Co-authored-by: igamigo --------- Co-authored-by: igamigo --- CHANGELOG.md | 1 + bin/node/src/commands/genesis/inputs.rs | 41 ++++++--------------- bin/node/src/commands/genesis/mod.rs | 47 ++++--------------------- config/genesis.toml | 7 ---- 4 files changed, 19 insertions(+), 77 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8f36a013..db01808a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - [BREAKING] Changed `GetAccountDetailsResponse` field to `details` (#481). - Improve `--version` by adding build metadata (#495). - [BREAKING] Introduced additional limits for note/account number (#503). +- [BREAKING] Removed support for basic wallets in genesis creation (#510). ## 0.5.1 (2024-09-12) diff --git a/bin/node/src/commands/genesis/inputs.rs b/bin/node/src/commands/genesis/inputs.rs index 32a54e7d1..a400fc69f 100644 --- a/bin/node/src/commands/genesis/inputs.rs +++ b/bin/node/src/commands/genesis/inputs.rs @@ -18,18 +18,9 @@ pub struct GenesisInput { #[derive(Debug, Clone, Deserialize, Serialize)] #[serde(tag = "type")] pub enum AccountInput { - BasicWallet(BasicWalletInputs), BasicFungibleFaucet(BasicFungibleFaucetInputs), } -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct BasicWalletInputs { - pub init_seed: String, - pub auth_scheme: AuthSchemeInput, - pub auth_seed: String, - pub storage_mode: String, -} - #[derive(Debug, Clone, Deserialize, Serialize)] pub struct BasicFungibleFaucetInputs { pub init_seed: String, @@ -54,27 +45,17 @@ impl Default for GenesisInput { .duration_since(UNIX_EPOCH) .expect("Current timestamp should be greater than unix epoch") .as_secs() as u32, - accounts: Some(vec![ - AccountInput::BasicWallet(BasicWalletInputs { - init_seed: "0xa123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - .to_string(), - auth_scheme: AuthSchemeInput::RpoFalcon512, - auth_seed: "0xb123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - .to_string(), - storage_mode: "private".to_string(), - }), - AccountInput::BasicFungibleFaucet(BasicFungibleFaucetInputs { - init_seed: "0xc123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - .to_string(), - auth_scheme: AuthSchemeInput::RpoFalcon512, - auth_seed: "0xd123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - .to_string(), - token_symbol: "POL".to_string(), - decimals: 12, - max_supply: 1000000, - storage_mode: "public".to_string(), - }), - ]), + accounts: Some(vec![AccountInput::BasicFungibleFaucet(BasicFungibleFaucetInputs { + init_seed: "0xc123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + .to_string(), + auth_scheme: AuthSchemeInput::RpoFalcon512, + auth_seed: "0xd123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + .to_string(), + token_symbol: "POL".to_string(), + decimals: 12, + max_supply: 1000000, + storage_mode: "public".to_string(), + })]), } } } diff --git a/bin/node/src/commands/genesis/mod.rs b/bin/node/src/commands/genesis/mod.rs index 23d244af4..3772b1201 100644 --- a/bin/node/src/commands/genesis/mod.rs +++ b/bin/node/src/commands/genesis/mod.rs @@ -5,14 +5,11 @@ use std::{ use anyhow::{anyhow, bail, Context, Result}; pub use inputs::{AccountInput, AuthSchemeInput, GenesisInput}; -use miden_lib::{ - accounts::{faucets::create_basic_fungible_faucet, wallets::create_basic_wallet}, - AuthScheme, -}; +use miden_lib::{accounts::faucets::create_basic_fungible_faucet, AuthScheme}; use miden_node_store::genesis::GenesisState; use miden_node_utils::config::load_config; use miden_objects::{ - accounts::{Account, AccountData, AccountStorageMode, AccountType, AuthSecretKey}, + accounts::{Account, AccountData, AccountStorageMode, AuthSecretKey}, assets::TokenSymbol, crypto::{ dsa::rpo_falcon512::SecretKey, @@ -81,7 +78,7 @@ pub fn make_genesis(inputs_path: &PathBuf, output_path: &PathBuf, force: &bool) let genesis_input: GenesisInput = load_config(inputs_path).map_err(|err| { anyhow!("Failed to load {} genesis input file: {err}", inputs_path.display()) })?; - info!("Genesis input file: {} has successfully been loaded.", output_path.display()); + info!("Genesis input file: {} has successfully been loaded.", inputs_path.display()); let accounts = create_accounts(&genesis_input.accounts.unwrap_or_default(), parent_path, force)?; @@ -128,24 +125,6 @@ fn create_accounts( for account in accounts { // build offchain account data from account inputs let mut account_data = match account { - AccountInput::BasicWallet(inputs) => { - info!("Creating basic wallet account..."); - let init_seed = hex_to_bytes(&inputs.init_seed)?; - - let (auth_scheme, auth_secret_key) = - parse_auth_inputs(inputs.auth_scheme, &inputs.auth_seed)?; - - let storage_mode: AccountStorageMode = inputs.storage_mode.as_str().try_into()?; - - let (account, account_seed) = create_basic_wallet( - init_seed, - auth_scheme, - AccountType::RegularAccountImmutableCode, - storage_mode, - )?; - - AccountData::new(account, Some(account_seed), auth_secret_key) - }, AccountInput::BasicFungibleFaucet(inputs) => { info!("Creating fungible faucet account..."); let init_seed = hex_to_bytes(&inputs.init_seed)?; @@ -234,13 +213,6 @@ mod tests { version = 1 timestamp = 1672531200 - [[accounts]] - type = "BasicWallet" - init_seed = "0xa123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - auth_scheme = "RpoFalcon512" - auth_seed = "0xb123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - storage_mode = "private" - [[accounts]] type = "BasicFungibleFaucet" init_seed = "0xc123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" @@ -259,27 +231,22 @@ mod tests { make_genesis(&genesis_inputs_file_path, &genesis_dat_file_path, &true).unwrap(); let a0_file_path = PathBuf::from("accounts/account0.mac"); - let a1_file_path = PathBuf::from("accounts/account1.mac"); // assert that the genesis.dat and account files exist assert!(genesis_dat_file_path.exists()); assert!(a0_file_path.exists()); - assert!(a1_file_path.exists()); - // deserialize accounts and genesis_state + // deserialize account and genesis_state let a0 = AccountData::read(a0_file_path).unwrap(); - let a1 = AccountData::read(a1_file_path).unwrap(); - // assert that the accounts have the corresponding storage mode - assert!(!a0.account.is_public()); - assert!(a1.account.is_public()); + // assert that the account has the corresponding storage mode + assert!(a0.account.is_public()); let genesis_file_contents = fs::read(genesis_dat_file_path).unwrap(); let genesis_state = GenesisState::read_from_bytes(&genesis_file_contents).unwrap(); // build supposed genesis_state - let supposed_genesis_state = - GenesisState::new(vec![a0.account, a1.account], 1, 1672531200); + let supposed_genesis_state = GenesisState::new(vec![a0.account], 1, 1672531200); // assert that both genesis_state(s) are eq assert_eq!(genesis_state, supposed_genesis_state); diff --git a/config/genesis.toml b/config/genesis.toml index 0ee00bbda..6a77d9a77 100644 --- a/config/genesis.toml +++ b/config/genesis.toml @@ -2,13 +2,6 @@ version = 1 timestamp = 1672531200 -[[accounts]] -type = "BasicWallet" -storage_mode = "private" -init_seed = "0xa123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" -auth_scheme = "RpoFalcon512" -auth_seed = "0xb123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - [[accounts]] type = "BasicFungibleFaucet" storage_mode = "public" From a6a12fff8c1723505ed3d3eb2571035111d077fb Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Fri, 4 Oct 2024 11:12:42 +0500 Subject: [PATCH 22/37] Implemented `GetAccountProofs` endpoint (#506) * feat: implement interface in proto * feat: implement `GetAccountStates` endpoint * docs: update CHANGELOG.md * refactor: simplify endpoint, address review comments * refactor: nit fixes * refactor: address review comments * chore: update to the latest `next` of `miden-base` * refactor: rename endpoint to `GetAccountProofs` * chore: remove unnecessary dependency * fix: don't query database if `include_headers` is `false` * refactor: address review comments --- CHANGELOG.md | 1 + Cargo.lock | 6 +- crates/proto/src/domain/accounts.rs | 17 ++++- crates/proto/src/domain/merkle.rs | 6 ++ crates/proto/src/generated/account.rs | 15 +++++ crates/proto/src/generated/requests.rs | 9 +++ crates/proto/src/generated/responses.rs | 33 ++++++++++ crates/proto/src/generated/rpc.rs | 78 +++++++++++++++++++++++ crates/proto/src/generated/store.rs | 81 ++++++++++++++++++++++++ crates/rpc-proto/proto/account.proto | 11 ++++ crates/rpc-proto/proto/requests.proto | 7 +++ crates/rpc-proto/proto/responses.proto | 25 ++++++++ crates/rpc-proto/proto/rpc.proto | 1 + crates/rpc-proto/proto/store.proto | 1 + crates/rpc/src/server/api.rs | 38 +++++++++-- crates/store/src/db/mod.rs | 41 +++++++++--- crates/store/src/db/sql.rs | 42 +++++++++++-- crates/store/src/db/tests.rs | 26 ++++---- crates/store/src/errors.rs | 2 + crates/store/src/server/api.rs | 53 ++++++++++++---- crates/store/src/state.rs | 83 ++++++++++++++++++++++--- proto/account.proto | 11 ++++ proto/requests.proto | 7 +++ proto/responses.proto | 25 ++++++++ proto/rpc.proto | 1 + proto/store.proto | 1 + 26 files changed, 562 insertions(+), 59 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db01808a2..6ee919517 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Improve `--version` by adding build metadata (#495). - [BREAKING] Introduced additional limits for note/account number (#503). - [BREAKING] Removed support for basic wallets in genesis creation (#510). +- Added `GetAccountStates` endpoint (#506). ## 0.5.1 (2024-09-12) diff --git a/Cargo.lock b/Cargo.lock index b40e17d56..cf34633e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1891,7 +1891,7 @@ dependencies = [ [[package]] name = "miden-lib" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#7dbd6083f49fceee41e328807805ebaef0029aef" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#9dc06d705b8f4cae86ff08a293f379c206f13421" dependencies = [ "miden-assembly", "miden-objects", @@ -2085,7 +2085,7 @@ dependencies = [ [[package]] name = "miden-objects" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#7dbd6083f49fceee41e328807805ebaef0029aef" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#9dc06d705b8f4cae86ff08a293f379c206f13421" dependencies = [ "miden-assembly", "miden-core", @@ -2156,7 +2156,7 @@ dependencies = [ [[package]] name = "miden-tx" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#7dbd6083f49fceee41e328807805ebaef0029aef" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#9dc06d705b8f4cae86ff08a293f379c206f13421" dependencies = [ "miden-lib", "miden-objects", diff --git a/crates/proto/src/domain/accounts.rs b/crates/proto/src/domain/accounts.rs index eaea327e4..3a7de73d1 100644 --- a/crates/proto/src/domain/accounts.rs +++ b/crates/proto/src/domain/accounts.rs @@ -2,7 +2,7 @@ use std::fmt::{Debug, Display, Formatter}; use miden_node_utils::formatting::format_opt; use miden_objects::{ - accounts::{Account, AccountId}, + accounts::{Account, AccountHeader, AccountId}, crypto::{hash::rpo::RpoDigest, merkle::MerklePath}, utils::Serializable, Digest, @@ -12,8 +12,8 @@ use crate::{ errors::{ConversionError, MissingFieldHelper}, generated::{ account::{ - AccountId as AccountIdPb, AccountInfo as AccountInfoPb, - AccountSummary as AccountSummaryPb, + AccountHeader as AccountHeaderPb, AccountId as AccountIdPb, + AccountInfo as AccountInfoPb, AccountSummary as AccountSummaryPb, }, responses::{AccountBlockInputRecord, AccountTransactionInputRecord}, }, @@ -180,6 +180,17 @@ impl From for AccountTransactionInputRecord { } } +impl From for AccountHeaderPb { + fn from(from: AccountHeader) -> Self { + Self { + vault_root: Some(from.vault_root().into()), + storage_commitment: Some(from.storage_commitment().into()), + code_commitment: Some(from.code_commitment().into()), + nonce: from.nonce().into(), + } + } +} + impl TryFrom for AccountState { type Error = ConversionError; diff --git a/crates/proto/src/domain/merkle.rs b/crates/proto/src/domain/merkle.rs index 6b71d18f3..f21bec087 100644 --- a/crates/proto/src/domain/merkle.rs +++ b/crates/proto/src/domain/merkle.rs @@ -19,6 +19,12 @@ impl From<&MerklePath> for generated::merkle::MerklePath { } } +impl From for generated::merkle::MerklePath { + fn from(value: MerklePath) -> Self { + (&value).into() + } +} + impl TryFrom<&generated::merkle::MerklePath> for MerklePath { type Error = ConversionError; diff --git a/crates/proto/src/generated/account.rs b/crates/proto/src/generated/account.rs index bcf609958..fc59f1fe3 100644 --- a/crates/proto/src/generated/account.rs +++ b/crates/proto/src/generated/account.rs @@ -24,3 +24,18 @@ pub struct AccountInfo { #[prost(bytes = "vec", optional, tag = "2")] pub details: ::core::option::Option<::prost::alloc::vec::Vec>, } +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct AccountHeader { + /// Vault root hash. + #[prost(message, optional, tag = "1")] + pub vault_root: ::core::option::Option, + /// Storage root hash. + #[prost(message, optional, tag = "2")] + pub storage_commitment: ::core::option::Option, + /// Code root hash. + #[prost(message, optional, tag = "3")] + pub code_commitment: ::core::option::Option, + /// Account nonce. + #[prost(uint64, tag = "4")] + pub nonce: u64, +} diff --git a/crates/proto/src/generated/requests.rs b/crates/proto/src/generated/requests.rs index e0b1dc089..34db2cb62 100644 --- a/crates/proto/src/generated/requests.rs +++ b/crates/proto/src/generated/requests.rs @@ -148,3 +148,12 @@ pub struct GetAccountStateDeltaRequest { #[prost(fixed32, tag = "3")] pub to_block_num: u32, } +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetAccountProofsRequest { + /// List of account IDs to get states. + #[prost(message, repeated, tag = "1")] + pub account_ids: ::prost::alloc::vec::Vec, + /// Optional flag to include header in the response. `false` by default. + #[prost(bool, optional, tag = "2")] + pub include_headers: ::core::option::Option, +} diff --git a/crates/proto/src/generated/responses.rs b/crates/proto/src/generated/responses.rs index 7afa7c899..a871cbe31 100644 --- a/crates/proto/src/generated/responses.rs +++ b/crates/proto/src/generated/responses.rs @@ -195,3 +195,36 @@ pub struct GetAccountStateDeltaResponse { #[prost(bytes = "vec", optional, tag = "1")] pub delta: ::core::option::Option<::prost::alloc::vec::Vec>, } +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetAccountProofsResponse { + /// Block number at which the state of the account was returned. + #[prost(fixed32, tag = "1")] + pub block_num: u32, + /// List of account state infos for the requested account keys. + #[prost(message, repeated, tag = "2")] + pub account_proofs: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AccountProofsResponse { + /// Account ID. + #[prost(message, optional, tag = "1")] + pub account_id: ::core::option::Option, + /// Account hash. + #[prost(message, optional, tag = "2")] + pub account_hash: ::core::option::Option, + /// Authentication path from the `account_root` of the block header to the account. + #[prost(message, optional, tag = "3")] + pub account_proof: ::core::option::Option, + /// State header for public accounts. Filled only if `include_headers` flag is set to `true`. + #[prost(message, optional, tag = "4")] + pub state_header: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AccountStateHeader { + /// Account header. + #[prost(message, optional, tag = "1")] + pub header: ::core::option::Option, + /// Values of all account storage slots (max 255). + #[prost(bytes = "vec", tag = "2")] + pub storage_header: ::prost::alloc::vec::Vec, +} diff --git a/crates/proto/src/generated/rpc.rs b/crates/proto/src/generated/rpc.rs index d1840c5f3..c7181943c 100644 --- a/crates/proto/src/generated/rpc.rs +++ b/crates/proto/src/generated/rpc.rs @@ -164,6 +164,29 @@ pub mod api_client { req.extensions_mut().insert(GrpcMethod::new("rpc.Api", "GetAccountDetails")); self.inner.unary(req, path, codec).await } + pub async fn get_account_proofs( + &mut self, + request: impl tonic::IntoRequest< + super::super::requests::GetAccountProofsRequest, + >, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/rpc.Api/GetAccountProofs"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("rpc.Api", "GetAccountProofs")); + self.inner.unary(req, path, codec).await + } pub async fn get_account_state_delta( &mut self, request: impl tonic::IntoRequest< @@ -366,6 +389,13 @@ pub mod api_server { tonic::Response, tonic::Status, >; + async fn get_account_proofs( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; async fn get_account_state_delta( &self, request: tonic::Request, @@ -641,6 +671,54 @@ pub mod api_server { }; Box::pin(fut) } + "/rpc.Api/GetAccountProofs" => { + #[allow(non_camel_case_types)] + struct GetAccountProofsSvc(pub Arc); + impl< + T: Api, + > tonic::server::UnaryService< + super::super::requests::GetAccountProofsRequest, + > for GetAccountProofsSvc { + type Response = super::super::responses::GetAccountProofsResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request< + super::super::requests::GetAccountProofsRequest, + >, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_account_proofs(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetAccountProofsSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } "/rpc.Api/GetAccountStateDelta" => { #[allow(non_camel_case_types)] struct GetAccountStateDeltaSvc(pub Arc); diff --git a/crates/proto/src/generated/store.rs b/crates/proto/src/generated/store.rs index 66c49e9d9..0a9055a9a 100644 --- a/crates/proto/src/generated/store.rs +++ b/crates/proto/src/generated/store.rs @@ -188,6 +188,32 @@ pub mod api_client { .insert(GrpcMethod::new("store.Api", "GetAccountDetails")); self.inner.unary(req, path, codec).await } + pub async fn get_account_proofs( + &mut self, + request: impl tonic::IntoRequest< + super::super::requests::GetAccountProofsRequest, + >, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/store.Api/GetAccountProofs", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("store.Api", "GetAccountProofs")); + self.inner.unary(req, path, codec).await + } pub async fn get_account_state_delta( &mut self, request: impl tonic::IntoRequest< @@ -514,6 +540,13 @@ pub mod api_server { tonic::Response, tonic::Status, >; + async fn get_account_proofs( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; async fn get_account_state_delta( &self, request: tonic::Request, @@ -872,6 +905,54 @@ pub mod api_server { }; Box::pin(fut) } + "/store.Api/GetAccountProofs" => { + #[allow(non_camel_case_types)] + struct GetAccountProofsSvc(pub Arc); + impl< + T: Api, + > tonic::server::UnaryService< + super::super::requests::GetAccountProofsRequest, + > for GetAccountProofsSvc { + type Response = super::super::responses::GetAccountProofsResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request< + super::super::requests::GetAccountProofsRequest, + >, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_account_proofs(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetAccountProofsSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } "/store.Api/GetAccountStateDelta" => { #[allow(non_camel_case_types)] struct GetAccountStateDeltaSvc(pub Arc); diff --git a/crates/rpc-proto/proto/account.proto b/crates/rpc-proto/proto/account.proto index a0eb36972..8f7becff9 100644 --- a/crates/rpc-proto/proto/account.proto +++ b/crates/rpc-proto/proto/account.proto @@ -20,3 +20,14 @@ message AccountInfo { AccountSummary summary = 1; optional bytes details = 2; } + +message AccountHeader { + // Vault root hash. + digest.Digest vault_root = 1; + // Storage root hash. + digest.Digest storage_commitment = 2; + // Code root hash. + digest.Digest code_commitment = 3; + // Account nonce. + uint64 nonce = 4; +} diff --git a/crates/rpc-proto/proto/requests.proto b/crates/rpc-proto/proto/requests.proto index a9c210a2b..9f9554b48 100644 --- a/crates/rpc-proto/proto/requests.proto +++ b/crates/rpc-proto/proto/requests.proto @@ -131,3 +131,10 @@ message GetAccountStateDeltaRequest { // Block number up to which the delta is requested (inclusive). fixed32 to_block_num = 3; } + +message GetAccountProofsRequest { + // List of account IDs to get states. + repeated account.AccountId account_ids = 1; + // Optional flag to include header in the response. `false` by default. + optional bool include_headers = 2; +} diff --git a/crates/rpc-proto/proto/responses.proto b/crates/rpc-proto/proto/responses.proto index 7342294ff..7d7d00032 100644 --- a/crates/rpc-proto/proto/responses.proto +++ b/crates/rpc-proto/proto/responses.proto @@ -173,3 +173,28 @@ message GetAccountStateDeltaResponse { // The calculated `AccountStateDelta` encoded using miden native format optional bytes delta = 1; } + +message GetAccountProofsResponse { + // Block number at which the state of the account was returned. + fixed32 block_num = 1; + // List of account state infos for the requested account keys. + repeated AccountProofsResponse account_proofs = 2; +} + +message AccountProofsResponse { + // Account ID. + account.AccountId account_id = 1; + // Account hash. + digest.Digest account_hash = 2; + // Authentication path from the `account_root` of the block header to the account. + merkle.MerklePath account_proof = 3; + // State header for public accounts. Filled only if `include_headers` flag is set to `true`. + optional AccountStateHeader state_header = 4; +} + +message AccountStateHeader { + // Account header. + account.AccountHeader header = 1; + // Values of all account storage slots (max 255). + bytes storage_header = 2; +} diff --git a/crates/rpc-proto/proto/rpc.proto b/crates/rpc-proto/proto/rpc.proto index da2c2bdd0..13934b2c4 100644 --- a/crates/rpc-proto/proto/rpc.proto +++ b/crates/rpc-proto/proto/rpc.proto @@ -9,6 +9,7 @@ service Api { rpc CheckNullifiers(requests.CheckNullifiersRequest) returns (responses.CheckNullifiersResponse) {} rpc CheckNullifiersByPrefix(requests.CheckNullifiersByPrefixRequest) returns (responses.CheckNullifiersByPrefixResponse) {} rpc GetAccountDetails(requests.GetAccountDetailsRequest) returns (responses.GetAccountDetailsResponse) {} + rpc GetAccountProofs(requests.GetAccountProofsRequest) returns (responses.GetAccountProofsResponse) {} rpc GetAccountStateDelta(requests.GetAccountStateDeltaRequest) returns (responses.GetAccountStateDeltaResponse) {} rpc GetBlockByNumber(requests.GetBlockByNumberRequest) returns (responses.GetBlockByNumberResponse) {} rpc GetBlockHeaderByNumber(requests.GetBlockHeaderByNumberRequest) returns (responses.GetBlockHeaderByNumberResponse) {} diff --git a/crates/rpc-proto/proto/store.proto b/crates/rpc-proto/proto/store.proto index a9e6fbd85..ec5a11270 100644 --- a/crates/rpc-proto/proto/store.proto +++ b/crates/rpc-proto/proto/store.proto @@ -12,6 +12,7 @@ service Api { rpc CheckNullifiers(requests.CheckNullifiersRequest) returns (responses.CheckNullifiersResponse) {} rpc CheckNullifiersByPrefix(requests.CheckNullifiersByPrefixRequest) returns (responses.CheckNullifiersByPrefixResponse) {} rpc GetAccountDetails(requests.GetAccountDetailsRequest) returns (responses.GetAccountDetailsResponse) {} + rpc GetAccountProofs(requests.GetAccountProofsRequest) returns (responses.GetAccountProofsResponse) {} rpc GetAccountStateDelta(requests.GetAccountStateDeltaRequest) returns (responses.GetAccountStateDeltaResponse) {} rpc GetBlockByNumber(requests.GetBlockByNumberRequest) returns (responses.GetBlockByNumberResponse) {} rpc GetBlockHeaderByNumber(requests.GetBlockHeaderByNumberRequest) returns (responses.GetBlockHeaderByNumberResponse) {} diff --git a/crates/rpc/src/server/api.rs b/crates/rpc/src/server/api.rs index 4ee3ed578..5c25bd480 100644 --- a/crates/rpc/src/server/api.rs +++ b/crates/rpc/src/server/api.rs @@ -3,14 +3,15 @@ use miden_node_proto::{ block_producer::api_client as block_producer_client, requests::{ CheckNullifiersByPrefixRequest, CheckNullifiersRequest, GetAccountDetailsRequest, - GetAccountStateDeltaRequest, GetBlockByNumberRequest, GetBlockHeaderByNumberRequest, - GetNotesByIdRequest, SubmitProvenTransactionRequest, SyncNoteRequest, SyncStateRequest, + GetAccountProofsRequest, GetAccountStateDeltaRequest, GetBlockByNumberRequest, + GetBlockHeaderByNumberRequest, GetNotesByIdRequest, SubmitProvenTransactionRequest, + SyncNoteRequest, SyncStateRequest, }, responses::{ CheckNullifiersByPrefixResponse, CheckNullifiersResponse, GetAccountDetailsResponse, - GetAccountStateDeltaResponse, GetBlockByNumberResponse, GetBlockHeaderByNumberResponse, - GetNotesByIdResponse, SubmitProvenTransactionResponse, SyncNoteResponse, - SyncStateResponse, + GetAccountProofsResponse, GetAccountStateDeltaResponse, GetBlockByNumberResponse, + GetBlockHeaderByNumberResponse, GetNotesByIdResponse, SubmitProvenTransactionResponse, + SyncNoteResponse, SyncStateResponse, }, rpc::api_server, store::api_client as store_client, @@ -19,7 +20,7 @@ use miden_node_proto::{ }; use miden_objects::{ accounts::AccountId, crypto::hash::rpo::RpoDigest, transaction::ProvenTransaction, - utils::serde::Deserializable, Digest, MIN_PROOF_SECURITY_LEVEL, + utils::serde::Deserializable, Digest, MAX_NUM_FOREIGN_ACCOUNTS, MIN_PROOF_SECURITY_LEVEL, }; use miden_tx::TransactionVerifier; use tonic::{ @@ -250,4 +251,29 @@ impl api_server::Api for RpcApi { self.store.clone().get_account_state_delta(request).await } + + #[instrument( + target = "miden-rpc", + name = "rpc:get_account_proofs", + skip_all, + ret(level = "debug"), + err + )] + async fn get_account_proofs( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + + debug!(target: COMPONENT, ?request); + + if request.account_ids.len() > MAX_NUM_FOREIGN_ACCOUNTS as usize { + return Err(Status::invalid_argument(format!( + "Too many accounts requested: {}, limit: {MAX_NUM_FOREIGN_ACCOUNTS}", + request.account_ids.len() + ))); + } + + self.store.clone().get_account_proofs(request).await + } } diff --git a/crates/store/src/db/mod.rs b/crates/store/src/db/mod.rs index a43dd4d39..6e04e67b1 100644 --- a/crates/store/src/db/mod.rs +++ b/crates/store/src/db/mod.rs @@ -200,10 +200,15 @@ impl Db { /// Loads all the nullifiers from the DB. #[instrument(target = "miden-store", skip_all, ret(level = "debug"), err)] - pub async fn select_nullifiers(&self) -> Result> { - self.pool.get().await?.interact(sql::select_nullifiers).await.map_err(|err| { - DatabaseError::InteractError(format!("Select nullifiers task failed: {err}")) - })? + pub async fn select_all_nullifiers(&self) -> Result> { + self.pool + .get() + .await? + .interact(sql::select_all_nullifiers) + .await + .map_err(|err| { + DatabaseError::InteractError(format!("Select nullifiers task failed: {err}")) + })? } /// Loads the nullifiers that match the prefixes from the DB. @@ -229,16 +234,16 @@ impl Db { /// Loads all the notes from the DB. #[instrument(target = "miden-store", skip_all, ret(level = "debug"), err)] - pub async fn select_notes(&self) -> Result> { - self.pool.get().await?.interact(sql::select_notes).await.map_err(|err| { + pub async fn select_all_notes(&self) -> Result> { + self.pool.get().await?.interact(sql::select_all_notes).await.map_err(|err| { DatabaseError::InteractError(format!("Select notes task failed: {err}")) })? } /// Loads all the accounts from the DB. #[instrument(target = "miden-store", skip_all, ret(level = "debug"), err)] - pub async fn select_accounts(&self) -> Result> { - self.pool.get().await?.interact(sql::select_accounts).await.map_err(|err| { + pub async fn select_all_accounts(&self) -> Result> { + self.pool.get().await?.interact(sql::select_all_accounts).await.map_err(|err| { DatabaseError::InteractError(format!("Select accounts task failed: {err}")) })? } @@ -291,11 +296,11 @@ impl Db { /// Loads all the account hashes from the DB. #[instrument(target = "miden-store", skip_all, ret(level = "debug"), err)] - pub async fn select_account_hashes(&self) -> Result> { + pub async fn select_all_account_hashes(&self) -> Result> { self.pool .get() .await? - .interact(sql::select_account_hashes) + .interact(sql::select_all_account_hashes) .await .map_err(|err| { DatabaseError::InteractError(format!("Select account hashes task failed: {err}")) @@ -315,6 +320,22 @@ impl Db { })? } + /// Loads public accounts details from the DB. + #[instrument(target = "miden-store", skip_all, ret(level = "debug"), err)] + pub async fn select_accounts_by_ids( + &self, + account_ids: Vec, + ) -> Result> { + self.pool + .get() + .await? + .interact(move |conn| sql::select_accounts_by_ids(conn, &account_ids)) + .await + .map_err(|err| { + DatabaseError::InteractError(format!("Get accounts details task failed: {err}")) + })? + } + #[instrument(target = "miden-store", skip_all, ret(level = "debug"), err)] pub async fn get_state_sync( &self, diff --git a/crates/store/src/db/sql.rs b/crates/store/src/db/sql.rs index 0ef7094bc..9980f40dd 100644 --- a/crates/store/src/db/sql.rs +++ b/crates/store/src/db/sql.rs @@ -39,7 +39,7 @@ use crate::{ /// # Returns /// /// A vector with accounts, or an error. -pub fn select_accounts(conn: &mut Connection) -> Result> { +pub fn select_all_accounts(conn: &mut Connection) -> Result> { let mut stmt = conn.prepare_cached( " SELECT @@ -67,7 +67,7 @@ pub fn select_accounts(conn: &mut Connection) -> Result> { /// # Returns /// /// The vector with the account id and corresponding hash, or an error. -pub fn select_account_hashes(conn: &mut Connection) -> Result> { +pub fn select_all_account_hashes(conn: &mut Connection) -> Result> { let mut stmt = conn .prepare_cached("SELECT account_id, account_hash FROM accounts ORDER BY block_num ASC;")?; let mut rows = stmt.query([])?; @@ -150,6 +150,40 @@ pub fn select_account(conn: &mut Connection, account_id: AccountId) -> Result Result> { + let mut stmt = conn.prepare_cached( + " + SELECT + account_id, + account_hash, + block_num, + details + FROM + accounts + WHERE + account_id IN rarray(?1); + ", + )?; + + let account_ids: Vec = account_ids.iter().copied().map(u64_to_value).collect(); + let mut rows = stmt.query(params![Rc::new(account_ids)])?; + + let mut result = Vec::new(); + while let Some(row) = rows.next()? { + result.push(account_info_from_row(row)?) + } + + Ok(result) +} + /// Select account deltas by account id and block range from the DB using the given [Connection]. /// /// # Note: @@ -297,7 +331,7 @@ pub fn insert_nullifiers_for_block( /// # Returns /// /// A vector with nullifiers and the block height at which they were created, or an error. -pub fn select_nullifiers(conn: &mut Connection) -> Result> { +pub fn select_all_nullifiers(conn: &mut Connection) -> Result> { let mut stmt = conn.prepare_cached("SELECT nullifier, block_num FROM nullifiers ORDER BY block_num ASC;")?; let mut rows = stmt.query([])?; @@ -415,7 +449,7 @@ pub fn select_nullifiers_by_prefix( /// # Returns /// /// A vector with notes, or an error. -pub fn select_notes(conn: &mut Connection) -> Result> { +pub fn select_all_notes(conn: &mut Connection) -> Result> { let mut stmt = conn.prepare_cached( " SELECT diff --git a/crates/store/src/db/tests.rs b/crates/store/src/db/tests.rs index f33d258bb..a79166003 100644 --- a/crates/store/src/db/tests.rs +++ b/crates/store/src/db/tests.rs @@ -133,7 +133,7 @@ fn test_sql_select_nullifiers() { create_block(&mut conn, block_num); // test querying empty table - let nullifiers = sql::select_nullifiers(&mut conn).unwrap(); + let nullifiers = sql::select_all_nullifiers(&mut conn).unwrap(); assert!(nullifiers.is_empty()); // test multiple entries @@ -146,7 +146,7 @@ fn test_sql_select_nullifiers() { let res = sql::insert_nullifiers_for_block(&transaction, &[nullifier], block_num); assert_eq!(res.unwrap(), 1, "One element must have been inserted"); transaction.commit().unwrap(); - let nullifiers = sql::select_nullifiers(&mut conn).unwrap(); + let nullifiers = sql::select_all_nullifiers(&mut conn).unwrap(); assert_eq!(nullifiers, state); } } @@ -159,7 +159,7 @@ fn test_sql_select_notes() { create_block(&mut conn, block_num); // test querying empty table - let notes = sql::select_notes(&mut conn).unwrap(); + let notes = sql::select_all_notes(&mut conn).unwrap(); assert!(notes.is_empty()); // test multiple entries @@ -186,7 +186,7 @@ fn test_sql_select_notes() { let res = sql::insert_notes(&transaction, &[note]); assert_eq!(res.unwrap(), 1, "One element must have been inserted"); transaction.commit().unwrap(); - let notes = sql::select_notes(&mut conn).unwrap(); + let notes = sql::select_all_notes(&mut conn).unwrap(); assert_eq!(notes, state); } } @@ -199,7 +199,7 @@ fn test_sql_select_notes_different_execution_hints() { create_block(&mut conn, block_num); // test querying empty table - let notes = sql::select_notes(&mut conn).unwrap(); + let notes = sql::select_all_notes(&mut conn).unwrap(); assert!(notes.is_empty()); // test multiple entries @@ -286,7 +286,7 @@ fn test_sql_select_accounts() { create_block(&mut conn, block_num); // test querying empty table - let accounts = sql::select_accounts(&mut conn).unwrap(); + let accounts = sql::select_all_accounts(&mut conn).unwrap(); assert!(accounts.is_empty()); // test multiple entries let mut state = vec![]; @@ -316,7 +316,7 @@ fn test_sql_select_accounts() { ); assert_eq!(res.unwrap(), 1, "One element must have been inserted"); transaction.commit().unwrap(); - let accounts = sql::select_accounts(&mut conn).unwrap(); + let accounts = sql::select_all_accounts(&mut conn).unwrap(); assert_eq!(accounts, state); } } @@ -362,7 +362,7 @@ fn test_sql_public_account_details() { ); // test querying empty table - let accounts_in_db = sql::select_accounts(&mut conn).unwrap(); + let accounts_in_db = sql::select_all_accounts(&mut conn).unwrap(); assert!(accounts_in_db.is_empty()); let transaction = conn.transaction().unwrap(); @@ -382,7 +382,7 @@ fn test_sql_public_account_details() { transaction.commit().unwrap(); - let mut accounts_in_db = sql::select_accounts(&mut conn).unwrap(); + let mut accounts_in_db = sql::select_all_accounts(&mut conn).unwrap(); assert_eq!(accounts_in_db.len(), 1, "One element must have been inserted"); @@ -422,7 +422,7 @@ fn test_sql_public_account_details() { transaction.commit().unwrap(); - let mut accounts_in_db = sql::select_accounts(&mut conn).unwrap(); + let mut accounts_in_db = sql::select_all_accounts(&mut conn).unwrap(); assert_eq!(accounts_in_db.len(), 1, "One element must have been inserted"); @@ -475,7 +475,7 @@ fn test_sql_public_account_details() { transaction.commit().unwrap(); - let mut accounts_in_db = sql::select_accounts(&mut conn).unwrap(); + let mut accounts_in_db = sql::select_all_accounts(&mut conn).unwrap(); assert_eq!(accounts_in_db.len(), 1, "One element must have been inserted"); @@ -532,7 +532,7 @@ fn test_sql_select_nullifiers_by_block_range() { sql::insert_nullifiers_for_block(&transaction, &[nullifier2], block_number2).unwrap(); transaction.commit().unwrap(); - let nullifiers = sql::select_nullifiers(&mut conn).unwrap(); + let nullifiers = sql::select_all_nullifiers(&mut conn).unwrap(); assert_eq!(nullifiers, vec![(nullifier1, block_number1), (nullifier2, block_number2)]); // only the nullifiers matching the prefix are included @@ -649,7 +649,7 @@ fn test_select_nullifiers_by_prefix() { sql::insert_nullifiers_for_block(&transaction, &[nullifier2], block_number2).unwrap(); transaction.commit().unwrap(); - let nullifiers = sql::select_nullifiers(&mut conn).unwrap(); + let nullifiers = sql::select_all_nullifiers(&mut conn).unwrap(); assert_eq!(nullifiers, vec![(nullifier1, block_number1), (nullifier2, block_number2)]); // only the nullifiers matching the prefix are included diff --git a/crates/store/src/errors.rs b/crates/store/src/errors.rs index 900837188..2666c138a 100644 --- a/crates/store/src/errors.rs +++ b/crates/store/src/errors.rs @@ -68,6 +68,8 @@ pub enum DatabaseError { ApplyBlockFailedClosedChannel(RecvError), #[error("Account {0} not found in the database")] AccountNotFoundInDb(AccountId), + #[error("Accounts {0:?} not found in the database")] + AccountsNotFoundInDb(Vec), #[error("Account {0} is not on the chain")] AccountNotOnChain(AccountId), #[error("Failed to apply block because of public account final hashes mismatch (expected {expected}, \ diff --git a/crates/store/src/server/api.rs b/crates/store/src/server/api.rs index 47b5922f3..38e4bdaf7 100644 --- a/crates/store/src/server/api.rs +++ b/crates/store/src/server/api.rs @@ -10,18 +10,20 @@ use miden_node_proto::{ note::NoteAuthenticationInfo as NoteAuthenticationInfoProto, requests::{ ApplyBlockRequest, CheckNullifiersByPrefixRequest, CheckNullifiersRequest, - GetAccountDetailsRequest, GetAccountStateDeltaRequest, GetBlockByNumberRequest, - GetBlockHeaderByNumberRequest, GetBlockInputsRequest, GetNoteAuthenticationInfoRequest, - GetNotesByIdRequest, GetTransactionInputsRequest, ListAccountsRequest, - ListNotesRequest, ListNullifiersRequest, SyncNoteRequest, SyncStateRequest, + GetAccountDetailsRequest, GetAccountProofsRequest, GetAccountStateDeltaRequest, + GetBlockByNumberRequest, GetBlockHeaderByNumberRequest, GetBlockInputsRequest, + GetNoteAuthenticationInfoRequest, GetNotesByIdRequest, GetTransactionInputsRequest, + ListAccountsRequest, ListNotesRequest, ListNullifiersRequest, SyncNoteRequest, + SyncStateRequest, }, responses::{ AccountTransactionInputRecord, ApplyBlockResponse, CheckNullifiersByPrefixResponse, - CheckNullifiersResponse, GetAccountDetailsResponse, GetAccountStateDeltaResponse, - GetBlockByNumberResponse, GetBlockHeaderByNumberResponse, GetBlockInputsResponse, - GetNoteAuthenticationInfoResponse, GetNotesByIdResponse, GetTransactionInputsResponse, - ListAccountsResponse, ListNotesResponse, ListNullifiersResponse, - NullifierTransactionInputRecord, NullifierUpdate, SyncNoteResponse, SyncStateResponse, + CheckNullifiersResponse, GetAccountDetailsResponse, GetAccountProofsResponse, + GetAccountStateDeltaResponse, GetBlockByNumberResponse, GetBlockHeaderByNumberResponse, + GetBlockInputsResponse, GetNoteAuthenticationInfoResponse, GetNotesByIdResponse, + GetTransactionInputsResponse, ListAccountsResponse, ListNotesResponse, + ListNullifiersResponse, NullifierTransactionInputRecord, NullifierUpdate, + SyncNoteResponse, SyncStateResponse, }, smt::SmtLeafEntry, store::api_server, @@ -36,7 +38,7 @@ use miden_objects::{ utils::{Deserializable, Serializable}, Felt, ZERO, }; -use tonic::{Response, Status}; +use tonic::{Request, Response, Status}; use tracing::{debug, info, instrument}; use crate::{state::State, types::AccountId, COMPONENT}; @@ -421,7 +423,7 @@ impl api_server::Api for StoreApi { debug!(target: COMPONENT, ?request); - let account_id = request.account_id.ok_or(invalid_argument("Account_id missing"))?.id; + let account_id = request.account_id.ok_or(invalid_argument("`account_id` missing"))?.id; let nullifiers = validate_nullifiers(&request.nullifiers)?; let unauthenticated_notes = validate_notes(&request.unauthenticated_notes)?; @@ -475,6 +477,35 @@ impl api_server::Api for StoreApi { Ok(Response::new(GetBlockByNumberResponse { block })) } + #[instrument( + target = "miden-store", + name = "store:get_account_proofs", + skip_all, + ret(level = "debug"), + err + )] + async fn get_account_proofs( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + + debug!(target: COMPONENT, ?request); + + let account_ids = convert(request.account_ids); + let include_headers = request.include_headers.unwrap_or_default(); + let (block_num, infos) = self + .state + .get_account_states(account_ids, include_headers) + .await + .map_err(internal_error)?; + + Ok(Response::new(GetAccountProofsResponse { + block_num, + account_proofs: infos.into_iter().map(Into::into).collect(), + })) + } + #[instrument( target = "miden-store", name = "store:get_account_state_delta", diff --git a/crates/store/src/state.rs b/crates/store/src/state.rs index 0ae2b8bb8..44e03425c 100644 --- a/crates/store/src/state.rs +++ b/crates/store/src/state.rs @@ -11,12 +11,12 @@ use std::{ use miden_node_proto::{ convert, domain::{accounts::AccountInfo, blocks::BlockInclusionProof, notes::NoteAuthenticationInfo}, - generated::responses::GetBlockInputsResponse, + generated::responses::{AccountProofsResponse, AccountStateHeader, GetBlockInputsResponse}, AccountInputRecord, NullifierWitness, }; use miden_node_utils::formatting::{format_account_id, format_array}; use miden_objects::{ - accounts::AccountDelta, + accounts::{AccountDelta, AccountHeader}, block::Block, crypto::{ hash::rpo::RpoDigest, @@ -95,6 +95,13 @@ struct InnerState { account_tree: SimpleSmt, } +impl InnerState { + /// Returns the latest block number. + fn latest_block_num(&self) -> BlockNumber { + (self.chain_mmr.forest() + 1).try_into().expect("block number overflow") + } +} + /// The rollup state pub struct State { /// The database which stores block headers, nullifiers, notes, and the latest states of @@ -653,25 +660,83 @@ impl State { /// Lists all known nullifiers with their inclusion blocks, intended for testing. pub async fn list_nullifiers(&self) -> Result, DatabaseError> { - self.db.select_nullifiers().await + self.db.select_all_nullifiers().await } /// Lists all known accounts, with their ids, latest state hash, and block at which the account /// was last modified, intended for testing. pub async fn list_accounts(&self) -> Result, DatabaseError> { - self.db.select_accounts().await + self.db.select_all_accounts().await } /// Lists all known notes, intended for testing. pub async fn list_notes(&self) -> Result, DatabaseError> { - self.db.select_notes().await + self.db.select_all_notes().await } - /// Returns details for public (public) account. + /// Returns details for public (on-chain) account. pub async fn get_account_details(&self, id: AccountId) -> Result { self.db.select_account(id).await } + /// Returns account states with details for public accounts. + pub async fn get_account_states( + &self, + account_ids: Vec, + include_headers: bool, + ) -> Result<(BlockNumber, Vec), DatabaseError> { + // Lock inner state for the whole operation. We need to hold this lock to prevent the + // database, account tree and latest block number from changing during the operation, + // because changing one of them would lead to inconsistent state. + let inner_state = self.inner.read().await; + + let state_headers = if !include_headers { + BTreeMap::::default() + } else { + let infos = self.db.select_accounts_by_ids(account_ids.clone()).await?; + + if account_ids.len() > infos.len() { + let found_ids: BTreeSet = + infos.iter().map(|info| info.summary.account_id.into()).collect(); + return Err(DatabaseError::AccountsNotFoundInDb( + BTreeSet::from_iter(account_ids).difference(&found_ids).copied().collect(), + )); + } + + infos + .into_iter() + .filter_map(|info| { + info.details.map(|details| { + ( + info.summary.account_id.into(), + AccountStateHeader { + header: Some(AccountHeader::from(&details).into()), + storage_header: details.storage().get_header().to_bytes(), + }, + ) + }) + }) + .collect() + }; + + let responses = account_ids + .into_iter() + .map(|account_id| { + let acc_leaf_idx = LeafIndex::new_max_depth(account_id); + let opening = inner_state.account_tree.open(&acc_leaf_idx); + + AccountProofsResponse { + account_id: Some(account_id.into()), + account_hash: Some(opening.value.into()), + account_proof: Some(opening.path.into()), + state_header: state_headers.get(&account_id).cloned(), + } + }) + .collect(); + + Ok((inner_state.latest_block_num(), responses)) + } + /// Returns the state delta between `from_block` (exclusive) and `to_block` (inclusive) for the /// given account. pub(crate) async fn get_account_state_delta( @@ -703,7 +768,7 @@ impl State { /// Returns the latest block number. pub async fn latest_block_num(&self) -> BlockNumber { - (self.inner.read().await.chain_mmr.forest() + 1) as BlockNumber + self.inner.read().await.latest_block_num() } } @@ -712,7 +777,7 @@ impl State { #[instrument(target = "miden-store", skip_all)] async fn load_nullifier_tree(db: &mut Db) -> Result { - let nullifiers = db.select_nullifiers().await?; + let nullifiers = db.select_all_nullifiers().await?; let len = nullifiers.len(); let now = Instant::now(); @@ -742,7 +807,7 @@ async fn load_accounts( db: &mut Db, ) -> Result, StateInitializationError> { let account_data: Vec<_> = db - .select_account_hashes() + .select_all_account_hashes() .await? .into_iter() .map(|(id, account_hash)| (id, account_hash.into())) diff --git a/proto/account.proto b/proto/account.proto index a0eb36972..8f7becff9 100644 --- a/proto/account.proto +++ b/proto/account.proto @@ -20,3 +20,14 @@ message AccountInfo { AccountSummary summary = 1; optional bytes details = 2; } + +message AccountHeader { + // Vault root hash. + digest.Digest vault_root = 1; + // Storage root hash. + digest.Digest storage_commitment = 2; + // Code root hash. + digest.Digest code_commitment = 3; + // Account nonce. + uint64 nonce = 4; +} diff --git a/proto/requests.proto b/proto/requests.proto index a9c210a2b..9f9554b48 100644 --- a/proto/requests.proto +++ b/proto/requests.proto @@ -131,3 +131,10 @@ message GetAccountStateDeltaRequest { // Block number up to which the delta is requested (inclusive). fixed32 to_block_num = 3; } + +message GetAccountProofsRequest { + // List of account IDs to get states. + repeated account.AccountId account_ids = 1; + // Optional flag to include header in the response. `false` by default. + optional bool include_headers = 2; +} diff --git a/proto/responses.proto b/proto/responses.proto index 7342294ff..7d7d00032 100644 --- a/proto/responses.proto +++ b/proto/responses.proto @@ -173,3 +173,28 @@ message GetAccountStateDeltaResponse { // The calculated `AccountStateDelta` encoded using miden native format optional bytes delta = 1; } + +message GetAccountProofsResponse { + // Block number at which the state of the account was returned. + fixed32 block_num = 1; + // List of account state infos for the requested account keys. + repeated AccountProofsResponse account_proofs = 2; +} + +message AccountProofsResponse { + // Account ID. + account.AccountId account_id = 1; + // Account hash. + digest.Digest account_hash = 2; + // Authentication path from the `account_root` of the block header to the account. + merkle.MerklePath account_proof = 3; + // State header for public accounts. Filled only if `include_headers` flag is set to `true`. + optional AccountStateHeader state_header = 4; +} + +message AccountStateHeader { + // Account header. + account.AccountHeader header = 1; + // Values of all account storage slots (max 255). + bytes storage_header = 2; +} diff --git a/proto/rpc.proto b/proto/rpc.proto index da2c2bdd0..13934b2c4 100644 --- a/proto/rpc.proto +++ b/proto/rpc.proto @@ -9,6 +9,7 @@ service Api { rpc CheckNullifiers(requests.CheckNullifiersRequest) returns (responses.CheckNullifiersResponse) {} rpc CheckNullifiersByPrefix(requests.CheckNullifiersByPrefixRequest) returns (responses.CheckNullifiersByPrefixResponse) {} rpc GetAccountDetails(requests.GetAccountDetailsRequest) returns (responses.GetAccountDetailsResponse) {} + rpc GetAccountProofs(requests.GetAccountProofsRequest) returns (responses.GetAccountProofsResponse) {} rpc GetAccountStateDelta(requests.GetAccountStateDeltaRequest) returns (responses.GetAccountStateDeltaResponse) {} rpc GetBlockByNumber(requests.GetBlockByNumberRequest) returns (responses.GetBlockByNumberResponse) {} rpc GetBlockHeaderByNumber(requests.GetBlockHeaderByNumberRequest) returns (responses.GetBlockHeaderByNumberResponse) {} diff --git a/proto/store.proto b/proto/store.proto index a9e6fbd85..ec5a11270 100644 --- a/proto/store.proto +++ b/proto/store.proto @@ -12,6 +12,7 @@ service Api { rpc CheckNullifiers(requests.CheckNullifiersRequest) returns (responses.CheckNullifiersResponse) {} rpc CheckNullifiersByPrefix(requests.CheckNullifiersByPrefixRequest) returns (responses.CheckNullifiersByPrefixResponse) {} rpc GetAccountDetails(requests.GetAccountDetailsRequest) returns (responses.GetAccountDetailsResponse) {} + rpc GetAccountProofs(requests.GetAccountProofsRequest) returns (responses.GetAccountProofsResponse) {} rpc GetAccountStateDelta(requests.GetAccountStateDeltaRequest) returns (responses.GetAccountStateDeltaResponse) {} rpc GetBlockByNumber(requests.GetBlockByNumberRequest) returns (responses.GetBlockByNumberResponse) {} rpc GetBlockHeaderByNumber(requests.GetBlockHeaderByNumberRequest) returns (responses.GetBlockHeaderByNumberResponse) {} From 167bbca10441ad0d592328bbe2df4b799224dcea Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:19:52 +0500 Subject: [PATCH 23/37] feat(faucet): migrate to axum from actix (#511) --- CHANGELOG.md | 3 +- Cargo.lock | 585 ++++--------------------------------- Cargo.toml | 2 +- bin/faucet/Cargo.toml | 12 +- bin/faucet/src/client.rs | 73 +++-- bin/faucet/src/config.rs | 6 - bin/faucet/src/errors.rs | 69 +++-- bin/faucet/src/handlers.rs | 83 ++++-- bin/faucet/src/main.rs | 88 +++--- bin/faucet/src/state.rs | 19 +- 10 files changed, 266 insertions(+), 674 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ee919517..b9bd903ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,8 @@ - Improve `--version` by adding build metadata (#495). - [BREAKING] Introduced additional limits for note/account number (#503). - [BREAKING] Removed support for basic wallets in genesis creation (#510). -- Added `GetAccountStates` endpoint (#506). +- Added `GetAccountProofs` endpoint (#506). +- Migrated faucet from actix-web to axum (#511). ## 0.5.1 (2024-09-12) diff --git a/Cargo.lock b/Cargo.lock index cf34633e8..e110537a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,216 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "actix-codec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-sink", - "memchr", - "pin-project-lite", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "actix-cors" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e772b3bcafe335042b5db010ab7c09013dad6eac4915c91d8d50902769f331" -dependencies = [ - "actix-utils", - "actix-web", - "derive_more", - "futures-util", - "log", - "once_cell", - "smallvec", -] - -[[package]] -name = "actix-http" -version = "3.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48f96fc3003717aeb9856ca3d02a8c7de502667ad76eeacd830b48d2e91fac4" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "ahash", - "base64", - "bitflags", - "brotli", - "bytes", - "bytestring", - "derive_more", - "encoding_rs", - "flate2", - "futures-core", - "h2 0.3.26", - "http 0.2.12", - "httparse", - "httpdate", - "itoa", - "language-tags", - "local-channel", - "mime", - "percent-encoding", - "pin-project-lite", - "rand", - "sha1", - "smallvec", - "tokio", - "tokio-util", - "tracing", - "zstd", -] - -[[package]] -name = "actix-macros" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "actix-router" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" -dependencies = [ - "bytestring", - "cfg-if", - "http 0.2.12", - "regex", - "regex-lite", - "serde", - "tracing", -] - -[[package]] -name = "actix-rt" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" -dependencies = [ - "futures-core", - "tokio", -] - -[[package]] -name = "actix-server" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca2549781d8dd6d75c40cf6b6051260a2cc2f3c62343d761a969a0640646894" -dependencies = [ - "actix-rt", - "actix-service", - "actix-utils", - "futures-core", - "futures-util", - "mio", - "socket2", - "tokio", - "tracing", -] - -[[package]] -name = "actix-service" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" -dependencies = [ - "futures-core", - "paste", - "pin-project-lite", -] - -[[package]] -name = "actix-utils" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" -dependencies = [ - "local-waker", - "pin-project-lite", -] - -[[package]] -name = "actix-web" -version = "4.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9180d76e5cc7ccbc4d60a506f2c727730b154010262df5b910eb17dbe4b8cb38" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-utils", - "actix-web-codegen", - "ahash", - "bytes", - "bytestring", - "cfg-if", - "cookie", - "derive_more", - "encoding_rs", - "futures-core", - "futures-util", - "impl-more", - "itoa", - "language-tags", - "log", - "mime", - "once_cell", - "pin-project-lite", - "regex", - "regex-lite", - "serde", - "serde_json", - "serde_urlencoded", - "smallvec", - "socket2", - "time", - "url", -] - -[[package]] -name = "actix-web-codegen" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" -dependencies = [ - "actix-router", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "actix-web-static-files" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adf6d1ef6d7a60e084f9e0595e2a5234abda14e76c105ecf8e2d0e8800c41a1f" -dependencies = [ - "actix-web", - "derive_more", - "futures-util", - "static-files", -] - [[package]] name = "addr2line" version = "0.24.1" @@ -234,7 +24,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom", "once_cell", "version_check", "zerocopy", @@ -249,21 +38,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - [[package]] name = "android-tzdata" version = "0.1.1" @@ -355,15 +129,6 @@ dependencies = [ "term", ] -[[package]] -name = "async-mutex" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" -dependencies = [ - "event-listener", -] - [[package]] name = "async-stream" version = "0.3.5" @@ -420,17 +185,19 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f43644eed690f5374f1af436ecd6aea01cd201f6fbdf0178adaf6907afb2cec" +checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" dependencies = [ "async-trait", "axum-core", "bytes", "futures-util", - "http 1.1.0", + "http", "http-body", "http-body-util", + "hyper", + "hyper-util", "itoa", "matchit", "memchr", @@ -439,22 +206,27 @@ dependencies = [ "pin-project-lite", "rustversion", "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", "sync_wrapper 1.0.1", + "tokio", "tower 0.5.1", "tower-layer", "tower-service", + "tracing", ] [[package]] name = "axum-core" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6b8ba012a258d63c9adfa28b9ddcf66149da6f986c5b5452e629d5ee64bf00" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.1.0", + "http", "http-body", "http-body-util", "mime", @@ -463,6 +235,7 @@ dependencies = [ "sync_wrapper 1.0.1", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -564,27 +337,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "brotli" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - [[package]] name = "bumpalo" version = "3.16.0" @@ -609,15 +361,6 @@ version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" -[[package]] -name = "bytestring" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" -dependencies = [ - "bytes", -] - [[package]] name = "camino" version = "1.1.9" @@ -763,23 +506,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "cookie" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -795,15 +521,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - [[package]] name = "crossbeam-deque" version = "0.8.5" @@ -960,19 +677,6 @@ dependencies = [ "syn", ] -[[package]] -name = "derive_more" -version = "0.99.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version 0.4.1", - "syn", -] - [[package]] name = "digest" version = "0.10.7" @@ -1046,15 +750,6 @@ dependencies = [ "log", ] -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -1071,12 +766,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - [[package]] name = "fallible-iterator" version = "0.3.0" @@ -1117,16 +806,6 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" -[[package]] -name = "flate2" -version = "1.0.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" @@ -1201,7 +880,6 @@ dependencies = [ "futures-task", "pin-project-lite", "pin-utils", - "slab", ] [[package]] @@ -1250,25 +928,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.5.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "h2" version = "0.4.6" @@ -1280,7 +939,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.1.0", + "http", "indexmap 2.5.0", "slab", "tokio", @@ -1330,17 +989,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http" version = "1.1.0" @@ -1359,7 +1007,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http", ] [[package]] @@ -1370,7 +1018,7 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http 1.1.0", + "http", "http-body", "pin-project-lite", ] @@ -1396,8 +1044,8 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.6", - "http 1.1.0", + "h2", + "http", "http-body", "httparse", "httpdate", @@ -1430,7 +1078,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", + "http", "http-body", "hyper", "pin-project-lite", @@ -1469,22 +1117,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "impl-more" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d" - [[package]] name = "indenter" version = "0.3.3" @@ -1616,12 +1248,6 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" -[[package]] -name = "language-tags" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" - [[package]] name = "lazy_static" version = "1.5.0" @@ -1684,23 +1310,6 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" -[[package]] -name = "local-channel" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" -dependencies = [ - "futures-core", - "futures-sink", - "local-waker", -] - -[[package]] -name = "local-waker" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" - [[package]] name = "lock_api" version = "0.4.12" @@ -1857,25 +1466,27 @@ dependencies = [ name = "miden-faucet" version = "0.6.0" dependencies = [ - "actix-cors", - "actix-web", - "actix-web-static-files", - "async-mutex", + "axum", "clap", - "derive_more", "figment", + "http", + "http-body-util", "miden-lib", "miden-node-proto", "miden-node-utils", "miden-objects", "miden-tx", + "mime", "rand", "rand_chacha", "serde", "static-files", "thiserror", + "tokio", "toml", "tonic", + "tower 0.5.1", + "tower-http 0.6.1", "tracing", ] @@ -2250,7 +1861,6 @@ checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ "hermit-abi", "libc", - "log", "wasi", "windows-sys 0.52.0", ] @@ -2453,12 +2063,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "path-matchers" version = "1.0.2" @@ -2852,12 +2456,6 @@ dependencies = [ "regex-syntax 0.8.4", ] -[[package]] -name = "regex-lite" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" - [[package]] name = "regex-syntax" version = "0.6.29" @@ -3038,6 +2636,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +dependencies = [ + "itoa", + "serde", +] + [[package]] name = "serde_spanned" version = "0.6.8" @@ -3059,17 +2667,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "sha3" version = "0.10.8" @@ -3095,15 +2692,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - [[package]] name = "siphasher" version = "0.3.11" @@ -3356,21 +2944,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "tinyvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokio" version = "1.40.0" @@ -3381,9 +2954,7 @@ dependencies = [ "bytes", "libc", "mio", - "parking_lot", "pin-project-lite", - "signal-hook-registry", "socket2", "tokio-macros", "windows-sys 0.52.0", @@ -3469,8 +3040,8 @@ dependencies = [ "axum", "base64", "bytes", - "h2 0.4.6", - "http 1.1.0", + "h2", + "http", "http-body", "http-body-util", "hyper", @@ -3510,13 +3081,13 @@ checksum = "5299dd20801ad736dccb4a5ea0da7376e59cd98f213bf1c3d478cf53f4834b58" dependencies = [ "base64", "bytes", - "http 1.1.0", + "http", "http-body", "http-body-util", "pin-project", "tokio-stream", "tonic", - "tower-http", + "tower-http 0.5.2", "tower-layer", "tower-service", "tracing", @@ -3552,8 +3123,10 @@ dependencies = [ "futures-util", "pin-project-lite", "sync_wrapper 0.1.2", + "tokio", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -3564,7 +3137,7 @@ checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ "bitflags", "bytes", - "http 1.1.0", + "http", "http-body", "http-body-util", "pin-project-lite", @@ -3572,6 +3145,22 @@ dependencies = [ "tower-service", ] +[[package]] +name = "tower-http" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8437150ab6bbc8c5f0f519e3d5ed4aa883a83dd4cdd3d1b21f9482936046cb97" +dependencies = [ + "bitflags", + "bytes", + "http", + "http-body", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -3723,12 +3312,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - [[package]] name = "unicode-ident" version = "1.0.13" @@ -3741,15 +3324,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-width" version = "0.1.14" @@ -3762,17 +3336,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "url" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - [[package]] name = "utf8parse" version = "0.2.2" @@ -4357,31 +3920,3 @@ dependencies = [ "quote", "syn", ] - -[[package]] -name = "zstd" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/Cargo.toml b/Cargo.toml index 7e2f0c5cc..656515f39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ miden-stdlib = { version = "0.10", default-features = false } miden-tx = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } prost = { version = "0.13" } thiserror = { version = "1.0" } -tokio = { version = "1.40" } +tokio = { version = "1.40", features = ["rt-multi-thread"] } tokio-stream = { version = "0.1" } tonic = { version = "0.12" } tracing = { version = "0.1" } diff --git a/bin/faucet/Cargo.toml b/bin/faucet/Cargo.toml index f08e37729..fc03a81ad 100644 --- a/bin/faucet/Cargo.toml +++ b/bin/faucet/Cargo.toml @@ -17,25 +17,27 @@ repository.workspace = true testing = ["miden-objects/testing", "miden-lib/testing"] [dependencies] -actix-cors = "0.7" -actix-web = "4.8" -actix-web-static-files = "4.0" -async-mutex = "1.4" +axum = { version = "0.7", features = ["tokio"] } clap = { version = "4.5", features = ["derive", "string"] } -derive_more = "0.99" figment = { version = "0.10", features = ["toml", "env"] } +http = "1.1" +http-body-util = "0.1" miden-lib = { workspace = true, features = ["concurrent"] } miden-node-proto = { workspace = true } miden-node-utils = { workspace = true } miden-objects = { workspace = true , features = ["concurrent"] } miden-tx = { workspace = true, features = ["concurrent"] } +mime = "0.3" rand = { version = "0.8" } rand_chacha = "0.3" serde = { version = "1.0", features = ["derive"] } static-files = "0.2" thiserror = { workspace = true } +tokio = { workspace = true } toml = { version = "0.8" } tonic = { workspace = true } +tower = "0.5" +tower-http = { version = "0.6", features = ["cors", "set-header", "trace"] } tracing = { workspace = true } [build-dependencies] diff --git a/bin/faucet/src/client.rs b/bin/faucet/src/client.rs index 595709b5c..d02f4a138 100644 --- a/bin/faucet/src/client.rs +++ b/bin/faucet/src/client.rs @@ -30,7 +30,10 @@ use rand::{rngs::StdRng, thread_rng, Rng}; use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use tonic::transport::Channel; -use crate::{config::FaucetConfig, errors::FaucetError}; +use crate::{ + config::FaucetConfig, + errors::{InitError, ProcessError}, +}; pub const DISTRIBUTE_FUNGIBLE_ASSET_SCRIPT: &str = include_str!("transaction_scripts/distribute_fungible_asset.masm"); @@ -52,7 +55,7 @@ unsafe impl Send for FaucetClient {} unsafe impl Sync for FaucetClient {} impl FaucetClient { - pub async fn new(config: FaucetConfig) -> Result { + pub async fn new(config: FaucetConfig) -> Result { let (rpc_api, root_block_header, root_chain_mmr) = initialize_faucet_client(config.clone()).await?; @@ -87,9 +90,9 @@ impl FaucetClient { target_account_id: AccountId, is_private_note: bool, asset_amount: u64, - ) -> Result<(ExecutedTransaction, Note), FaucetError> { + ) -> Result<(ExecutedTransaction, Note), ProcessError> { let asset = FungibleAsset::new(self.id, asset_amount) - .map_err(|err| FaucetError::InternalServerError(err.to_string()))?; + .map_err(|err| ProcessError::InternalServerError(err.to_string()))?; let note_type = if is_private_note { NoteType::Private @@ -105,7 +108,7 @@ impl FaucetClient { Default::default(), &mut self.rng, ) - .map_err(|err| FaucetError::InternalServerError(err.to_string()))?; + .map_err(|err| ProcessError::InternalServerError(err.to_string()))?; let transaction_args = build_transaction_arguments(&output_note, note_type, asset)?; @@ -113,7 +116,7 @@ impl FaucetClient { .executor .execute_transaction(self.id, 0, &[], transaction_args) .map_err(|err| { - FaucetError::InternalServerError(format!("Failed to execute transaction: {}", err)) + ProcessError::InternalServerError(format!("Failed to execute transaction: {err}")) })?; Ok((executed_tx, output_note)) @@ -123,27 +126,32 @@ impl FaucetClient { pub async fn prove_and_submit_transaction( &mut self, executed_tx: ExecutedTransaction, - ) -> Result { - let transaction_prover = LocalTransactionProver::new(ProvingOptions::default()); - + ) -> Result { let delta = executed_tx.account_delta().clone(); - let proven_transaction = transaction_prover.prove(executed_tx).map_err(|err| { - FaucetError::InternalServerError(format!("Failed to prove transaction: {}", err)) - })?; + // Prepare request with proven transaction. + // This is needed to be in a separated code block in order to release reference to avoid + // borrow checker error. + let request = { + let transaction_prover = LocalTransactionProver::new(ProvingOptions::default()); - let request = SubmitProvenTransactionRequest { - transaction: proven_transaction.to_bytes(), + let proven_transaction = transaction_prover.prove(executed_tx).map_err(|err| { + ProcessError::InternalServerError(format!("Failed to prove transaction: {err}")) + })?; + + SubmitProvenTransactionRequest { + transaction: proven_transaction.to_bytes(), + } }; let response = self .rpc_api .submit_proven_transaction(request) .await - .map_err(|err| FaucetError::InternalServerError(err.to_string()))?; + .map_err(|err| ProcessError::InternalServerError(err.to_string()))?; self.data_store.update_faucet_account(&delta).map_err(|err| { - FaucetError::InternalServerError(format!("Failed to update account: {}", err)) + ProcessError::InternalServerError(format!("Failed to update account: {err}")) })?; Ok(response.into_inner().block_height) @@ -181,11 +189,11 @@ impl FaucetDataStore { } /// Updates the stored faucet account with the provided delta. - fn update_faucet_account(&mut self, delta: &AccountDelta) -> Result<(), FaucetError> { + fn update_faucet_account(&mut self, delta: &AccountDelta) -> Result<(), ProcessError> { self.faucet_account .borrow_mut() .apply_delta(delta) - .map_err(|err| FaucetError::InternalServerError(err.to_string())) + .map_err(|err| ProcessError::InternalServerError(err.to_string())) } } @@ -221,13 +229,13 @@ impl DataStore for FaucetDataStore { /// Builds a new faucet account with the provided configuration. /// /// Returns the created account, its seed, and the secret key used to sign transactions. -fn build_account(config: FaucetConfig) -> Result<(Account, Word, SecretKey), FaucetError> { +fn build_account(config: FaucetConfig) -> Result<(Account, Word, SecretKey), InitError> { let token_symbol = TokenSymbol::new(config.token_symbol.as_str()) - .map_err(|err| FaucetError::AccountCreationError(err.to_string()))?; + .map_err(|err| InitError::AccountCreationError(err.to_string()))?; let seed: [u8; 32] = [0; 32]; - // Instantiate keypair and authscheme + // Instantiate keypair and auth scheme let mut rng = ChaCha20Rng::from_seed(seed); let secret = SecretKey::with_rng(&mut rng); let auth_scheme = AuthScheme::RpoFalcon512 { pub_key: secret.public_key() }; @@ -237,11 +245,11 @@ fn build_account(config: FaucetConfig) -> Result<(Account, Word, SecretKey), Fau token_symbol, config.decimals, Felt::try_from(config.max_supply) - .map_err(|err| FaucetError::InternalServerError(err.to_string()))?, + .map_err(|err| InitError::AccountCreationError(err.to_string()))?, AccountStorageMode::Private, auth_scheme, ) - .map_err(|err| FaucetError::AccountCreationError(err.to_string()))?; + .map_err(|err| InitError::AccountCreationError(err.to_string()))?; Ok((faucet_account, account_seed, secret)) } @@ -249,26 +257,27 @@ fn build_account(config: FaucetConfig) -> Result<(Account, Word, SecretKey), Fau /// Initializes the faucet client by connecting to the node and fetching the root block header. pub async fn initialize_faucet_client( config: FaucetConfig, -) -> Result<(ApiClient, BlockHeader, ChainMmr), FaucetError> { +) -> Result<(ApiClient, BlockHeader, ChainMmr), InitError> { let endpoint = tonic::transport::Endpoint::try_from(config.node_url.clone()) - .map_err(|_| FaucetError::InternalServerError("Failed to connect to node.".to_string()))? + .map_err(|_| InitError::ClientInitFailed("Failed to connect to node.".to_string()))? .timeout(Duration::from_millis(config.timeout_ms)); let mut rpc_api = ApiClient::connect(endpoint) .await - .map_err(|err| FaucetError::InternalServerError(err.to_string()))?; + .map_err(|err| InitError::ClientInitFailed(err.to_string()))?; let request = GetBlockHeaderByNumberRequest { block_num: Some(0), include_mmr_proof: Some(true), }; - let response = rpc_api.get_block_header_by_number(request).await.map_err(|err| { - FaucetError::InternalServerError(format!("Failed to get block header: {}", err)) - })?; + let response = rpc_api + .get_block_header_by_number(request) + .await + .map_err(|err| InitError::ClientInitFailed(format!("Failed to get block header: {err}")))?; let root_block_header = response.into_inner().block_header.unwrap(); let root_block_header: BlockHeader = root_block_header.try_into().map_err(|err| { - FaucetError::InternalServerError(format!("Failed to parse block header: {}", err)) + InitError::ClientInitFailed(format!("Failed to parse block header: {err}")) })?; let root_chain_mmr = ChainMmr::new( @@ -287,7 +296,7 @@ fn build_transaction_arguments( output_note: &Note, note_type: NoteType, asset: FungibleAsset, -) -> Result { +) -> Result { let recipient = output_note .recipient() .digest() @@ -310,7 +319,7 @@ fn build_transaction_arguments( let script = TransactionScript::compile(script, vec![], TransactionKernel::assembler()) .map_err(|err| { - FaucetError::InternalServerError(format!("Failed to compile script: {}", err)) + ProcessError::InternalServerError(format!("Failed to compile script: {err}")) })?; let mut transaction_args = TransactionArgs::new(Some(script), None, AdviceMap::new()); diff --git a/bin/faucet/src/config.rs b/bin/faucet/src/config.rs index 16ce094eb..1e443585a 100644 --- a/bin/faucet/src/config.rs +++ b/bin/faucet/src/config.rs @@ -25,12 +25,6 @@ pub struct FaucetConfig { pub max_supply: u64, } -impl FaucetConfig { - pub fn endpoint_url(&self) -> String { - self.endpoint.to_string() - } -} - impl Display for FaucetConfig { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!( diff --git a/bin/faucet/src/errors.rs b/bin/faucet/src/errors.rs index 4e167e855..50777c719 100644 --- a/bin/faucet/src/errors.rs +++ b/bin/faucet/src/errors.rs @@ -1,47 +1,62 @@ -use actix_web::{ - error, - http::{header::ContentType, StatusCode}, - HttpResponse, +use axum::{ + http::{header, StatusCode}, + response::{IntoResponse, Response}, }; use thiserror::Error; #[derive(Debug, Error)] -pub enum FaucetError { +pub enum InitError { #[error("Failed to start faucet: {0}")] - StartError(String), + FaucetFailedToStart(String), - #[error("Client has submitted a bad request: {0}")] - BadRequest(String), + #[error("Failed to initialize client: {0}")] + ClientInitFailed(String), #[error("Failed to configure faucet: {0}")] ConfigurationError(String), + #[error("Failed to create Miden account: {0}")] + AccountCreationError(String), +} + +#[derive(Debug, Error)] +pub enum ProcessError { + #[error("Client has submitted a bad request: {0}")] + BadRequest(String), + #[error("Server has encountered an internal error: {0}")] InternalServerError(String), - #[error("Failed to create Miden account: {0}")] - AccountCreationError(String), + #[error("Page not found: {0}")] + NotFound(String), } -impl error::ResponseError for FaucetError { - fn error_response(&self) -> HttpResponse { - let message = match self { - FaucetError::StartError(msg) => msg.to_string(), - FaucetError::BadRequest(msg) => msg.to_string(), - FaucetError::ConfigurationError(msg) => msg.to_string(), - FaucetError::InternalServerError(msg) => msg.to_string(), - FaucetError::AccountCreationError(msg) => msg.to_string(), - }; - - HttpResponse::build(self.status_code()) - .insert_header(ContentType::html()) - .body(message.to_owned()) +impl ProcessError { + fn status_code(&self) -> StatusCode { + match *self { + Self::BadRequest(_) => StatusCode::BAD_REQUEST, + Self::NotFound(_) => StatusCode::NOT_FOUND, + Self::InternalServerError(_) => StatusCode::INTERNAL_SERVER_ERROR, + } } - fn status_code(&self) -> actix_web::http::StatusCode { - match *self { - FaucetError::BadRequest(_) => StatusCode::BAD_REQUEST, - _ => StatusCode::INTERNAL_SERVER_ERROR, + fn message(&self) -> String { + match self { + Self::BadRequest(msg) => msg, + Self::InternalServerError(_) => "Error processing request", + Self::NotFound(msg) => msg, } + .to_string() + } +} + +impl IntoResponse for ProcessError { + fn into_response(self) -> Response { + ( + self.status_code(), + [(header::CONTENT_TYPE, mime::TEXT_HTML_UTF_8.as_ref())], + self.message(), + ) + .into_response() } } diff --git a/bin/faucet/src/handlers.rs b/bin/faucet/src/handlers.rs index a98daec6f..5e51e4fda 100644 --- a/bin/faucet/src/handlers.rs +++ b/bin/faucet/src/handlers.rs @@ -1,60 +1,71 @@ -use actix_web::{get, http::header, post, web, HttpResponse, Result}; +use axum::{ + extract::{Path, State}, + http::{Response, StatusCode}, + response::IntoResponse, + Json, +}; +use http::header; +use http_body_util::Full; use miden_objects::{ accounts::AccountId, notes::{NoteDetails, NoteExecutionMode, NoteFile, NoteId, NoteTag}, utils::serde::Serializable, }; use serde::{Deserialize, Serialize}; +use tonic::body; use tracing::info; -use crate::{errors::FaucetError, state::FaucetState}; +use crate::{errors::ProcessError, state::FaucetState, COMPONENT}; #[derive(Deserialize)] -struct FaucetRequest { +pub struct FaucetRequest { account_id: String, is_private_note: bool, asset_amount: u64, } #[derive(Serialize)] -struct FaucetMetadataReponse { +pub struct FaucetMetadataReponse { id: String, asset_amount_options: Vec, } -#[get("/get_metadata")] -pub async fn get_metadata(state: web::Data) -> HttpResponse { +pub async fn get_metadata( + State(state): State, +) -> (StatusCode, Json) { let response = FaucetMetadataReponse { id: state.id.to_string(), asset_amount_options: state.config.asset_amount_options.clone(), }; - HttpResponse::Ok().json(response) + (StatusCode::OK, Json(response)) } -#[post("/get_tokens")] pub async fn get_tokens( - req: web::Json, - state: web::Data, -) -> Result { + State(state): State, + Json(req): Json, +) -> Result { info!( - "Received a request with account_id: {}, is_private_note: {}, asset_amount: {}", - req.account_id, req.is_private_note, req.asset_amount + target: COMPONENT, + account_id = %req.account_id, + is_private_note = %req.is_private_note, + asset_amount = %req.asset_amount, + "Received a request", ); // Check that the amount is in the asset amount options if !state.config.asset_amount_options.contains(&req.asset_amount) { - return Err(FaucetError::BadRequest("Invalid asset amount.".to_string()).into()); + return Err(ProcessError::BadRequest("Invalid asset amount".to_string())); } let mut client = state.client.lock().await; // Receive and hex user account id let target_account_id = AccountId::from_hex(req.account_id.as_str()) - .map_err(|err| FaucetError::BadRequest(err.to_string()))?; + .map_err(|err| ProcessError::BadRequest(err.to_string()))?; // Execute transaction - info!("Executing mint transaction for account."); + info!(target: COMPONENT, "Executing mint transaction for account."); let (executed_tx, created_note) = client.execute_mint_transaction( target_account_id, req.is_private_note, @@ -62,7 +73,7 @@ pub async fn get_tokens( )?; // Run transaction prover & send transaction to node - info!("Proving and submitting transaction."); + info!(target: COMPONENT, "Proving and submitting transaction."); let block_height = client.prove_and_submit_transaction(executed_tx).await?; let note_id: NoteId = created_note.id(); @@ -80,17 +91,33 @@ pub async fn get_tokens( } .to_bytes(); - info!("A new note has been created: {}", note_id); + info!(target: COMPONENT, %note_id, "A new note has been created"); // Send generated note to user - Ok(HttpResponse::Ok() - .content_type("application/octet-stream") - .append_header(header::ContentDisposition { - disposition: actix_web::http::header::DispositionType::Attachment, - parameters: vec![actix_web::http::header::DispositionParam::Filename( - "note.mno".to_string(), - )], - }) - .append_header(("Note-Id", note_id.to_string())) - .body(bytes)) + Response::builder() + .status(StatusCode::OK) + .header(header::CONTENT_TYPE, "application/octet-stream") + .header(header::CONTENT_DISPOSITION, "attachment; filename=note.mno") + .header("Note-Id", note_id.to_string()) + .body(body::boxed(Full::from(bytes))) + .map_err(|err| ProcessError::InternalServerError(err.to_string())) +} + +pub async fn get_index(state: State) -> Result { + get_static_file(state, Path("index.html".to_string())).await +} + +pub async fn get_static_file( + State(state): State, + Path(path): Path, +) -> Result { + info!(target: COMPONENT, path, "Serving static file"); + + let static_file = state.static_files.get(path.as_str()).ok_or(ProcessError::NotFound(path))?; + + Response::builder() + .status(StatusCode::OK) + .header(header::CONTENT_TYPE, static_file.mime_type) + .body(body::boxed(Full::from(static_file.data))) + .map_err(|err| ProcessError::InternalServerError(err.to_string())) } diff --git a/bin/faucet/src/main.rs b/bin/faucet/src/main.rs index 3247a4f31..f58f9f184 100644 --- a/bin/faucet/src/main.rs +++ b/bin/faucet/src/main.rs @@ -6,22 +6,24 @@ mod state; use std::{fs::File, io::Write, path::PathBuf}; -use actix_cors::Cors; -use actix_web::{ - middleware::{DefaultHeaders, Logger}, - web, App, HttpServer, +use axum::{ + routing::{get, post}, + Router, }; use clap::{Parser, Subcommand}; -use errors::FaucetError; +use http::HeaderValue; use miden_node_utils::{config::load_config, version::LongVersion}; use state::FaucetState; +use tokio::net::TcpListener; +use tower::ServiceBuilder; +use tower_http::{cors::CorsLayer, set_header::SetResponseHeaderLayer, trace::TraceLayer}; use tracing::info; use crate::{ config::FaucetConfig, - handlers::{get_metadata, get_tokens}, + errors::InitError, + handlers::{get_index, get_metadata, get_static_file, get_tokens}, }; - // CONSTANTS // ================================================================================================= @@ -56,69 +58,71 @@ pub enum Command { // MAIN // ================================================================================================= -#[actix_web::main] -async fn main() -> Result<(), FaucetError> { +#[tokio::main] +async fn main() -> Result<(), InitError> { miden_node_utils::logging::setup_logging() - .map_err(|err| FaucetError::StartError(err.to_string()))?; + .map_err(|err| InitError::FaucetFailedToStart(err.to_string()))?; let cli = Cli::parse(); match &cli.command { Command::Start { config } => { let config: FaucetConfig = load_config(config) - .map_err(|err| FaucetError::ConfigurationError(err.to_string()))?; + .map_err(|err| InitError::ConfigurationError(err.to_string()))?; let faucet_state = FaucetState::new(config.clone()).await?; info!(target: COMPONENT, %config, "Initializing server"); - info!("Server is now running on: {}", config.endpoint_url()); - - HttpServer::new(move || { - let cors = Cors::default().allow_any_origin().allow_any_method(); - App::new() - .app_data(web::Data::new(faucet_state.clone())) - .wrap(cors) - .wrap(Logger::default()) - .wrap(DefaultHeaders::new().add(("Cache-Control", "no-cache"))) - .service(get_metadata) - .service(get_tokens) - .service(actix_web_static_files::ResourceFiles::new( - "/", - static_resources::generate(), - )) - }) - .bind((config.endpoint.host, config.endpoint.port)) - .map_err(|err| FaucetError::StartError(err.to_string()))? - .run() - .await - .map_err(|err| FaucetError::StartError(err.to_string()))?; + let app = Router::new() + .route("/", get(get_index)) + .route("/get_metadata", get(get_metadata)) + .route("/get_tokens", post(get_tokens)) + .route("/*path", get(get_static_file)) + .layer( + ServiceBuilder::new() + .layer(TraceLayer::new_for_http()) + .layer(SetResponseHeaderLayer::if_not_present( + http::header::CACHE_CONTROL, + HeaderValue::from_static("no-cache"), + )) + .layer( + CorsLayer::new() + .allow_origin(tower_http::cors::Any) + .allow_methods(tower_http::cors::Any), + ), + ) + .with_state(faucet_state); + + let listener = TcpListener::bind((config.endpoint.host.as_str(), config.endpoint.port)) + .await + .map_err(|err| InitError::FaucetFailedToStart(err.to_string()))?; + + info!(target: COMPONENT, endpoint = %config.endpoint, "Server started"); + + axum::serve(listener, app).await.unwrap(); }, Command::Init { config_path } => { let current_dir = std::env::current_dir().map_err(|err| { - FaucetError::ConfigurationError(format!("failed to open current directory: {err}")) + InitError::ConfigurationError(format!("failed to open current directory: {err}")) })?; - let mut config_file_path = current_dir.clone(); - config_file_path.push(config_path); - + let config_file_path = current_dir.join(config_path); let config = FaucetConfig::default(); let config_as_toml_string = toml::to_string(&config).map_err(|err| { - FaucetError::ConfigurationError(format!( - "Failed to serialize default config: {err}" - )) + InitError::ConfigurationError(format!("Failed to serialize default config: {err}")) })?; let mut file_handle = File::options().write(true).create_new(true).open(&config_file_path).map_err( - |err| FaucetError::ConfigurationError(format!("Error opening the file: {err}")), + |err| InitError::ConfigurationError(format!("Error opening the file: {err}")), )?; file_handle.write(config_as_toml_string.as_bytes()).map_err(|err| { - FaucetError::ConfigurationError(format!("Error writing to file: {err}")) + InitError::ConfigurationError(format!("Error writing to file: {err}")) })?; - println!("Config file successfully created at: {:?}", config_file_path); + println!("Config file successfully created at: {config_file_path:?}"); }, } diff --git a/bin/faucet/src/state.rs b/bin/faucet/src/state.rs index c94175caf..898a5e7bd 100644 --- a/bin/faucet/src/state.rs +++ b/bin/faucet/src/state.rs @@ -1,11 +1,13 @@ -use std::sync::Arc; +use std::{collections::HashMap, sync::Arc}; -use async_mutex::Mutex; use miden_objects::accounts::AccountId; +use static_files::Resource; +use tokio::sync::Mutex; use tracing::info; -use crate::{client::FaucetClient, config::FaucetConfig, errors::FaucetError}; - +use crate::{ + client::FaucetClient, config::FaucetConfig, errors::InitError, static_resources, COMPONENT, +}; // FAUCET STATE // ================================================================================================ @@ -18,15 +20,18 @@ pub struct FaucetState { pub id: AccountId, pub client: Arc>, pub config: FaucetConfig, + pub static_files: Arc>, } impl FaucetState { - pub async fn new(config: FaucetConfig) -> Result { + pub async fn new(config: FaucetConfig) -> Result { let client = FaucetClient::new(config.clone()).await?; let id = client.get_faucet_id(); let client = Arc::new(Mutex::new(client)); - info!("Faucet initialization successful, account id: {}", id); + let static_files = Arc::new(static_resources::generate()); + + info!(target: COMPONENT, account_id = %id, "Faucet initialization successful"); - Ok(FaucetState { client, id, config }) + Ok(FaucetState { client, id, config, static_files }) } } From 0e352bd94c4a42659d69789b4299737b35e06d0a Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Mon, 14 Oct 2024 19:17:30 +0300 Subject: [PATCH 24/37] `BlockWitness`: pass inputs to the VM through the advice provider (#516) --- CHANGELOG.md | 3 +- .../prover/asm/block_kernel.masm | 224 ++++++++++++------ .../src/block_builder/prover/block_witness.rs | 147 ++++++------ 3 files changed, 227 insertions(+), 147 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9bd903ba..37ded380a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,11 @@ - Optimized state synchronizations by removing unnecessary fetching and parsing of note details (#462). - [BREAKING] Changed `GetAccountDetailsResponse` field to `details` (#481). - Improve `--version` by adding build metadata (#495). -- [BREAKING] Introduced additional limits for note/account number (#503). +- [BREAKING] Introduced additional limits for note/account number (#503). - [BREAKING] Removed support for basic wallets in genesis creation (#510). - Added `GetAccountProofs` endpoint (#506). - Migrated faucet from actix-web to axum (#511). +- Changed the `BlockWitness` to pass the inputs to the VM using only advice provider (#516). ## 0.5.1 (2024-09-12) diff --git a/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm b/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm index 023f2c39a..48139646b 100644 --- a/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm +++ b/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm @@ -13,154 +13,228 @@ const.CHAIN_MMR_PTR=1000 #! Compute the account root #! -#! Stack: [num_accounts_updated, OLD_ACCOUNT_ROOT, -#! NEW_ACCOUNT_HASH_0, account_id_0, ... , NEW_ACCOUNT_HASH_n, account_id_n] -#! Output: [NEW_ACCOUNT_ROOT] +#! Inputs: +#! Operand stack: [] +#! Advice stack: [num_accounts_updated, OLD_ACCOUNT_ROOT, [NEW_ACCOUNT_HASH_i, account_id_i]] +#! Outputs: +#! Operand stack: [NEW_ACCOUNT_ROOT] proc.compute_account_root - dup neq.0 - # => [0 or 1, num_accounts_updated, OLD_ACCOUNT_ROOT, - # NEW_ACCOUNT_HASH_0, account_id_0, ... , NEW_ACCOUNT_HASH_n, account_id_n] + # move the number of updated accounts and an old account root to the operand stack + adv_push.5 + # OS => [OLD_ACCOUNT_ROOT, num_accounts_updated] + # AS => [[NEW_ACCOUNT_HASH_i, account_id_i]] + + # assess if we should loop + dup.4 neq.0 + # OS => [flag, OLD_ACCOUNT_ROOT, num_accounts_updated] + # AS => [[NEW_ACCOUNT_HASH_i, account_id_i]] while.true - # stack: [counter, ROOT_0, ..., NEW_ACCOUNT_HASH_i, account_id_i , ...] + # num_accounts_updated here serves as a counter, so rename it accordingly + # old account root will be updated in each iteration, so rename it to the ROOT_i + # OS => [ROOT_i, counter] + # AS => [[NEW_ACCOUNT_HASH_i, account_id_i]] - # Move counter down for next iteration - movdn.9 - # => [ROOT_i, NEW_ACCOUNT_HASH_i, account_id_i, counter, ...] + # move the account hash to the operand stack and move it below the root + adv_push.4 swapw + # OS => [ROOT_i, NEW_ACCOUNT_HASH_i, counter] + # AS => [account_id_i, [NEW_ACCOUNT_HASH_{i+1}, account_id_{i+1}]] - # Prepare stack for `mtree_set` - movup.8 push.ACCOUNT_TREE_DEPTH - # => [account_tree_depth, account_id_i, ROOT_i, NEW_ACCOUNT_HASH_i, counter, ...] + # move the account id to the operand stack, push the account tree depth + adv_push.1 push.ACCOUNT_TREE_DEPTH + # OS => [account_tree_depth, account_id_i, ROOT_i, NEW_ACCOUNT_HASH_i, counter] + # AS => [[NEW_ACCOUNT_HASH_{i+1}, account_id_{i+1}]] # set new value in SMT mtree_set dropw - # => [ROOT_{i+1}, counter, ...] + # OS => [ROOT_{i+1}, counter] + # AS => [[NEW_ACCOUNT_HASH_{i+1}, account_id_{i+1}]] # loop counter - movup.4 sub.1 dup neq.0 - # => [0 or 1, counter-1, ROOT_{i+1}, ...] + movup.4 sub.1 dup movdn.5 neq.0 + # OS => [flag, ROOT_{i+1}, counter] + # AS => [[NEW_ACCOUNT_HASH_{i+1}, account_id_{i+1}]] end - drop - # => [ROOT_{n-1}] + # drop the counter + movup.4 drop + # OS => [ROOT_{n-1}] + # AS => [] end #! Compute the note root. #! -#! Each batch contains a tree of depth 10 for its created notes. The block's created notes tree is created -#! by aggregating up to 2^6 tree roots coming from the batches contained in the block. +#! Each batch contains a tree of depth 10 for its created notes. The block's created notes tree is +#! created by aggregating up to 2^6 tree roots coming from the batches contained in the block. #! -#! `SMT_EMPTY_ROOT` must be `E16`, the root of the empty tree of depth 16. If less than 2^6 batches are -#! contained in the block, `E10` is used as the padding value; this is derived from the fact that -#! `SMT_EMPTY_ROOT` is `E16`, and that our tree has depth 6. +#! `SMT_EMPTY_ROOT` must be `E16`, the root of the empty tree of depth 16. If less than 2^6 batches +#! are contained in the block, `E10` is used as the padding value; this is derived from the fact +#! that `SMT_EMPTY_ROOT` is `E16`, and that our tree has depth 6. #! -#! Stack: [num_notes_updated, SMT_EMPTY_ROOT, -#! batch_note_root_idx_0, BATCH_NOTE_TREE_ROOT_0, -#! ... , -#! batch_note_root_idx_{n-1}, BATCH_NOTE_TREE_ROOT_{n-1}] -#! Output: [NOTES_ROOT] +#! Inputs: +#! Operand stack: [] +#! Advice stack: [num_notes_updated, SMT_EMPTY_ROOT, [BATCH_NOTE_TREE_ROOT_i, batch_note_root_idx_i]] +#! Outputs: +#! Operand stack: [NOTES_ROOT] proc.compute_note_root + # move the number of updated notes and empty root to the operand stack + adv_push.5 + # OS => [SMT_EMPTY_ROOT, num_notes_updated] + # AS => [[BATCH_NOTE_TREE_ROOT_i, batch_note_root_idx_i]] + # assess if we should loop - dup neq.0 - #=> [0 or 1, num_notes_updated, SMT_EMPTY_ROOT, ... ] + dup.4 neq.0 + # OS => [flag, SMT_EMPTY_ROOT, num_notes_updated] + # AS => [[BATCH_NOTE_TREE_ROOT_i, batch_note_root_idx_i]] while.true - #=> [note_roots_left_to_update, ROOT_i, batch_note_root_idx_i, BATCH_NOTE_TREE_ROOT_i, ... ] + # num_notes_updated here serves as a counter, so rename it accordingly + # empty root will be updated in each iteration, so rename it to the ROOT_i + # OS => [ROOT_i, counter] + # AS => [[BATCH_NOTE_TREE_ROOT_i, batch_note_root_idx_i]] - # Move counter down for next iteration - movdn.9 - #=> [ROOT_i, batch_note_root_idx_i, BATCH_NOTE_TREE_ROOT_i, note_roots_left_to_update, ... ] + # move the batch note tree root to the operand stack and move it below the root + adv_push.4 swapw + # OS => [ROOT_i, BATCH_NOTE_TREE_ROOT_i, counter] + # AS => [batch_note_root_idx_i, [BATCH_NOTE_TREE_ROOT_{i+1}, batch_note_root_idx_{i+1}]] - # Prepare stack for mtree_set - movup.4 push.BLOCK_NOTES_BATCH_TREE_DEPTH - #=> [depth=batch_tree_depth, batch_note_root_idx_i, ROOT_i, - # BATCH_NOTE_TREE_ROOT_i, note_roots_left_to_update, ... ] + # move the batch note root index to the operand stack, push the block notes batch tree depth + adv_push.1 push.BLOCK_NOTES_BATCH_TREE_DEPTH + # OS => [batch_tree_depth, batch_note_root_idx_i, ROOT_i, BATCH_NOTE_TREE_ROOT_i, counter] + # AS => [[BATCH_NOTE_TREE_ROOT_{i+1}, batch_note_root_idx_{i+1}]] + # set new value in SMT mtree_set dropw - #=> [ROOT_{i+1}, note_roots_left_to_update, ... ] - + # OS => [ROOT_{i+1}, counter] + # AS => [[BATCH_NOTE_TREE_ROOT_{i+1}, batch_note_root_idx_{i+1}]] + # loop counter - movup.4 sub.1 dup neq.0 - #=> [0 or 1, note_roots_left_to_update - 1, ROOT_{i+1}, ... ] + movup.4 sub.1 dup movdn.5 neq.0 + # OS => [flag, ROOT_{i+1}, counter] + # AS => [[BATCH_NOTE_TREE_ROOT_{i+1}, batch_note_root_idx_{i+1}]] end - drop - # => [ROOT_{n-1}] + # drop the counter + movup.4 drop + # OS => [ROOT_{n-1}] + # AS => [] end -#! Stack: [num_produced_nullifiers, OLD_NULLIFIER_ROOT, NULLIFIER_VALUE, -#! NULLIFIER_0, ..., NULLIFIER_n] -#! Output: [NULLIFIER_ROOT] +#! Compute the nullifier root. +#! +#! Inputs: +#! Operand stack: [] +#! Advice stack: [num_produced_nullifiers, OLD_NULLIFIER_ROOT, NULLIFIER_VALUE, [NULLIFIER_i]] +#! Outputs: +#! Operand stack: [NULLIFIER_ROOT] proc.compute_nullifier_root + # move the number of produced nullifiers, old root and nullifier value to the operand stack; + # move nullifier value below the root + adv_push.9 swapw + # OS => [OLD_NULLIFIER_ROOT, NULLIFIER_VALUE, num_produced_nullifiers] + # AS => [[NULLIFIER_i]] + # assess if we should loop - dup neq.0 - #=> [0 or 1, num_produced_nullifiers, OLD_NULLIFIER_ROOT, NULLIFIER_VALUE, NULLIFIER_0, ..., NULLIFIER_n ] + dup.8 neq.0 + # OS => [flag, OLD_NULLIFIER_ROOT, NULLIFIER_VALUE, num_produced_nullifiers] + # AS => [[NULLIFIER_i]] while.true - #=> [num_nullifiers_left_to_update, ROOT_i, NULLIFIER_VALUE, NULLIFIER_i, ... ] + # num_produced_nullifiers here serves as a counter, so rename it accordingly + # old nullifier root will be updated in each iteration, so rename it to the ROOT_i + # OS => [ROOT_i, NULLIFIER_VALUE, counter] + # AS => [[NULLIFIER_i]] + + # move the nullifier hash to the operand stack + adv_push.4 + # OS => [NULLIFIER_i, ROOT_i, NULLIFIER_VALUE, counter] + # AS => [[NULLIFIER_{i+1}]] - # Prepare stack for `smt::set` - movdn.12 movupw.2 dupw.2 - #=> [NULLIFIER_VALUE, NULLIFIER_i, ROOT_i, NULLIFIER_VALUE, num_nullifiers_left_to_update, ... ] + # dup the nullifier value + dupw.2 + # OS => [NULLIFIER_VALUE, NULLIFIER_i, ROOT_i, NULLIFIER_VALUE, counter] + # AS => [[NULLIFIER_{i+1}]] exec.smt::set - #=> [OLD_VALUE, ROOT_{i+1}, NULLIFIER_VALUE, num_nullifiers_left_to_update, ... ] + # OS => [OLD_VALUE, ROOT_{i+1}, NULLIFIER_VALUE, counter] + # AS => [[NULLIFIER_{i+1}]] # Check that OLD_VALUE == 0 (i.e. that nullifier was indeed not previously produced) assertz assertz assertz assertz - #=> [ROOT_{i+1}, NULLIFIER_VALUE, num_nullifiers_left_to_update, ... ] + # OS => [ROOT_{i+1}, NULLIFIER_VALUE, counter] + # AS => [[NULLIFIER_{i+1}]] # loop counter - movup.8 sub.1 dup neq.0 - #=> [0 or 1, num_nullifiers_left_to_update - 1, ROOT_{i+1}, NULLIFIER_VALUE, ... ] + movup.8 sub.1 dup movdn.9 neq.0 + # OS => [flag, ROOT_{i+1}, NULLIFIER_VALUE, counter] + # AS => [[NULLIFIER_{i+1}]] end - #=> [0, ROOT_{n-1}, NULLIFIER_VALUE ] - drop swapw dropw - # => [ROOT_{n-1}] + # drop the counter and the nullifier value + swapw dropw movup.4 drop + # OS => [ROOT_{n-1}] + # AS => [] end #! Compute the chain MMR root #! -#! Stack: [ PREV_CHAIN_MMR_HASH, PREV_BLOCK_HASH_TO_INSERT ] -#! Advice map: PREV_CHAIN_MMR_HASH -> NUM_LEAVES || peak_0 || .. || peak_{n-1} || -#! -#! Output: [ CHAIN_MMR_ROOT ] +#! Inputs: +#! Operand stack: [] +#! Advice stack: [PREV_BLOCK_HASH_TO_INSERT, PREV_CHAIN_MMR_HASH] +#! Advice map: { +#! PREV_CHAIN_MMR_HASH: [NUM_LEAVES, [peak_i], ] +#! } +#! Outputs: +#! Operand stack: [CHAIN_MMR_ROOT] proc.compute_chain_mmr_root + # move the previous block hash and chain MMR hash to the operand stack + adv_push.8 + # OS => [PREV_CHAIN_MMR_HASH, PREV_BLOCK_HASH_TO_INSERT] + # AS => [] + + # push chain MMR pointer to the operand stack push.CHAIN_MMR_PTR movdn.4 - # => [ PREV_CHAIN_MMR_HASH, chain_mmr_ptr, PREV_BLOCK_HASH_TO_INSERT ] + # OS => [PREV_CHAIN_MMR_HASH, chain_mmr_ptr, PREV_BLOCK_HASH_TO_INSERT] # load the chain MMR (as of previous block) at memory location CHAIN_MMR_PTR exec.mmr::unpack - # => [ PREV_BLOCK_HASH_TO_INSERT ] + # OS => [PREV_BLOCK_HASH_TO_INSERT] + # push chain MMR pointer to the operand stack push.CHAIN_MMR_PTR movdn.4 - # => [ PREV_BLOCK_HASH_TO_INSERT, chain_mmr_ptr ] + # OS => [PREV_BLOCK_HASH_TO_INSERT, chain_mmr_ptr] # add PREV_BLOCK_HASH_TO_INSERT to chain MMR exec.mmr::add - # => [ ] + # OS => [] # Compute new MMR root push.CHAIN_MMR_PTR exec.mmr::pack - # => [ CHAIN_MMR_ROOT ] + # OS => [CHAIN_MMR_ROOT] end -# Stack: [, , , ] +#! Inputs: +#! Operand stack: [] +#! Advice stack: [, , , ] +#! Advice map: { +#! PREV_CHAIN_MMR_HASH: [NUM_LEAVES, [peak_i], ] +#! } +#! Outputs: +#! Operand stack: [ACCOUNT_ROOT, NOTE_ROOT, NULLIFIER_ROOT, CHAIN_MMR_ROOT] begin exec.compute_account_root mem_storew.0 dropw # => [, , ] exec.compute_note_root mem_storew.1 dropw - # => [ , ] + # => [, ] exec.compute_nullifier_root mem_storew.2 dropw - # => [ ] + # => [] exec.compute_chain_mmr_root - # => [ CHAIN_MMR_ROOT ] + # => [CHAIN_MMR_ROOT] # Load output on stack padw mem_loadw.2 padw mem_loadw.1 padw mem_loadw.0 - #=> [ ACCOUNT_ROOT, NOTE_ROOT, NULLIFIER_ROOT, CHAIN_MMR_ROOT ] -end \ No newline at end of file + # => [ACCOUNT_ROOT, NOTE_ROOT, NULLIFIER_ROOT, CHAIN_MMR_ROOT] +end diff --git a/crates/block-producer/src/block_builder/prover/block_witness.rs b/crates/block-producer/src/block_builder/prover/block_witness.rs index 9bbe473c8..0b4f06567 100644 --- a/crates/block-producer/src/block_builder/prover/block_witness.rs +++ b/crates/block-producer/src/block_builder/prover/block_witness.rs @@ -136,10 +136,9 @@ impl BlockWitness { pub(super) fn into_program_inputs( self, ) -> Result<(AdviceInputs, StackInputs), BlockProverError> { - let stack_inputs = self.build_stack_inputs(); let advice_inputs = self.build_advice_inputs()?; - Ok((advice_inputs, stack_inputs)) + Ok((advice_inputs, StackInputs::default())) } /// Returns an iterator over all transactions which affected accounts in the block with @@ -178,84 +177,88 @@ impl BlockWitness { } } - /// Builds the stack inputs to the block kernel - fn build_stack_inputs(&self) -> StackInputs { - // Note: `StackInputs::new()` reverses the input vector, so we need to construct the stack - // from the bottom to the top - let mut stack_inputs = Vec::new(); - - // Chain MMR stack inputs - { - stack_inputs.extend(self.prev_header.hash()); - stack_inputs.extend(self.chain_peaks.hash_peaks()); - } - - // Nullifiers stack inputs - { - let num_produced_nullifiers: Felt = (self.produced_nullifiers.len() as u64) - .try_into() - .expect("nullifiers number is greater than or equal to the field modulus"); + /// Builds the advice inputs to the block kernel + fn build_advice_inputs(self) -> Result { + let advice_stack = { + let mut advice_stack = Vec::new(); + + // add account stack inputs to the advice stack + { + let mut account_data = Vec::new(); + let mut num_accounts_updated: u64 = 0; + for (idx, (account_id, account_update)) in self.updated_accounts.iter().enumerate() + { + account_data.extend(account_update.final_state_hash); + account_data.push((*account_id).into()); + + let idx = u64::try_from(idx).expect("can't be more than 2^64 - 1 accounts"); + num_accounts_updated = idx + 1; + } + + // append number of accounts updated + advice_stack.push(num_accounts_updated.try_into().expect( + "updated accounts number is greater than or equal to the field modulus", + )); + + // append initial account root + advice_stack.extend(self.prev_header.account_root()); + + // append the updated accounts data + advice_stack.extend(account_data); + } - for nullifier in self.produced_nullifiers.keys() { - stack_inputs.extend(nullifier.inner()); + // add notes stack inputs to the advice stack + { + // append the number of updated notes + advice_stack + .push(Felt::try_from(self.batch_created_notes_roots.len() as u64).expect( + "notes roots number is greater than or equal to the field modulus", + )); + + // append the empty root + let empty_root = EmptySubtreeRoots::entry(BLOCK_NOTE_TREE_DEPTH, 0); + advice_stack.extend(*empty_root); + + for (batch_index, batch_created_notes_root) in self.batch_created_notes_roots.iter() + { + advice_stack.extend(batch_created_notes_root.iter()); + + let batch_index = Felt::try_from(*batch_index as u64) + .expect("batch index is greater than or equal to the field modulus"); + advice_stack.push(batch_index); + } } - // append nullifier value (`[block_num, 0, 0, 0]`) - let block_num = self.prev_header.block_num() + 1; - stack_inputs.extend([block_num.into(), ZERO, ZERO, ZERO]); + // Nullifiers stack inputs + { + let num_produced_nullifiers: Felt = (self.produced_nullifiers.len() as u64) + .try_into() + .expect("nullifiers number is greater than or equal to the field modulus"); - // append initial nullifier root - stack_inputs.extend(self.prev_header.nullifier_root()); + // append number of nullifiers + advice_stack.push(num_produced_nullifiers); - // append number of nullifiers - stack_inputs.push(num_produced_nullifiers); - } + // append initial nullifier root + advice_stack.extend(self.prev_header.nullifier_root()); - // Notes stack inputs - { - for (batch_index, batch_created_notes_root) in self.batch_created_notes_roots.iter() { - stack_inputs.extend(batch_created_notes_root.iter()); + // append nullifier value (`[block_num, 0, 0, 0]`) + let block_num = self.prev_header.block_num() + 1; + advice_stack.extend([block_num.into(), ZERO, ZERO, ZERO]); - let batch_index = Felt::try_from(*batch_index as u64) - .expect("batch index is greater than or equal to the field modulus"); - stack_inputs.push(batch_index); + for nullifier in self.produced_nullifiers.keys() { + advice_stack.extend(nullifier.inner()); + } } - let empty_root = EmptySubtreeRoots::entry(BLOCK_NOTE_TREE_DEPTH, 0); - stack_inputs.extend(*empty_root); - stack_inputs.push( - Felt::try_from(self.batch_created_notes_roots.len() as u64) - .expect("notes roots number is greater than or equal to the field modulus"), - ); - } - - // Account stack inputs - let mut num_accounts_updated: u64 = 0; - for (idx, (account_id, account_update)) in self.updated_accounts.iter().enumerate() { - stack_inputs.push((*account_id).into()); - stack_inputs.extend(account_update.final_state_hash); - - let idx = u64::try_from(idx).expect("can't be more than 2^64 - 1 accounts"); - num_accounts_updated = idx + 1; - } - - // append initial account root - stack_inputs.extend(self.prev_header.account_root()); - - // append number of accounts updated - stack_inputs.push( - num_accounts_updated - .try_into() - .expect("updated accounts number is greater than or equal to the field modulus"), - ); + // Chain MMR stack inputs + { + advice_stack.extend(self.prev_header.hash()); + advice_stack.extend(self.chain_peaks.hash_peaks()); + } - // TODO: We need provide produced nullifier different way, because such big stack inputs - // will cause problem in recursive proofs - StackInputs::new(stack_inputs).expect("Stack inputs count extends max limit") - } + advice_stack + }; - /// Builds the advice inputs to the block kernel - fn build_advice_inputs(self) -> Result { let merkle_store = { let mut merkle_store = MerkleStore::default(); @@ -290,8 +293,10 @@ impl BlockWitness { .chain(std::iter::once(mmr_peaks_advice_map_key_value(&self.chain_peaks))) .collect(); - let advice_inputs = - AdviceInputs::default().with_merkle_store(merkle_store).with_map(advice_map); + let advice_inputs = AdviceInputs::default() + .with_merkle_store(merkle_store) + .with_map(advice_map) + .with_stack(advice_stack); Ok(advice_inputs) } From d9201488974d3222eb56650c126d754372602d42 Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Tue, 22 Oct 2024 00:20:19 +0500 Subject: [PATCH 25/37] feat(store): improve errors (#518) * feat: improve node errors * docs: update `CHANGELOG.md` --- CHANGELOG.md | 1 + crates/store/src/errors.rs | 16 +++++- crates/store/src/server/api.rs | 89 +++++++++++++--------------------- crates/store/src/state.rs | 4 +- 4 files changed, 51 insertions(+), 59 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37ded380a..88d847b05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - Added `GetAccountProofs` endpoint (#506). - Migrated faucet from actix-web to axum (#511). - Changed the `BlockWitness` to pass the inputs to the VM using only advice provider (#516). +- [BREAKING] Improved store API errors (return "not found" instead of "internal error" status if requested account(s) not found) (#518). ## 0.5.1 (2024-09-12) diff --git a/crates/store/src/errors.rs b/crates/store/src/errors.rs index 2666c138a..700c9d3c5 100644 --- a/crates/store/src/errors.rs +++ b/crates/store/src/errors.rs @@ -14,6 +14,7 @@ use miden_objects::{ use rusqlite::types::FromSqlError; use thiserror::Error; use tokio::sync::oneshot::error::RecvError; +use tonic::Status; use crate::types::{AccountId, BlockNumber}; @@ -60,8 +61,6 @@ pub enum DatabaseError { InteractError(String), #[error("Deserialization of BLOB data from database failed: {0}")] DeserializationError(DeserializationError), - #[error("Corrupted data: {0}")] - CorruptedData(String), #[error("Invalid Felt: {0}")] InvalidFelt(String), #[error("Block applying was broken because of closed channel on state side: {0}")] @@ -91,6 +90,19 @@ impl From for DatabaseError { } } +impl From for Status { + fn from(err: DatabaseError) -> Self { + match err { + DatabaseError::AccountNotFoundInDb(_) + | DatabaseError::AccountsNotFoundInDb(_) + | DatabaseError::AccountNotOnChain(_) + | DatabaseError::BlockNotFoundInDb(_) => Status::not_found(err.to_string()), + + _ => Status::internal(err.to_string()), + } + } +} + // INITIALIZATION ERRORS // ================================================================================================= diff --git a/crates/store/src/server/api.rs b/crates/store/src/server/api.rs index 38e4bdaf7..0018ff166 100644 --- a/crates/store/src/server/api.rs +++ b/crates/store/src/server/api.rs @@ -70,7 +70,7 @@ impl api_server::Api for StoreApi { )] async fn get_block_header_by_number( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { info!(target: COMPONENT, ?request); let request = request.into_inner(); @@ -102,7 +102,7 @@ impl api_server::Api for StoreApi { )] async fn check_nullifiers( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { // Validate the nullifiers and convert them to Digest values. Stop on first error. let request = request.into_inner(); @@ -126,7 +126,7 @@ impl api_server::Api for StoreApi { )] async fn check_nullifiers_by_prefix( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { let request = request.into_inner(); @@ -137,8 +137,7 @@ impl api_server::Api for StoreApi { let nullifiers = self .state .check_nullifiers_by_prefix(request.prefix_len, request.nullifiers) - .await - .map_err(internal_error)? + .await? .into_iter() .map(|nullifier_info| NullifierUpdate { nullifier: Some(nullifier_info.nullifier.into()), @@ -160,7 +159,7 @@ impl api_server::Api for StoreApi { )] async fn sync_state( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { let request = request.into_inner(); @@ -224,7 +223,7 @@ impl api_server::Api for StoreApi { )] async fn sync_notes( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { let request = request.into_inner(); @@ -256,7 +255,7 @@ impl api_server::Api for StoreApi { )] async fn get_notes_by_id( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { info!(target: COMPONENT, ?request); @@ -270,8 +269,7 @@ impl api_server::Api for StoreApi { let notes = self .state .get_notes_by_id(note_ids) - .await - .map_err(internal_error)? + .await? .into_iter() .map(Into::into) .collect(); @@ -289,7 +287,7 @@ impl api_server::Api for StoreApi { )] async fn get_note_authentication_info( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { info!(target: COMPONENT, ?request); @@ -325,7 +323,7 @@ impl api_server::Api for StoreApi { )] async fn get_account_details( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { let request = request.into_inner(); let account_info = self @@ -333,8 +331,7 @@ impl api_server::Api for StoreApi { .get_account_details( request.account_id.ok_or(invalid_argument("Account missing id"))?.into(), ) - .await - .map_err(internal_error)?; + .await?; Ok(Response::new(GetAccountDetailsResponse { details: Some((&account_info).into()), @@ -354,8 +351,8 @@ impl api_server::Api for StoreApi { )] async fn apply_block( &self, - request: tonic::Request, - ) -> Result, tonic::Status> { + request: Request, + ) -> Result, Status> { let request = request.into_inner(); debug!(target: COMPONENT, ?request); @@ -391,7 +388,7 @@ impl api_server::Api for StoreApi { )] async fn get_block_inputs( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { let request = request.into_inner(); @@ -417,7 +414,7 @@ impl api_server::Api for StoreApi { )] async fn get_transaction_inputs( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { let request = request.into_inner(); @@ -430,8 +427,7 @@ impl api_server::Api for StoreApi { let tx_inputs = self .state .get_transaction_inputs(account_id, &nullifiers, unauthenticated_notes) - .await - .map_err(internal_error)?; + .await?; let block_height = self.state.latest_block_num().await; @@ -466,13 +462,13 @@ impl api_server::Api for StoreApi { )] async fn get_block_by_number( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { let request = request.into_inner(); debug!(target: COMPONENT, ?request); - let block = self.state.load_block(request.block_num).await.map_err(internal_error)?; + let block = self.state.load_block(request.block_num).await?; Ok(Response::new(GetBlockByNumberResponse { block })) } @@ -494,11 +490,8 @@ impl api_server::Api for StoreApi { let account_ids = convert(request.account_ids); let include_headers = request.include_headers.unwrap_or_default(); - let (block_num, infos) = self - .state - .get_account_states(account_ids, include_headers) - .await - .map_err(internal_error)?; + let (block_num, infos) = + self.state.get_account_proofs(account_ids, include_headers).await?; Ok(Response::new(GetAccountProofsResponse { block_num, @@ -515,7 +508,7 @@ impl api_server::Api for StoreApi { )] async fn get_account_state_delta( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { let request = request.into_inner(); @@ -528,8 +521,7 @@ impl api_server::Api for StoreApi { request.from_block_num, request.to_block_num, ) - .await - .map_err(internal_error)?; + .await?; Ok(Response::new(GetAccountStateDeltaResponse { delta: Some(delta.to_bytes()) })) } @@ -547,9 +539,9 @@ impl api_server::Api for StoreApi { )] async fn list_nullifiers( &self, - _request: tonic::Request, + _request: Request, ) -> Result, Status> { - let raw_nullifiers = self.state.list_nullifiers().await.map_err(internal_error)?; + let raw_nullifiers = self.state.list_nullifiers().await?; let nullifiers = raw_nullifiers .into_iter() .map(|(key, block_num)| SmtLeafEntry { @@ -570,16 +562,9 @@ impl api_server::Api for StoreApi { )] async fn list_notes( &self, - _request: tonic::Request, + _request: Request, ) -> Result, Status> { - let notes = self - .state - .list_notes() - .await - .map_err(internal_error)? - .into_iter() - .map(Into::into) - .collect(); + let notes = self.state.list_notes().await?.into_iter().map(Into::into).collect(); Ok(Response::new(ListNotesResponse { notes })) } @@ -593,16 +578,9 @@ impl api_server::Api for StoreApi { )] async fn list_accounts( &self, - _request: tonic::Request, + _request: Request, ) -> Result, Status> { - let accounts = self - .state - .list_accounts() - .await - .map_err(internal_error)? - .iter() - .map(Into::into) - .collect(); + let accounts = self.state.list_accounts().await?.iter().map(Into::into).collect(); Ok(Response::new(ListAccountsResponse { accounts })) } } @@ -610,13 +588,14 @@ impl api_server::Api for StoreApi { // UTILITIES // ================================================================================================ -/// Formats an error -fn internal_error(err: E) -> Status { - Status::internal(format!("{:?}", err)) +/// Formats an "Internal error" error +fn internal_error(err: E) -> Status { + Status::internal(err.to_string()) } -fn invalid_argument(err: E) -> Status { - Status::invalid_argument(format!("{:?}", err)) +/// Formats an "Invalid argument" error +fn invalid_argument(err: E) -> Status { + Status::invalid_argument(err.to_string()) } #[instrument(target = "miden-store", skip_all, err)] diff --git a/crates/store/src/state.rs b/crates/store/src/state.rs index 44e03425c..294f1ebcb 100644 --- a/crates/store/src/state.rs +++ b/crates/store/src/state.rs @@ -679,8 +679,8 @@ impl State { self.db.select_account(id).await } - /// Returns account states with details for public accounts. - pub async fn get_account_states( + /// Returns account proofs with optional account and storage headers. + pub async fn get_account_proofs( &self, account_ids: Vec, include_headers: bool, From b0a1721ceb8bf709242143b436407ed7e709373f Mon Sep 17 00:00:00 2001 From: igamigo Date: Wed, 23 Oct 2024 10:45:51 -0300 Subject: [PATCH 26/37] feat: Return code for FPI (#521) * feat: Return code for FPI * Rename var * CHANGELOG * Address comments * Check earlier * Address comments * Force proto rebuild * Update crates/rpc-proto/proto/responses.proto Co-authored-by: Mirko <48352201+Mirko-von-Leipzig@users.noreply.github.com> * Update description * Proto rebuild * Update description --------- Co-authored-by: Mirko <48352201+Mirko-von-Leipzig@users.noreply.github.com> --- CHANGELOG.md | 1 + crates/proto/src/generated/requests.rs | 6 +++++- crates/proto/src/generated/responses.rs | 4 ++++ crates/rpc-proto/proto/requests.proto | 5 ++++- crates/rpc-proto/proto/responses.proto | 3 +++ crates/store/src/server/api.rs | 20 ++++++++++++++++---- crates/store/src/state.rs | 14 +++++++++++--- proto/requests.proto | 5 ++++- proto/responses.proto | 3 +++ 9 files changed, 51 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88d847b05..572ed2678 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## v0.6.0 (TBD) +- Added `AccountCode` as part of `GetAccountProofs` endpoint response (#521). - [BREAKING] Added `kernel_root` to block header's protobuf message definitions (#496). - [BREAKING] Renamed `off-chain` and `on-chain` to `private` and `public` respectively for the account storage modes (#489). - Optimized state synchronizations by removing unnecessary fetching and parsing of note details (#462). diff --git a/crates/proto/src/generated/requests.rs b/crates/proto/src/generated/requests.rs index 34db2cb62..ee5c70caf 100644 --- a/crates/proto/src/generated/requests.rs +++ b/crates/proto/src/generated/requests.rs @@ -153,7 +153,11 @@ pub struct GetAccountProofsRequest { /// List of account IDs to get states. #[prost(message, repeated, tag = "1")] pub account_ids: ::prost::alloc::vec::Vec, + /// Account code commitments corresponding to the last-known `AccountCode` for requested + /// accounts. Responses will include only the ones that are not known to the caller. + #[prost(message, repeated, tag = "2")] + pub code_commitments: ::prost::alloc::vec::Vec, /// Optional flag to include header in the response. `false` by default. - #[prost(bool, optional, tag = "2")] + #[prost(bool, optional, tag = "3")] pub include_headers: ::core::option::Option, } diff --git a/crates/proto/src/generated/responses.rs b/crates/proto/src/generated/responses.rs index a871cbe31..b0d695bb8 100644 --- a/crates/proto/src/generated/responses.rs +++ b/crates/proto/src/generated/responses.rs @@ -227,4 +227,8 @@ pub struct AccountStateHeader { /// Values of all account storage slots (max 255). #[prost(bytes = "vec", tag = "2")] pub storage_header: ::prost::alloc::vec::Vec, + /// Account code, returned only when none of the request's code commitments match with the + /// current one. + #[prost(bytes = "vec", optional, tag = "3")] + pub account_code: ::core::option::Option<::prost::alloc::vec::Vec>, } diff --git a/crates/rpc-proto/proto/requests.proto b/crates/rpc-proto/proto/requests.proto index 9f9554b48..5751f3978 100644 --- a/crates/rpc-proto/proto/requests.proto +++ b/crates/rpc-proto/proto/requests.proto @@ -135,6 +135,9 @@ message GetAccountStateDeltaRequest { message GetAccountProofsRequest { // List of account IDs to get states. repeated account.AccountId account_ids = 1; + // Account code commitments corresponding to the last-known `AccountCode` for requested + // accounts. Responses will include only the ones that are not known to the caller. + repeated digest.Digest code_commitments = 2; // Optional flag to include header in the response. `false` by default. - optional bool include_headers = 2; + optional bool include_headers = 3; } diff --git a/crates/rpc-proto/proto/responses.proto b/crates/rpc-proto/proto/responses.proto index 7d7d00032..b586458b1 100644 --- a/crates/rpc-proto/proto/responses.proto +++ b/crates/rpc-proto/proto/responses.proto @@ -197,4 +197,7 @@ message AccountStateHeader { account.AccountHeader header = 1; // Values of all account storage slots (max 255). bytes storage_header = 2; + // Account code, returned only when none of the request's code commitments match with the + // current one. + optional bytes account_code = 3; } diff --git a/crates/store/src/server/api.rs b/crates/store/src/server/api.rs index 0018ff166..5ca4930ed 100644 --- a/crates/store/src/server/api.rs +++ b/crates/store/src/server/api.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::{collections::BTreeSet, sync::Arc}; use miden_node_proto::{ convert, @@ -485,13 +485,25 @@ impl api_server::Api for StoreApi { request: Request, ) -> Result, Status> { let request = request.into_inner(); + if request.account_ids.len() > request.code_commitments.len() { + return Err(Status::invalid_argument( + "The number of code commitments should not exceed the number of requested accounts.", + )); + } debug!(target: COMPONENT, ?request); - let account_ids = convert(request.account_ids); let include_headers = request.include_headers.unwrap_or_default(); - let (block_num, infos) = - self.state.get_account_proofs(account_ids, include_headers).await?; + let account_ids: Vec = convert(request.account_ids); + let request_code_commitments: BTreeSet = try_convert(request.code_commitments) + .map_err(|err| { + Status::invalid_argument(format!("Invalid code commitment: {}", err)) + })?; + + let (block_num, infos) = self + .state + .get_account_proofs(account_ids, request_code_commitments, include_headers) + .await?; Ok(Response::new(GetAccountProofsResponse { block_num, diff --git a/crates/store/src/state.rs b/crates/store/src/state.rs index 294f1ebcb..31b8607c2 100644 --- a/crates/store/src/state.rs +++ b/crates/store/src/state.rs @@ -5,6 +5,7 @@ use std::{ collections::{BTreeMap, BTreeSet}, + ops::Not, sync::Arc, }; @@ -683,6 +684,7 @@ impl State { pub async fn get_account_proofs( &self, account_ids: Vec, + request_code_commitments: BTreeSet, include_headers: bool, ) -> Result<(BlockNumber, Vec), DatabaseError> { // Lock inner state for the whole operation. We need to hold this lock to prevent the @@ -696,8 +698,7 @@ impl State { let infos = self.db.select_accounts_by_ids(account_ids.clone()).await?; if account_ids.len() > infos.len() { - let found_ids: BTreeSet = - infos.iter().map(|info| info.summary.account_id.into()).collect(); + let found_ids = infos.iter().map(|info| info.summary.account_id.into()).collect(); return Err(DatabaseError::AccountsNotFoundInDb( BTreeSet::from_iter(account_ids).difference(&found_ids).copied().collect(), )); @@ -712,6 +713,12 @@ impl State { AccountStateHeader { header: Some(AccountHeader::from(&details).into()), storage_header: details.storage().get_header().to_bytes(), + // Only include account code if the request did not contain it + // (known by the caller) + account_code: request_code_commitments + .contains(&details.code().commitment()) + .not() + .then_some(details.code().to_bytes()), }, ) }) @@ -724,12 +731,13 @@ impl State { .map(|account_id| { let acc_leaf_idx = LeafIndex::new_max_depth(account_id); let opening = inner_state.account_tree.open(&acc_leaf_idx); + let state_header = state_headers.get(&account_id).cloned(); AccountProofsResponse { account_id: Some(account_id.into()), account_hash: Some(opening.value.into()), account_proof: Some(opening.path.into()), - state_header: state_headers.get(&account_id).cloned(), + state_header, } }) .collect(); diff --git a/proto/requests.proto b/proto/requests.proto index 9f9554b48..5751f3978 100644 --- a/proto/requests.proto +++ b/proto/requests.proto @@ -135,6 +135,9 @@ message GetAccountStateDeltaRequest { message GetAccountProofsRequest { // List of account IDs to get states. repeated account.AccountId account_ids = 1; + // Account code commitments corresponding to the last-known `AccountCode` for requested + // accounts. Responses will include only the ones that are not known to the caller. + repeated digest.Digest code_commitments = 2; // Optional flag to include header in the response. `false` by default. - optional bool include_headers = 2; + optional bool include_headers = 3; } diff --git a/proto/responses.proto b/proto/responses.proto index 7d7d00032..b586458b1 100644 --- a/proto/responses.proto +++ b/proto/responses.proto @@ -197,4 +197,7 @@ message AccountStateHeader { account.AccountHeader header = 1; // Values of all account storage slots (max 255). bytes storage_header = 2; + // Account code, returned only when none of the request's code commitments match with the + // current one. + optional bytes account_code = 3; } From 3df08adeaf8ce809023ef7e9e7e8b67baf636c48 Mon Sep 17 00:00:00 2001 From: igamigo Date: Thu, 24 Oct 2024 15:30:13 -0300 Subject: [PATCH 27/37] fix: Incorrect validation (#526) --- crates/proto/src/generated/requests.rs | 10 ++++++---- crates/rpc-proto/proto/requests.proto | 8 +++++--- crates/store/src/server/api.rs | 2 +- proto/requests.proto | 8 +++++--- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/crates/proto/src/generated/requests.rs b/crates/proto/src/generated/requests.rs index ee5c70caf..db4d238a5 100644 --- a/crates/proto/src/generated/requests.rs +++ b/crates/proto/src/generated/requests.rs @@ -153,11 +153,13 @@ pub struct GetAccountProofsRequest { /// List of account IDs to get states. #[prost(message, repeated, tag = "1")] pub account_ids: ::prost::alloc::vec::Vec, + /// Optional flag to include header and account code in the response. `false` by default. + #[prost(bool, optional, tag = "2")] + pub include_headers: ::core::option::Option, /// Account code commitments corresponding to the last-known `AccountCode` for requested /// accounts. Responses will include only the ones that are not known to the caller. - #[prost(message, repeated, tag = "2")] + /// These are not associated with a specific account but rather, they will be matched against + /// all requested accounts. + #[prost(message, repeated, tag = "3")] pub code_commitments: ::prost::alloc::vec::Vec, - /// Optional flag to include header in the response. `false` by default. - #[prost(bool, optional, tag = "3")] - pub include_headers: ::core::option::Option, } diff --git a/crates/rpc-proto/proto/requests.proto b/crates/rpc-proto/proto/requests.proto index 5751f3978..31a0cb68e 100644 --- a/crates/rpc-proto/proto/requests.proto +++ b/crates/rpc-proto/proto/requests.proto @@ -135,9 +135,11 @@ message GetAccountStateDeltaRequest { message GetAccountProofsRequest { // List of account IDs to get states. repeated account.AccountId account_ids = 1; + // Optional flag to include header and account code in the response. `false` by default. + optional bool include_headers = 2; // Account code commitments corresponding to the last-known `AccountCode` for requested // accounts. Responses will include only the ones that are not known to the caller. - repeated digest.Digest code_commitments = 2; - // Optional flag to include header in the response. `false` by default. - optional bool include_headers = 3; + // These are not associated with a specific account but rather, they will be matched against + // all requested accounts. + repeated digest.Digest code_commitments = 3; } diff --git a/crates/store/src/server/api.rs b/crates/store/src/server/api.rs index 5ca4930ed..51cb21ef4 100644 --- a/crates/store/src/server/api.rs +++ b/crates/store/src/server/api.rs @@ -485,7 +485,7 @@ impl api_server::Api for StoreApi { request: Request, ) -> Result, Status> { let request = request.into_inner(); - if request.account_ids.len() > request.code_commitments.len() { + if request.account_ids.len() < request.code_commitments.len() { return Err(Status::invalid_argument( "The number of code commitments should not exceed the number of requested accounts.", )); diff --git a/proto/requests.proto b/proto/requests.proto index 5751f3978..31a0cb68e 100644 --- a/proto/requests.proto +++ b/proto/requests.proto @@ -135,9 +135,11 @@ message GetAccountStateDeltaRequest { message GetAccountProofsRequest { // List of account IDs to get states. repeated account.AccountId account_ids = 1; + // Optional flag to include header and account code in the response. `false` by default. + optional bool include_headers = 2; // Account code commitments corresponding to the last-known `AccountCode` for requested // accounts. Responses will include only the ones that are not known to the caller. - repeated digest.Digest code_commitments = 2; - // Optional flag to include header in the response. `false` by default. - optional bool include_headers = 3; + // These are not associated with a specific account but rather, they will be matched against + // all requested accounts. + repeated digest.Digest code_commitments = 3; } From 22d3216bd113a35c1ade3bbf53d6825f6a919b6d Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Mon, 28 Oct 2024 20:59:07 +0300 Subject: [PATCH 28/37] chore: migrate to `miden-vm` v0.11 (#528) --- CHANGELOG.md | 1 + Cargo.lock | 329 +++++++++--------- Cargo.toml | 10 +- Makefile | 2 +- bin/faucet/src/client.rs | 45 +-- .../prover/asm/block_kernel.masm | 4 + .../src/block_builder/prover/mod.rs | 2 +- .../src/block_builder/prover/tests.rs | 2 +- crates/block-producer/src/test_utils/block.rs | 4 +- crates/block-producer/src/test_utils/store.rs | 10 +- crates/store/src/state.rs | 29 +- rust-toolchain.toml | 2 +- 12 files changed, 223 insertions(+), 217 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 572ed2678..33f4807f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Migrated faucet from actix-web to axum (#511). - Changed the `BlockWitness` to pass the inputs to the VM using only advice provider (#516). - [BREAKING] Improved store API errors (return "not found" instead of "internal error" status if requested account(s) not found) (#518). +- [BREAKING] Migrated to v0.11 version of Miden VM (#528). ## 0.5.1 (2024-09-12) diff --git a/Cargo.lock b/Cargo.lock index e110537a5..ee1f4a6e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] @@ -55,9 +55,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" dependencies = [ "anstyle", "anstyle-parse", @@ -70,43 +70,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" [[package]] name = "arrayref" @@ -131,9 +131,9 @@ dependencies = [ [[package]] name = "async-stream" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" dependencies = [ "async-stream-impl", "futures-core", @@ -142,9 +142,9 @@ dependencies = [ [[package]] name = "async-stream-impl" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", @@ -276,9 +276,9 @@ checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ "bitflags", "cexpr", @@ -345,9 +345,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" [[package]] name = "byteorder" @@ -357,9 +357,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "camino" @@ -395,9 +395,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.21" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "jobserver", "libc", @@ -456,9 +456,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.18" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -466,9 +466,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.18" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -496,9 +496,9 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "constant_time_eq" @@ -648,18 +648,18 @@ dependencies = [ [[package]] name = "derive_builder" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ "darling", "proc-macro2", @@ -669,9 +669,9 @@ dependencies = [ [[package]] name = "derive_builder_macro" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", "syn", @@ -823,9 +823,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -837,9 +837,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -847,33 +847,33 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-sink", @@ -918,9 +918,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" @@ -940,7 +940,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.5.0", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -962,6 +962,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + [[package]] name = "hashlink" version = "0.9.1" @@ -1025,9 +1031,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -1037,9 +1043,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" dependencies = [ "bytes", "futures-channel", @@ -1071,9 +1077,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", "futures-channel", @@ -1135,12 +1141,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.0", ] [[package]] @@ -1205,9 +1211,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -1234,7 +1240,7 @@ dependencies = [ "lalrpop-util", "petgraph", "regex", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", "string_cache", "term", "tiny-keccak", @@ -1262,9 +1268,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libloading" @@ -1278,9 +1284,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "a00419de735aac21d53b0de5ce2c03bd3627277cf471300f27ebc89f7d828047" [[package]] name = "libredox" @@ -1346,7 +1352,7 @@ dependencies = [ "lazy_static", "proc-macro2", "quote", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", "syn", ] @@ -1396,8 +1402,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miden-air" version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2702f8adb96844e3521f49149f6c3d4773ecdd2a96a3169e3c025a2e3ee32b5e" +source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" dependencies = [ "miden-core", "miden-thiserror", @@ -1408,8 +1413,7 @@ dependencies = [ [[package]] name = "miden-assembly" version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae9cef4fbafb4fe26da18574bcdbd78815857cfe1099760782701ababb076c2" +source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" dependencies = [ "aho-corasick", "lalrpop", @@ -1426,8 +1430,7 @@ dependencies = [ [[package]] name = "miden-core" version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc3f6db878d6b56c1566cd5b832908675566d3919b9a3523d630dfb5e2f7422d" +source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" dependencies = [ "lock_api", "loom", @@ -1445,9 +1448,9 @@ dependencies = [ [[package]] name = "miden-crypto" -version = "0.10.3" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "825fc5d2e4c951f45da54da2d0d23071918d966133f85dbc219694e0b9a1e141" +checksum = "1e0ca714c8242f329b9ea6f1a5bf0e93f1490f348f982e3a606d91b884254308" dependencies = [ "blake3", "cc", @@ -1502,7 +1505,7 @@ dependencies = [ [[package]] name = "miden-lib" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#9dc06d705b8f4cae86ff08a293f379c206f13421" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#b624d0810b1b3813f106aa38b796b9d62a39265d" dependencies = [ "miden-assembly", "miden-objects", @@ -1696,7 +1699,7 @@ dependencies = [ [[package]] name = "miden-objects" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#9dc06d705b8f4cae86ff08a293f379c206f13421" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#b624d0810b1b3813f106aa38b796b9d62a39265d" dependencies = [ "miden-assembly", "miden-core", @@ -1710,8 +1713,7 @@ dependencies = [ [[package]] name = "miden-processor" version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04a128e20400086c9a985f4e5702e438ba781338fb0bdf9acff16d996c640087" +source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" dependencies = [ "miden-air", "miden-core", @@ -1722,8 +1724,7 @@ dependencies = [ [[package]] name = "miden-prover" version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "680d9203cee09b3cee6f79dc952a15f18a1eb47744ffac4f4e559d02bfcdee7a" +source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" dependencies = [ "miden-air", "miden-processor", @@ -1738,8 +1739,7 @@ version = "0.6.0" [[package]] name = "miden-stdlib" version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41623ad4f4ea6449760f70ab8928c682c3824d735d3e330f07e3d24d1ad20bfa" +source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" dependencies = [ "miden-assembly", ] @@ -1767,8 +1767,10 @@ dependencies = [ [[package]] name = "miden-tx" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#9dc06d705b8f4cae86ff08a293f379c206f13421" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#b624d0810b1b3813f106aa38b796b9d62a39265d" dependencies = [ + "async-trait", + "miden-assembly", "miden-lib", "miden-objects", "miden-processor", @@ -1776,14 +1778,15 @@ dependencies = [ "miden-verifier", "rand", "rand_chacha", - "winter-maybe-async 0.10.0", + "regex", + "walkdir", + "winter-maybe-async 0.10.1", ] [[package]] name = "miden-verifier" version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e8144a126ecb1941122e8261e85f2e8e94c0b82740bc23879c0a14263f48797" +source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" dependencies = [ "miden-air", "miden-core", @@ -2009,18 +2012,18 @@ dependencies = [ [[package]] name = "object" -version = "0.36.4" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "option-ext" @@ -2114,7 +2117,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.5.0", + "indexmap 2.6.0", ] [[package]] @@ -2128,18 +2131,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", @@ -2148,9 +2151,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -2187,9 +2190,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prettyplease" -version = "0.2.22" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", "syn", @@ -2197,9 +2200,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -2231,7 +2234,7 @@ dependencies = [ "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", "rusty-fork", "tempfile", "unarray", @@ -2406,9 +2409,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags", ] @@ -2426,14 +2429,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -2447,13 +2450,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", ] [[package]] @@ -2464,9 +2467,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rusqlite" @@ -2524,9 +2527,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" dependencies = [ "bitflags", "errno", @@ -2537,9 +2540,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "rusty-fork" @@ -2606,18 +2609,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", @@ -2626,9 +2629,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", @@ -2797,9 +2800,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "2.0.77" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote", @@ -2818,11 +2821,17 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +[[package]] +name = "target-triple" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a4d50cdb458045afc8131fd91b64904da29548bcb63c7236e0844936c13078" + [[package]] name = "tempfile" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", "fastrand", @@ -2874,18 +2883,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", @@ -2946,9 +2955,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", "bytes", @@ -3022,7 +3031,7 @@ version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", @@ -3269,15 +3278,16 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.99" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "207aa50d36c4be8d8c6ea829478be44a372c6a77669937bb39c698e52f1491e8" +checksum = "8dcd332a5496c026f1e14b7f3d2b7bd98e509660c04239c58b0ba38a12daded4" dependencies = [ "dissimilar", "glob", "serde", "serde_derive", "serde_json", + "target-triple", "termcolor", "toml", ] @@ -3305,12 +3315,9 @@ dependencies = [ [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-ident" @@ -3456,9 +3463,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -3467,9 +3474,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", @@ -3482,9 +3489,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3492,9 +3499,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", @@ -3505,9 +3512,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "winapi" @@ -3828,9 +3835,9 @@ dependencies = [ [[package]] name = "winter-maybe-async" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77eafc7944188b941c90759b938b8377247ee6e440952a0a7c4dbde7edc4ecbb" +checksum = "be43529f43f70306437d2c2c9f9e2b3a4d39b42e86702d8d7577f2357ea32fa6" dependencies = [ "quote", "syn", diff --git a/Cargo.toml b/Cargo.toml index 656515f39..dfc3349c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ resolver = "2" [workspace.package] edition = "2021" -rust-version = "1.80" +rust-version = "1.82" version = "0.6.0" license = "MIT" authors = ["Miden contributors"] @@ -25,8 +25,8 @@ exclude = [".github/"] readme = "README.md" [workspace.dependencies] -miden-air = { version = "0.10", default-features = false } -miden-lib = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next"} +miden-air = { git = "https://github.com/0xPolygonMiden/miden-vm.git", branch = "next" } +miden-lib = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } miden-node-block-producer = { path = "crates/block-producer", version = "0.6" } miden-node-faucet = { path = "bin/faucet", version = "0.6" } miden-node-proto = { path = "crates/proto", version = "0.6" } @@ -36,8 +36,8 @@ miden-node-store = { path = "crates/store", version = "0.6" } miden-node-test-macro = { path = "crates/test-macro" } miden-node-utils = { path = "crates/utils", version = "0.6" } miden-objects = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } -miden-processor = { version = "0.10" } -miden-stdlib = { version = "0.10", default-features = false } +miden-processor = { git = "https://github.com/0xPolygonMiden/miden-vm.git", branch = "next" } +miden-stdlib = { git = "https://github.com/0xPolygonMiden/miden-vm.git", branch = "next", default-features = false } miden-tx = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } prost = { version = "0.13" } thiserror = { version = "1.0" } diff --git a/Makefile b/Makefile index afa1a2da9..b10ad72a9 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ BUILD_PROTO=BUILD_PROTO=1 .PHONY: clippy clippy: ## Runs Clippy with configs - cargo clippy --locked --workspace --all-targets --all-features -- -D warnings + cargo clippy --locked --workspace --all-targets --all-features -- -D warnings --allow clippy::arc_with_non_send_sync .PHONY: fix diff --git a/bin/faucet/src/client.rs b/bin/faucet/src/client.rs index d02f4a138..ae5d55a90 100644 --- a/bin/faucet/src/client.rs +++ b/bin/faucet/src/client.rs @@ -1,4 +1,7 @@ -use std::{cell::RefCell, rc::Rc, time::Duration}; +use std::{ + sync::{Arc, Mutex}, + time::Duration, +}; use miden_lib::{ accounts::faucets::create_basic_fungible_faucet, notes::create_p2id_note, @@ -45,8 +48,8 @@ pub const DISTRIBUTE_FUNGIBLE_ASSET_SCRIPT: &str = /// for the faucet. pub struct FaucetClient { rpc_api: ApiClient, - executor: TransactionExecutor>, - data_store: FaucetDataStore, + executor: TransactionExecutor, + data_store: Arc, id: AccountId, rng: RpoRandomCoin, } @@ -60,20 +63,19 @@ impl FaucetClient { initialize_faucet_client(config.clone()).await?; let (faucet_account, account_seed, secret) = build_account(config.clone())?; - let faucet_account = Rc::new(RefCell::new(faucet_account)); - let id = faucet_account.borrow().id(); + let id = faucet_account.id(); - let data_store = FaucetDataStore::new( - faucet_account.clone(), + let data_store = Arc::new(FaucetDataStore::new( + faucet_account, account_seed, root_block_header, root_chain_mmr, - ); - let authenticator = BasicAuthenticator::::new(&[( + )); + let authenticator = Arc::new(BasicAuthenticator::::new(&[( secret.public_key().into(), AuthSecretKey::RpoFalcon512(secret), - )]); - let executor = TransactionExecutor::new(data_store.clone(), Some(Rc::new(authenticator))); + )])); + let executor = TransactionExecutor::new(data_store.clone(), Some(authenticator)); let mut rng = thread_rng(); let coin_seed: [u64; 4] = rng.gen(); @@ -135,9 +137,10 @@ impl FaucetClient { let request = { let transaction_prover = LocalTransactionProver::new(ProvingOptions::default()); - let proven_transaction = transaction_prover.prove(executed_tx).map_err(|err| { - ProcessError::InternalServerError(format!("Failed to prove transaction: {err}")) - })?; + let proven_transaction = + transaction_prover.prove(executed_tx.into()).map_err(|err| { + ProcessError::InternalServerError(format!("Failed to prove transaction: {err}")) + })?; SubmitProvenTransactionRequest { transaction: proven_transaction.to_bytes(), @@ -162,9 +165,8 @@ impl FaucetClient { } } -#[derive(Clone)] pub struct FaucetDataStore { - faucet_account: Rc>, + faucet_account: Mutex, seed: Word, block_header: BlockHeader, chain_mmr: ChainMmr, @@ -175,13 +177,13 @@ pub struct FaucetDataStore { impl FaucetDataStore { pub fn new( - faucet_account: Rc>, + faucet_account: Account, seed: Word, root_block_header: BlockHeader, root_chain_mmr: ChainMmr, ) -> Self { Self { - faucet_account, + faucet_account: Mutex::new(faucet_account), seed, block_header: root_block_header, chain_mmr: root_chain_mmr, @@ -189,9 +191,10 @@ impl FaucetDataStore { } /// Updates the stored faucet account with the provided delta. - fn update_faucet_account(&mut self, delta: &AccountDelta) -> Result<(), ProcessError> { + fn update_faucet_account(&self, delta: &AccountDelta) -> Result<(), ProcessError> { self.faucet_account - .borrow_mut() + .lock() + .expect("Poisoned lock") .apply_delta(delta) .map_err(|err| ProcessError::InternalServerError(err.to_string())) } @@ -204,7 +207,7 @@ impl DataStore for FaucetDataStore { _block_ref: u32, _notes: &[NoteId], ) -> Result { - let account = self.faucet_account.borrow(); + let account = self.faucet_account.lock().expect("Poisoned lock"); if account_id != account.id() { return Err(DataStoreError::AccountNotFound(account_id)); } diff --git a/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm b/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm index 48139646b..63e277047 100644 --- a/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm +++ b/crates/block-producer/src/block_builder/prover/asm/block_kernel.masm @@ -6,6 +6,7 @@ use.std::collections::smt use.std::collections::mmr +use.std::sys const.ACCOUNT_TREE_DEPTH=64 const.BLOCK_NOTES_BATCH_TREE_DEPTH=6 @@ -237,4 +238,7 @@ begin # Load output on stack padw mem_loadw.2 padw mem_loadw.1 padw mem_loadw.0 # => [ACCOUNT_ROOT, NOTE_ROOT, NULLIFIER_ROOT, CHAIN_MMR_ROOT] + + # truncate the stack + exec.sys::truncate_stack end diff --git a/crates/block-producer/src/block_builder/prover/mod.rs b/crates/block-producer/src/block_builder/prover/mod.rs index 17f7d6424..cede229eb 100644 --- a/crates/block-producer/src/block_builder/prover/mod.rs +++ b/crates/block-producer/src/block_builder/prover/mod.rs @@ -88,7 +88,7 @@ impl BlockProver { let advice_provider = MemAdviceProvider::from(advice_inputs); let mut host = DefaultHost::new(advice_provider); - host.load_mast_forest(StdLibrary::default().into()); + host.load_mast_forest(StdLibrary::default().mast_forest().clone()); host }; diff --git a/crates/block-producer/src/block_builder/prover/tests.rs b/crates/block-producer/src/block_builder/prover/tests.rs index 09f98d787..3d776ffc6 100644 --- a/crates/block-producer/src/block_builder/prover/tests.rs +++ b/crates/block-producer/src/block_builder/prover/tests.rs @@ -843,7 +843,7 @@ async fn test_compute_chain_mmr_root_mmr_17_peaks() { mmr.add(Digest::default()); } - assert_eq!(mmr.peaks(mmr.forest()).unwrap().peaks().len(), 17); + assert_eq!(mmr.peaks().peaks().len(), 17); mmr }; diff --git a/crates/block-producer/src/test_utils/block.rs b/crates/block-producer/src/test_utils/block.rs index a8678eea6..71d15f7e6 100644 --- a/crates/block-producer/src/test_utils/block.rs +++ b/crates/block-producer/src/test_utils/block.rs @@ -49,7 +49,7 @@ pub async fn build_expected_block_header( store_chain_mmr.add(last_block_header.hash()); - store_chain_mmr.peaks(store_chain_mmr.forest()).unwrap().hash_peaks() + store_chain_mmr.peaks().hash_peaks() }; let note_created_smt = note_created_smt_from_note_batches(block_output_notes(batches.iter())); @@ -157,7 +157,7 @@ impl MockBlockBuilder { 0, self.last_block_header.hash(), self.last_block_header.block_num() + 1, - self.store_chain_mmr.peaks(self.store_chain_mmr.forest()).unwrap().hash_peaks(), + self.store_chain_mmr.peaks().hash_peaks(), self.store_accounts.root(), Digest::default(), note_created_smt_from_note_batches(created_notes.iter()).root(), diff --git a/crates/block-producer/src/test_utils/store.rs b/crates/block-producer/src/test_utils/store.rs index bf1e89328..f1fb7fef4 100644 --- a/crates/block-producer/src/test_utils/store.rs +++ b/crates/block-producer/src/test_utils/store.rs @@ -121,7 +121,7 @@ impl MockStoreSuccessBuilder { 0, Digest::default(), block_num, - chain_mmr.peaks(chain_mmr.forest()).unwrap().hash_peaks(), + chain_mmr.peaks().hash_peaks(), accounts_smt.root(), nullifiers_smt.root(), note_root, @@ -301,7 +301,7 @@ impl Store for MockStoreSuccess { let chain_peaks = { let locked_chain_mmr = self.chain_mmr.read().await; - locked_chain_mmr.peaks(locked_chain_mmr.forest()).unwrap() + locked_chain_mmr.peaks() }; let accounts = { @@ -329,15 +329,13 @@ impl Store for MockStoreSuccess { *locked_headers.iter().max_by_key(|(block_num, _)| *block_num).unwrap().1; let locked_chain_mmr = self.chain_mmr.read().await; - let mmr_forest = locked_chain_mmr.forest(); let chain_length = latest_header.block_num(); let block_proofs = note_proofs .values() .map(|note_proof| { let block_num = note_proof.location().block_num(); let block_header = *locked_headers.get(&block_num).unwrap(); - let mmr_path = - locked_chain_mmr.open(block_num as usize, mmr_forest).unwrap().merkle_path; + let mmr_path = locked_chain_mmr.open(block_num as usize).unwrap().merkle_path; BlockInclusionProof { block_header, mmr_path, chain_length } }) @@ -376,7 +374,7 @@ impl Store for MockStoreSuccess { let block_num = note_proof.location().block_num(); let block_header = *locked_headers.get(&block_num).unwrap(); let mmr_path = locked_chain_mmr - .open(block_num as usize, latest_header.block_num() as usize) + .open_at(block_num as usize, latest_header.block_num() as usize) .unwrap() .merkle_path; diff --git a/crates/store/src/state.rs b/crates/store/src/state.rs index 31b8607c2..169684777 100644 --- a/crates/store/src/state.rs +++ b/crates/store/src/state.rs @@ -232,12 +232,7 @@ impl State { let mut chain_mmr = inner.chain_mmr.clone(); // new_block.chain_root must be equal to the chain MMR root prior to the update - let peaks = chain_mmr.peaks(chain_mmr.forest()).map_err(|error| { - ApplyBlockError::FailedToGetMmrPeaksForForest { - forest: chain_mmr.forest(), - error, - } - })?; + let peaks = chain_mmr.peaks(); if peaks.hash_peaks() != header.chain_root() { return Err(ApplyBlockError::NewBlockInvalidChainRoot); } @@ -372,8 +367,7 @@ impl State { if let Some(header) = block_header { let mmr_proof = if include_mmr_proof { let inner = self.inner.read().await; - let mmr_proof = - inner.chain_mmr.open(header.block_num() as usize, inner.chain_mmr.forest())?; + let mmr_proof = inner.chain_mmr.open(header.block_num() as usize)?; Some(mmr_proof) } else { None @@ -444,7 +438,7 @@ impl State { let paths = blocks .iter() .map(|&block_num| { - let proof = state.chain_mmr.open(block_num as usize, chain_length)?.merkle_path; + let proof = state.chain_mmr.open(block_num as usize)?.merkle_path; Ok::<_, MmrError>((block_num, proof)) }) @@ -548,9 +542,7 @@ impl State { let note_sync = self.db.get_note_sync(block_num, note_tags).await?; - let mmr_proof = inner - .chain_mmr - .open(note_sync.block_header.block_num() as usize, inner.chain_mmr.forest())?; + let mmr_proof = inner.chain_mmr.open(note_sync.block_header.block_num() as usize)?; Ok((note_sync, mmr_proof)) } @@ -580,12 +572,13 @@ impl State { // using current block number gets us the peaks of the chain MMR as of one block ago; // this is done so that latest.chain_root matches the returned peaks - let chain_peaks = inner.chain_mmr.peaks(latest.block_num() as usize).map_err(|error| { - GetBlockInputsError::FailedToGetMmrPeaksForForest { - forest: latest.block_num() as usize, - error, - } - })?; + let chain_peaks = + inner.chain_mmr.peaks_at(latest.block_num() as usize).map_err(|error| { + GetBlockInputsError::FailedToGetMmrPeaksForForest { + forest: latest.block_num() as usize, + error, + } + })?; let account_states = account_ids .iter() .cloned() diff --git a/rust-toolchain.toml b/rust-toolchain.toml index b12899f14..6ad542bbc 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.80" +channel = "1.82" components = ["rustfmt", "rust-src", "clippy"] profile = "minimal" From 17a5ca1f47c8cd70f145b2f5ef075bc719bd9804 Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Wed, 30 Oct 2024 12:53:57 +0500 Subject: [PATCH 29/37] feat(node): avoid cloning in-memory data structures on `apply_block` (#532) * feat: avoid cloning in-memory data structures on `apply_block` * docs: update `CHANGELOG.md` * chore: update `miden-crypto` dependency Co-authored-by: Mirko <48352201+Mirko-von-Leipzig@users.noreply.github.com> * Update CHANGELOG.md Co-authored-by: Mirko <48352201+Mirko-von-Leipzig@users.noreply.github.com> * chore: update `Cargo.lock` * refactor: address review comments * fix: prevent inconsistent in-memory and DB states * refactor: address review comments --------- Co-authored-by: Mirko <48352201+Mirko-von-Leipzig@users.noreply.github.com> --- CHANGELOG.md | 1 + crates/store/src/nullifier_tree.rs | 45 ++++---- crates/store/src/state.rs | 161 +++++++++++++++-------------- 3 files changed, 110 insertions(+), 97 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33f4807f2..1b1d07d9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Changed the `BlockWitness` to pass the inputs to the VM using only advice provider (#516). - [BREAKING] Improved store API errors (return "not found" instead of "internal error" status if requested account(s) not found) (#518). - [BREAKING] Migrated to v0.11 version of Miden VM (#528). +- Reduce cloning in the store's `apply_block` (#532). ## 0.5.1 (2024-09-12) diff --git a/crates/store/src/nullifier_tree.rs b/crates/store/src/nullifier_tree.rs index b5f3c542d..04f868015 100644 --- a/crates/store/src/nullifier_tree.rs +++ b/crates/store/src/nullifier_tree.rs @@ -1,7 +1,7 @@ use miden_objects::{ crypto::{ hash::rpo::RpoDigest, - merkle::{Smt, SmtProof}, + merkle::{MutationSet, Smt, SmtProof, SMT_DEPTH}, }, notes::Nullifier, Felt, FieldElement, Word, @@ -27,7 +27,7 @@ impl NullifierTree { Ok(Self(inner)) } - /// Get SMT root. + /// Returns the root of the nullifier SMT. pub fn root(&self) -> RpoDigest { self.0.root() } @@ -37,26 +37,6 @@ impl NullifierTree { self.0.open(&nullifier.inner()) } - /// Inserts block number in which nullifier was consumed. - pub fn insert( - &mut self, - nullifier: &Nullifier, - block_num: BlockNumber, - ) -> Result<(), NullifierTreeError> { - let key = nullifier.inner(); - let prev_value = self.0.get_value(&key); - if prev_value != Smt::EMPTY_VALUE { - return Err(NullifierTreeError::NullifierAlreadyExists { - nullifier: *nullifier, - block_num: Self::leaf_value_to_block_num(prev_value), - }); - } - - self.0.insert(key, Self::block_num_to_leaf_value(block_num)); - - Ok(()) - } - /// Returns block number stored for the given nullifier or `None` if the nullifier wasn't /// consumed. pub fn get_block_num(&self, nullifier: &Nullifier) -> Option { @@ -68,6 +48,27 @@ impl NullifierTree { Some(Self::leaf_value_to_block_num(value)) } + /// Computes mutations for the nullifier SMT. + pub fn compute_mutations( + &self, + kv_pairs: impl IntoIterator, + ) -> MutationSet { + self.0.compute_mutations(kv_pairs.into_iter().map(|(nullifier, block_num)| { + (nullifier.inner(), Self::block_num_to_leaf_value(block_num)) + })) + } + + /// Applies mutations to the nullifier SMT. + pub fn apply_mutations( + &mut self, + mutations: MutationSet, + ) -> Result<(), NullifierTreeError> { + self.0.apply_mutations(mutations).map_err(Into::into) + } + + // HELPER FUNCTIONS + // -------------------------------------------------------------------------------------------- + /// Returns the nullifier's leaf value in the SMT by its block number. fn block_num_to_leaf_value(block: BlockNumber) -> Word { [Felt::from(block), Felt::ZERO, Felt::ZERO, Felt::ZERO] diff --git a/crates/store/src/state.rs b/crates/store/src/state.rs index 169684777..3ff4c4197 100644 --- a/crates/store/src/state.rs +++ b/crates/store/src/state.rs @@ -203,15 +203,21 @@ impl State { // block store. Thus, such block should be considered as block candidates, but not // finalized blocks. So we should check for the latest block when getting block from // the store. - let store = self.block_store.clone(); + let store = Arc::clone(&self.block_store); let block_save_task = tokio::spawn(async move { store.save_block(block_num, &block_data).await }); - // scope to read in-memory data, validate the request, and compute intermediary values - let (account_tree, chain_mmr, nullifier_tree, notes) = { + // scope to read in-memory data, compute mutations required for updating account + // and nullifier trees, and validate the request + let ( + nullifier_tree_old_root, + nullifier_tree_update, + account_tree_old_root, + account_tree_update, + ) = { let inner = self.inner.read().await; - let span = info_span!(target: COMPONENT, "update_in_memory_structs").entered(); + let _span = info_span!(target: COMPONENT, "update_in_memory_structs").entered(); // nullifiers can be produced only once let duplicate_nullifiers: Vec<_> = block @@ -224,83 +230,72 @@ impl State { return Err(ApplyBlockError::DuplicatedNullifiers(duplicate_nullifiers)); } - // update the in-memory data structures and compute the new block header. Important, the - // structures are not yet committed + // compute updates for the in-memory data structures - // update chain MMR - let chain_mmr = { - let mut chain_mmr = inner.chain_mmr.clone(); - - // new_block.chain_root must be equal to the chain MMR root prior to the update - let peaks = chain_mmr.peaks(); - if peaks.hash_peaks() != header.chain_root() { - return Err(ApplyBlockError::NewBlockInvalidChainRoot); - } - - chain_mmr.add(block_hash); - chain_mmr - }; - - // update nullifier tree - let nullifier_tree = { - let mut nullifier_tree = inner.nullifier_tree.clone(); - for nullifier in block.nullifiers() { - nullifier_tree - .insert(nullifier, block_num) - .map_err(ApplyBlockError::FailedToUpdateNullifierTree)?; - } + // new_block.chain_root must be equal to the chain MMR root prior to the update + let peaks = inner.chain_mmr.peaks(); + if peaks.hash_peaks() != header.chain_root() { + return Err(ApplyBlockError::NewBlockInvalidChainRoot); + } - if nullifier_tree.root() != header.nullifier_root() { - return Err(ApplyBlockError::NewBlockInvalidNullifierRoot); - } - nullifier_tree - }; + // compute update for nullifier tree + let nullifier_tree_update = inner.nullifier_tree.compute_mutations( + block.nullifiers().iter().map(|nullifier| (*nullifier, block_num)), + ); - // update account tree - let mut account_tree = inner.account_tree.clone(); - for update in block.updated_accounts() { - account_tree.insert( - LeafIndex::new_max_depth(update.account_id().into()), - update.new_state_hash().into(), - ); + if nullifier_tree_update.root() != header.nullifier_root() { + return Err(ApplyBlockError::NewBlockInvalidNullifierRoot); } - if account_tree.root() != header.account_root() { + // compute update for account tree + let account_tree_update = inner.account_tree.compute_mutations( + block.updated_accounts().iter().map(|update| { + ( + LeafIndex::new_max_depth(update.account_id().into()), + update.new_state_hash().into(), + ) + }), + ); + + if account_tree_update.root() != header.account_root() { return Err(ApplyBlockError::NewBlockInvalidAccountRoot); } - // build note tree - let note_tree = block.build_note_tree(); - if note_tree.root() != header.note_root() { - return Err(ApplyBlockError::NewBlockInvalidNoteRoot); - } + ( + inner.nullifier_tree.root(), + nullifier_tree_update, + inner.account_tree.root(), + account_tree_update, + ) + }; - drop(span); - - let notes = block - .notes() - .map(|(note_index, note)| { - let details = match note { - OutputNote::Full(note) => Some(note.to_bytes()), - OutputNote::Header(_) => None, - note => return Err(ApplyBlockError::InvalidOutputNoteType(note.clone())), - }; - - let merkle_path = note_tree.get_note_path(note_index); - - Ok(NoteRecord { - block_num, - note_index, - note_id: note.id().into(), - metadata: *note.metadata(), - details, - merkle_path, - }) - }) - .collect::, ApplyBlockError>>()?; + // build note tree + let note_tree = block.build_note_tree(); + if note_tree.root() != header.note_root() { + return Err(ApplyBlockError::NewBlockInvalidNoteRoot); + } - (account_tree, chain_mmr, nullifier_tree, notes) - }; + let notes = block + .notes() + .map(|(note_index, note)| { + let details = match note { + OutputNote::Full(note) => Some(note.to_bytes()), + OutputNote::Header(_) => None, + note => return Err(ApplyBlockError::InvalidOutputNoteType(note.clone())), + }; + + let merkle_path = note_tree.get_note_path(note_index); + + Ok(NoteRecord { + block_num, + note_index, + note_id: note.id().into(), + metadata: *note.metadata(), + details, + merkle_path, + }) + }) + .collect::, ApplyBlockError>>()?; // Signals the transaction is ready to be committed, and the write lock can be acquired let (allow_acquire, acquired_allowed) = oneshot::channel::<()>(); @@ -311,7 +306,7 @@ impl State { // overlapping. Namely, the DB transaction only proceeds after this task acquires the // in-memory write lock. This requires the DB update to run concurrently, so a new task is // spawned. - let db = self.db.clone(); + let db = Arc::clone(&self.db); let db_update_task = tokio::spawn( async move { db.apply_block(allow_acquire, acquire_done, block, notes).await }, @@ -332,6 +327,16 @@ impl State { // successfully. let mut inner = self.inner.write().await; + // We need to check that neither the nullifier tree nor the account tree have changed + // while we were waiting for the DB preparation task to complete. If either of them + // did change, we do not proceed with in-memory and database updates, since it may + // lead to an inconsistent state. + if inner.nullifier_tree.root() != nullifier_tree_old_root + || inner.account_tree.root() != account_tree_old_root + { + return Err(ApplyBlockError::ConcurrentWrite); + } + // Notify the DB update task that the write lock has been acquired, so it can commit // the DB transaction let _ = inform_acquire_done.send(()); @@ -343,9 +348,15 @@ impl State { db_update_task.await??; // Update the in-memory data structures after successful commit of the DB transaction - inner.chain_mmr = chain_mmr; - inner.nullifier_tree = nullifier_tree; - inner.account_tree = account_tree; + inner + .nullifier_tree + .apply_mutations(nullifier_tree_update) + .expect("Unreachable: old nullifier tree root must be checked before this step"); + inner + .account_tree + .apply_mutations(account_tree_update) + .expect("Unreachable: old account tree root must be checked before this step"); + inner.chain_mmr.add(block_hash); } info!(%block_hash, block_num, COMPONENT, "apply_block successful"); From f5416109fce40a372128fe347de7a14801dad190 Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Wed, 30 Oct 2024 23:29:39 +0500 Subject: [PATCH 30/37] fix(faucet): resume after restart (#517) * feat: improve node errors * docs: update `CHANGELOG.md` * feat: save/restore faucet state and keypair to/from files * feat: make faucet account public, request account state on submission error * feat: introduce `ClientError` * fix: update config * fix: save new faucet state to in-memory store after getting from the server * fix: remove `macros` feature from axum dependency * docs: update `CHANGELOG.md` * docs: add comment for `seed` field Co-authored-by: Mirko <48352201+Mirko-von-Leipzig@users.noreply.github.com> * fix: log message Co-authored-by: Mirko <48352201+Mirko-von-Leipzig@users.noreply.github.com> * refactor: address review comments * refactor: initial changes * refactor: impl Send and Sync for FaucetDataStore * chore: update changelog * refactor: remove unnecessary async, add warning ignore to makefile * refactor: update genesis generation, read faucet account from `faucet.mac`, request faucet state on initialization * feat: faucet account creation * fix: handling of account not found error * refactor: use Arc and Mutex * chore: removed unneeded cast * fix: lint * docs: update CHANGELOG.md * fix: compilation errors * docs: add `TODO` for incorrect and unsafe `Send` implementation * refactor: small refactoring * refactor: address review comments * docs: update `README.md` for faucet * docs: improve instructions and clarifications in faucet's `README.md` --------- Co-authored-by: Mirko <48352201+Mirko-von-Leipzig@users.noreply.github.com> Co-authored-by: Andrey Co-authored-by: Bobbin Threadbare --- .github/workflows/deploy_package.yml | 2 +- CHANGELOG.md | 1 + Cargo.lock | 3 + Cargo.toml | 1 + bin/faucet/Cargo.toml | 5 +- bin/faucet/README.md | 26 ++- bin/faucet/src/client.rs | 286 +++++++++++------------- bin/faucet/src/config.rs | 31 +-- bin/faucet/src/errors.rs | 41 ++-- bin/faucet/src/handlers.rs | 31 ++- bin/faucet/src/main.rs | 116 +++++++--- bin/faucet/src/state.rs | 9 +- bin/faucet/src/store.rs | 73 ++++++ bin/node/Cargo.toml | 1 + bin/node/src/commands/genesis/inputs.rs | 6 - bin/node/src/commands/genesis/mod.rs | 85 +++---- bin/node/src/main.rs | 7 +- config/genesis.toml | 2 - config/miden-faucet.toml | 6 +- crates/utils/Cargo.toml | 1 + crates/utils/src/crypto.rs | 13 ++ crates/utils/src/lib.rs | 1 + 22 files changed, 437 insertions(+), 310 deletions(-) create mode 100644 bin/faucet/src/store.rs create mode 100644 crates/utils/src/crypto.rs diff --git a/.github/workflows/deploy_package.yml b/.github/workflows/deploy_package.yml index 53530896b..d2de0c2ba 100644 --- a/.github/workflows/deploy_package.yml +++ b/.github/workflows/deploy_package.yml @@ -117,7 +117,7 @@ jobs: sudo chown -R miden /opt/miden; \ sudo /usr/bin/miden-node init -c /etc/miden/miden-node.toml -g /opt/miden/miden-node/genesis.toml; \ sudo /usr/bin/miden-node make-genesis -i /opt/miden/miden-node/genesis.toml -o /opt/miden/miden-node/genesis.dat --force; \ - sudo /usr/bin/miden-faucet init -c /opt/miden/miden-faucet/miden-faucet.toml + sudo /usr/bin/miden-faucet init -c /opt/miden/miden-faucet/miden-faucet.toml -f /opt/miden/miden-node/accounts/faucet.mac - name: Start miden node service uses: ./.github/actions/ssm_execute diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b1d07d9b..ed2ecf837 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - [BREAKING] Improved store API errors (return "not found" instead of "internal error" status if requested account(s) not found) (#518). - [BREAKING] Migrated to v0.11 version of Miden VM (#528). - Reduce cloning in the store's `apply_block` (#532). +- [BREAKING] Changed faucet storage type in the genesis to public. Using faucet from the genesis for faucet web app. Added support for faucet restarting without blockchain restarting (#517). ## 0.5.1 (2024-09-12) diff --git a/Cargo.lock b/Cargo.lock index ee1f4a6e2..67049c24b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1469,6 +1469,7 @@ dependencies = [ name = "miden-faucet" version = "0.6.0" dependencies = [ + "anyhow", "axum", "clap", "figment", @@ -1568,6 +1569,7 @@ dependencies = [ "miden-node-store", "miden-node-utils", "miden-objects", + "rand", "rand_chacha", "serde", "tokio", @@ -1686,6 +1688,7 @@ dependencies = [ "figment", "itertools 0.12.1", "miden-objects", + "rand", "serde", "thiserror", "tonic", diff --git a/Cargo.toml b/Cargo.toml index dfc3349c8..9e0d53b99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ miden-processor = { git = "https://github.com/0xPolygonMiden/miden-vm.git", bran miden-stdlib = { git = "https://github.com/0xPolygonMiden/miden-vm.git", branch = "next", default-features = false } miden-tx = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } prost = { version = "0.13" } +rand = { version = "0.8" } thiserror = { version = "1.0" } tokio = { version = "1.40", features = ["rt-multi-thread"] } tokio-stream = { version = "0.1" } diff --git a/bin/faucet/Cargo.toml b/bin/faucet/Cargo.toml index fc03a81ad..7d299e3e2 100644 --- a/bin/faucet/Cargo.toml +++ b/bin/faucet/Cargo.toml @@ -17,6 +17,7 @@ repository.workspace = true testing = ["miden-objects/testing", "miden-lib/testing"] [dependencies] +anyhow = "1.0" axum = { version = "0.7", features = ["tokio"] } clap = { version = "4.5", features = ["derive", "string"] } figment = { version = "0.10", features = ["toml", "env"] } @@ -28,12 +29,12 @@ miden-node-utils = { workspace = true } miden-objects = { workspace = true , features = ["concurrent"] } miden-tx = { workspace = true, features = ["concurrent"] } mime = "0.3" -rand = { version = "0.8" } +rand = { workspace = true } rand_chacha = "0.3" serde = { version = "1.0", features = ["derive"] } static-files = "0.2" thiserror = { workspace = true } -tokio = { workspace = true } +tokio = { workspace = true, features = ["fs"] } toml = { version = "0.8" } tonic = { workspace = true } tower = "0.5" diff --git a/bin/faucet/README.md b/bin/faucet/README.md index 2d9fe8edb..2d7b15e55 100644 --- a/bin/faucet/README.md +++ b/bin/faucet/README.md @@ -2,8 +2,12 @@ This crate contains a binary for running a Miden rollup faucet. -## Running the faucet -1. Run a local node, for example using the docker image. From the "miden-node" repo root run the following commands: +## Running the faucet in testing mode + +> [!TIP] +> Miden account generation uses a proof-of-work puzzle to prevent DoS attacks. These puzzles can be quite expensive, especially for test purposes. You can lower the difficulty of the puzzle by appending `--features testing` to the `cargo install ..` invocation. + +1. Run a local node with the "testing" feature, for example using the docker image. From the "miden-node" repo root run the following commands: ```bash make docker-build-node make docker-run-node @@ -14,12 +18,24 @@ make docker-run-node make install-faucet-testing ``` -3. Create the default faucet configuration file: +3. [Optional] Create faucet account (skip this step if you want to use an account from the genesis). This will generate authentication keypair and generate and write public faucet account data with its keypair into the file specified in `output-path`: + +```bash +miden-faucet create-faucet-account \ + --output-path \ + --token-symbol POL \ + --decimals 9 \ + --max-supply 1000000000 +``` +> [!TIP] +> This account will not be created on chain yet, creation on chain will happen on the first minting transaction. + +4. Create the default faucet configuration file. Specify the path to the faucet account file created on the previous step in the `-f` flag (if you want to use an account from the genesis, specify the path to the `faucet.mac` file generated by the [make-genesis](../../README.md#setup) command of the Miden node): ```bash -miden-faucet init +miden-faucet init -f ``` -4. Start the faucet server: +5. Start the faucet server: ```bash miden-faucet start ``` diff --git a/bin/faucet/src/client.rs b/bin/faucet/src/client.rs index ae5d55a90..ce76a37ed 100644 --- a/bin/faucet/src/client.rs +++ b/bin/faucet/src/client.rs @@ -1,41 +1,39 @@ -use std::{ - sync::{Arc, Mutex}, - time::Duration, -}; +use std::{sync::Arc, time::Duration}; -use miden_lib::{ - accounts::faucets::create_basic_fungible_faucet, notes::create_p2id_note, - transaction::TransactionKernel, AuthScheme, -}; +use anyhow::Context; +use miden_lib::{notes::create_p2id_note, transaction::TransactionKernel}; use miden_node_proto::generated::{ - requests::{GetBlockHeaderByNumberRequest, SubmitProvenTransactionRequest}, + requests::{ + GetAccountDetailsRequest, GetBlockHeaderByNumberRequest, SubmitProvenTransactionRequest, + }, rpc::api_client::ApiClient, }; use miden_objects::{ - accounts::{Account, AccountDelta, AccountId, AccountStorageMode, AuthSecretKey}, - assets::{FungibleAsset, TokenSymbol}, + accounts::{Account, AccountData, AccountId, AuthSecretKey}, + assets::FungibleAsset, crypto::{ - dsa::rpo_falcon512::SecretKey, merkle::{MmrPeaks, PartialMmr}, rand::RpoRandomCoin, }, - notes::{Note, NoteId, NoteType}, - transaction::{ChainMmr, ExecutedTransaction, InputNotes, TransactionArgs, TransactionScript}, + notes::{Note, NoteType}, + transaction::{ChainMmr, ExecutedTransaction, TransactionArgs, TransactionScript}, + utils::Deserializable, vm::AdviceMap, - BlockHeader, Felt, Word, + BlockHeader, Felt, }; use miden_tx::{ - auth::BasicAuthenticator, utils::Serializable, DataStore, DataStoreError, - LocalTransactionProver, ProvingOptions, TransactionExecutor, TransactionInputs, - TransactionProver, + auth::BasicAuthenticator, utils::Serializable, LocalTransactionProver, ProvingOptions, + TransactionExecutor, TransactionProver, }; -use rand::{rngs::StdRng, thread_rng, Rng}; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; +use rand::{random, rngs::StdRng}; use tonic::transport::Channel; +use tracing::info; use crate::{ config::FaucetConfig, - errors::{InitError, ProcessError}, + errors::{ClientError, ImplError}, + store::FaucetDataStore, + COMPONENT, }; pub const DISTRIBUTE_FUNGIBLE_ASSET_SCRIPT: &str = @@ -54,31 +52,68 @@ pub struct FaucetClient { rng: RpoRandomCoin, } +// TODO: Remove this once https://github.com/0xPolygonMiden/miden-base/issues/909 is resolved unsafe impl Send for FaucetClient {} -unsafe impl Sync for FaucetClient {} impl FaucetClient { - pub async fn new(config: FaucetConfig) -> Result { - let (rpc_api, root_block_header, root_chain_mmr) = - initialize_faucet_client(config.clone()).await?; - - let (faucet_account, account_seed, secret) = build_account(config.clone())?; - let id = faucet_account.id(); + /// Fetches the latest faucet account state from the node and creates a new faucet client. + /// + /// # Note + /// If the faucet account is not found on chain, it will be created on submission of the first + /// minting transaction. + pub async fn new(config: &FaucetConfig) -> Result { + let (mut rpc_api, root_block_header, root_chain_mmr) = + initialize_faucet_client(config).await?; + + let faucet_account_data = AccountData::read(&config.faucet_account_path) + .context("Failed to load faucet account from file")?; + + let id = faucet_account_data.account.id(); + + info!(target: COMPONENT, "Requesting account state from the node..."); + let faucet_account = match request_account_state(&mut rpc_api, id).await { + Ok(account) => { + info!( + target: COMPONENT, + hash = %account.hash(), + nonce = %account.nonce(), + "Received faucet account state from the node", + ); + + account + }, + + Err(err) => match err { + ClientError::RequestError(status) if status.code() == tonic::Code::NotFound => { + info!(target: COMPONENT, "Faucet account not found in the node"); + + faucet_account_data.account + }, + _ => { + return Err(err); + }, + }, + }; let data_store = Arc::new(FaucetDataStore::new( faucet_account, - account_seed, + faucet_account_data.account_seed, root_block_header, root_chain_mmr, )); - let authenticator = Arc::new(BasicAuthenticator::::new(&[( - secret.public_key().into(), - AuthSecretKey::RpoFalcon512(secret), - )])); - let executor = TransactionExecutor::new(data_store.clone(), Some(authenticator)); - - let mut rng = thread_rng(); - let coin_seed: [u64; 4] = rng.gen(); + + let public_key = match &faucet_account_data.auth_secret_key { + AuthSecretKey::RpoFalcon512(secret) => secret.public_key(), + }; + + let authenticator = BasicAuthenticator::::new(&[( + public_key.into(), + faucet_account_data.auth_secret_key, + )]); + + let executor = TransactionExecutor::new(data_store.clone(), Some(Arc::new(authenticator))); + + let coin_seed: [u64; 4] = random(); let rng = RpoRandomCoin::new(coin_seed.map(Felt::new)); Ok(Self { data_store, rpc_api, executor, id, rng }) @@ -92,9 +127,9 @@ impl FaucetClient { target_account_id: AccountId, is_private_note: bool, asset_amount: u64, - ) -> Result<(ExecutedTransaction, Note), ProcessError> { - let asset = FungibleAsset::new(self.id, asset_amount) - .map_err(|err| ProcessError::InternalServerError(err.to_string()))?; + ) -> Result<(ExecutedTransaction, Note), ClientError> { + let asset = + FungibleAsset::new(self.id, asset_amount).context("Failed to create fungible asset")?; let note_type = if is_private_note { NoteType::Private @@ -110,16 +145,14 @@ impl FaucetClient { Default::default(), &mut self.rng, ) - .map_err(|err| ProcessError::InternalServerError(err.to_string()))?; + .context("Failed to create P2ID note")?; let transaction_args = build_transaction_arguments(&output_note, note_type, asset)?; let executed_tx = self .executor .execute_transaction(self.id, 0, &[], transaction_args) - .map_err(|err| { - ProcessError::InternalServerError(format!("Failed to execute transaction: {err}")) - })?; + .context("Failed to execute transaction")?; Ok((executed_tx, output_note)) } @@ -128,19 +161,16 @@ impl FaucetClient { pub async fn prove_and_submit_transaction( &mut self, executed_tx: ExecutedTransaction, - ) -> Result { - let delta = executed_tx.account_delta().clone(); - + ) -> Result { // Prepare request with proven transaction. // This is needed to be in a separated code block in order to release reference to avoid // borrow checker error. let request = { let transaction_prover = LocalTransactionProver::new(ProvingOptions::default()); - let proven_transaction = - transaction_prover.prove(executed_tx.into()).map_err(|err| { - ProcessError::InternalServerError(format!("Failed to prove transaction: {err}")) - })?; + let proven_transaction = transaction_prover + .prove(executed_tx.into()) + .context("Failed to prove transaction")?; SubmitProvenTransactionRequest { transaction: proven_transaction.to_bytes(), @@ -151,137 +181,50 @@ impl FaucetClient { .rpc_api .submit_proven_transaction(request) .await - .map_err(|err| ProcessError::InternalServerError(err.to_string()))?; - - self.data_store.update_faucet_account(&delta).map_err(|err| { - ProcessError::InternalServerError(format!("Failed to update account: {err}")) - })?; + .context("Failed to submit proven transaction")?; Ok(response.into_inner().block_height) } - pub fn get_faucet_id(&self) -> AccountId { - self.id + /// Returns a reference to the data store. + pub fn data_store(&self) -> &FaucetDataStore { + &self.data_store } -} - -pub struct FaucetDataStore { - faucet_account: Mutex, - seed: Word, - block_header: BlockHeader, - chain_mmr: ChainMmr, -} -// FAUCET DATA STORE -// ================================================================================================ - -impl FaucetDataStore { - pub fn new( - faucet_account: Account, - seed: Word, - root_block_header: BlockHeader, - root_chain_mmr: ChainMmr, - ) -> Self { - Self { - faucet_account: Mutex::new(faucet_account), - seed, - block_header: root_block_header, - chain_mmr: root_chain_mmr, - } - } - - /// Updates the stored faucet account with the provided delta. - fn update_faucet_account(&self, delta: &AccountDelta) -> Result<(), ProcessError> { - self.faucet_account - .lock() - .expect("Poisoned lock") - .apply_delta(delta) - .map_err(|err| ProcessError::InternalServerError(err.to_string())) - } -} - -impl DataStore for FaucetDataStore { - fn get_transaction_inputs( - &self, - account_id: AccountId, - _block_ref: u32, - _notes: &[NoteId], - ) -> Result { - let account = self.faucet_account.lock().expect("Poisoned lock"); - if account_id != account.id() { - return Err(DataStoreError::AccountNotFound(account_id)); - } - - let empty_input_notes = - InputNotes::new(Vec::new()).map_err(DataStoreError::InvalidTransactionInput)?; - - TransactionInputs::new( - account.clone(), - account.is_new().then_some(self.seed), - self.block_header, - self.chain_mmr.clone(), - empty_input_notes, - ) - .map_err(DataStoreError::InvalidTransactionInput) + /// Returns the id of the faucet account. + pub fn get_faucet_id(&self) -> AccountId { + self.id } } // HELPER FUNCTIONS // ================================================================================================ -/// Builds a new faucet account with the provided configuration. -/// -/// Returns the created account, its seed, and the secret key used to sign transactions. -fn build_account(config: FaucetConfig) -> Result<(Account, Word, SecretKey), InitError> { - let token_symbol = TokenSymbol::new(config.token_symbol.as_str()) - .map_err(|err| InitError::AccountCreationError(err.to_string()))?; - - let seed: [u8; 32] = [0; 32]; - - // Instantiate keypair and auth scheme - let mut rng = ChaCha20Rng::from_seed(seed); - let secret = SecretKey::with_rng(&mut rng); - let auth_scheme = AuthScheme::RpoFalcon512 { pub_key: secret.public_key() }; - - let (faucet_account, account_seed) = create_basic_fungible_faucet( - seed, - token_symbol, - config.decimals, - Felt::try_from(config.max_supply) - .map_err(|err| InitError::AccountCreationError(err.to_string()))?, - AccountStorageMode::Private, - auth_scheme, - ) - .map_err(|err| InitError::AccountCreationError(err.to_string()))?; - - Ok((faucet_account, account_seed, secret)) -} - /// Initializes the faucet client by connecting to the node and fetching the root block header. pub async fn initialize_faucet_client( - config: FaucetConfig, -) -> Result<(ApiClient, BlockHeader, ChainMmr), InitError> { + config: &FaucetConfig, +) -> Result<(ApiClient, BlockHeader, ChainMmr), ClientError> { let endpoint = tonic::transport::Endpoint::try_from(config.node_url.clone()) - .map_err(|_| InitError::ClientInitFailed("Failed to connect to node.".to_string()))? + .context("Failed to parse node URL from configuration file")? .timeout(Duration::from_millis(config.timeout_ms)); - let mut rpc_api = ApiClient::connect(endpoint) - .await - .map_err(|err| InitError::ClientInitFailed(err.to_string()))?; + let mut rpc_api = + ApiClient::connect(endpoint).await.context("Failed to connect to the node")?; let request = GetBlockHeaderByNumberRequest { block_num: Some(0), - include_mmr_proof: Some(true), + include_mmr_proof: None, }; let response = rpc_api .get_block_header_by_number(request) .await - .map_err(|err| InitError::ClientInitFailed(format!("Failed to get block header: {err}")))?; - let root_block_header = response.into_inner().block_header.unwrap(); + .context("Failed to get block header")?; + let root_block_header = response + .into_inner() + .block_header + .context("Missing root block header in response")?; - let root_block_header: BlockHeader = root_block_header.try_into().map_err(|err| { - InitError::ClientInitFailed(format!("Failed to parse block header: {err}")) - })?; + let root_block_header = root_block_header.try_into().context("Failed to parse block header")?; let root_chain_mmr = ChainMmr::new( PartialMmr::from_peaks( @@ -294,12 +237,35 @@ pub async fn initialize_faucet_client( Ok((rpc_api, root_block_header, root_chain_mmr)) } +/// Requests account state from the node. +/// +/// The account is expected to be public, otherwise, the error is returned. +async fn request_account_state( + rpc_api: &mut ApiClient, + account_id: AccountId, +) -> Result { + let account_info = rpc_api + .get_account_details(GetAccountDetailsRequest { account_id: Some(account_id.into()) }) + .await? + .into_inner() + .details + .context("Account info field is empty")?; + + let faucet_account_state_bytes = + account_info.details.context("Account details field is empty")?; + + Account::read_from_bytes(&faucet_account_state_bytes) + .map_err(ImplError) + .context("Failed to deserialize faucet account") + .map_err(Into::into) +} + /// Builds transaction arguments for the mint transaction. fn build_transaction_arguments( output_note: &Note, note_type: NoteType, asset: FungibleAsset, -) -> Result { +) -> Result { let recipient = output_note .recipient() .digest() @@ -321,9 +287,7 @@ fn build_transaction_arguments( .replace("{execution_hint}", &Felt::new(execution_hint).to_string()); let script = TransactionScript::compile(script, vec![], TransactionKernel::assembler()) - .map_err(|err| { - ProcessError::InternalServerError(format!("Failed to compile script: {err}")) - })?; + .context("Failed to compile script")?; let mut transaction_args = TransactionArgs::new(Some(script), None, AdviceMap::new()); transaction_args.extend_expected_output_notes(vec![output_note.clone()]); diff --git a/bin/faucet/src/config.rs b/bin/faucet/src/config.rs index 1e443585a..d61fe5cbf 100644 --- a/bin/faucet/src/config.rs +++ b/bin/faucet/src/config.rs @@ -1,4 +1,7 @@ -use std::fmt::{Display, Formatter}; +use std::{ + fmt::{Display, Formatter}, + path::PathBuf, +}; use miden_node_utils::config::{Endpoint, DEFAULT_FAUCET_SERVER_PORT, DEFAULT_NODE_RPC_PORT}; use serde::{Deserialize, Serialize}; @@ -6,30 +9,32 @@ use serde::{Deserialize, Serialize}; // Faucet config // ================================================================================================ +/// Default path to the faucet account file +pub const DEFAULT_FAUCET_ACCOUNT_PATH: &str = "accounts/faucet.mac"; + +/// Default timeout for RPC requests +pub const DEFAULT_RPC_TIMEOUT_MS: u64 = 10000; + #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct FaucetConfig { /// Endpoint of the faucet pub endpoint: Endpoint, - /// Node RPC gRPC endpoint in the format `http://[:]`. + /// Node RPC gRPC endpoint in the format `http://[:]` pub node_url: String, /// Timeout for RPC requests in milliseconds pub timeout_ms: u64, /// Possible options on the amount of asset that should be dispersed on each faucet request pub asset_amount_options: Vec, - /// Token symbol of the generated fungible asset - pub token_symbol: String, - /// Number of decimals of the generated fungible asset - pub decimals: u8, - /// Maximum supply of the generated fungible asset - pub max_supply: u64, + /// Path to the faucet account file + pub faucet_account_path: PathBuf, } impl Display for FaucetConfig { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!( - "{{ endpoint: \"{}\", asset_amount_options: {:?}, token_symbol: {}, decimals: {}, max_supply: {} }}", - self.endpoint, self.asset_amount_options, self.token_symbol, self.decimals, self.max_supply + "{{ endpoint: \"{}\", node_url: \"{}\", timeout_ms: \"{}\", asset_amount_options: {:?}, faucet_account_path: \"{}\" }}", + self.endpoint, self.node_url, self.timeout_ms, self.asset_amount_options, self.faucet_account_path.display() )) } } @@ -39,11 +44,9 @@ impl Default for FaucetConfig { Self { endpoint: Endpoint::localhost(DEFAULT_FAUCET_SERVER_PORT), node_url: Endpoint::localhost(DEFAULT_NODE_RPC_PORT).to_string(), - timeout_ms: 10000, + timeout_ms: DEFAULT_RPC_TIMEOUT_MS, asset_amount_options: vec![100, 500, 1000], - token_symbol: "POL".to_string(), - decimals: 8, - max_supply: 1000000, + faucet_account_path: DEFAULT_FAUCET_ACCOUNT_PATH.into(), } } } diff --git a/bin/faucet/src/errors.rs b/bin/faucet/src/errors.rs index 50777c719..c87054133 100644 --- a/bin/faucet/src/errors.rs +++ b/bin/faucet/src/errors.rs @@ -1,56 +1,61 @@ +use std::fmt::{Debug, Display}; + use axum::{ http::{header, StatusCode}, response::{IntoResponse, Response}, }; use thiserror::Error; +/// Wrapper for implementing `Error` trait for errors, which do not implement it, like +/// [miden_objects::crypto::utils::DeserializationError] and other error types from `miden-base`. #[derive(Debug, Error)] -pub enum InitError { - #[error("Failed to start faucet: {0}")] - FaucetFailedToStart(String), - - #[error("Failed to initialize client: {0}")] - ClientInitFailed(String), +#[error("{0}")] +pub struct ImplError(pub E); - #[error("Failed to configure faucet: {0}")] - ConfigurationError(String), +#[derive(Debug, Error)] +pub enum ClientError { + #[error("Request error: {0}")] + RequestError(#[from] tonic::Status), - #[error("Failed to create Miden account: {0}")] - AccountCreationError(String), + #[error("Client error: {0:#}")] + Other(#[from] anyhow::Error), } #[derive(Debug, Error)] -pub enum ProcessError { +pub enum HandlerError { + #[error("Node client error: {0}")] + ClientError(#[from] ClientError), + + #[error("Server has encountered an internal error: {0:#}")] + Internal(#[from] anyhow::Error), + #[error("Client has submitted a bad request: {0}")] BadRequest(String), - #[error("Server has encountered an internal error: {0}")] - InternalServerError(String), - #[error("Page not found: {0}")] NotFound(String), } -impl ProcessError { +impl HandlerError { fn status_code(&self) -> StatusCode { match *self { Self::BadRequest(_) => StatusCode::BAD_REQUEST, Self::NotFound(_) => StatusCode::NOT_FOUND, - Self::InternalServerError(_) => StatusCode::INTERNAL_SERVER_ERROR, + Self::ClientError(_) | Self::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR, } } fn message(&self) -> String { match self { Self::BadRequest(msg) => msg, - Self::InternalServerError(_) => "Error processing request", + Self::ClientError(_) | Self::Internal(_) => "Error processing request", Self::NotFound(msg) => msg, } .to_string() } } -impl IntoResponse for ProcessError { +impl IntoResponse for HandlerError { fn into_response(self) -> Response { ( self.status_code(), diff --git a/bin/faucet/src/handlers.rs b/bin/faucet/src/handlers.rs index 5e51e4fda..764f997d6 100644 --- a/bin/faucet/src/handlers.rs +++ b/bin/faucet/src/handlers.rs @@ -1,3 +1,4 @@ +use anyhow::Context; use axum::{ extract::{Path, State}, http::{Response, StatusCode}, @@ -15,7 +16,7 @@ use serde::{Deserialize, Serialize}; use tonic::body; use tracing::info; -use crate::{errors::ProcessError, state::FaucetState, COMPONENT}; +use crate::{errors::HandlerError, state::FaucetState, COMPONENT}; #[derive(Deserialize)] pub struct FaucetRequest { @@ -44,7 +45,7 @@ pub async fn get_metadata( pub async fn get_tokens( State(state): State, Json(req): Json, -) -> Result { +) -> Result { info!( target: COMPONENT, account_id = %req.account_id, @@ -55,14 +56,14 @@ pub async fn get_tokens( // Check that the amount is in the asset amount options if !state.config.asset_amount_options.contains(&req.asset_amount) { - return Err(ProcessError::BadRequest("Invalid asset amount".to_string())); + return Err(HandlerError::BadRequest("Invalid asset amount".to_string())); } let mut client = state.client.lock().await; // Receive and hex user account id let target_account_id = AccountId::from_hex(req.account_id.as_str()) - .map_err(|err| ProcessError::BadRequest(err.to_string()))?; + .map_err(|err| HandlerError::BadRequest(err.to_string()))?; // Execute transaction info!(target: COMPONENT, "Executing mint transaction for account."); @@ -72,16 +73,24 @@ pub async fn get_tokens( req.asset_amount, )?; + let mut faucet_account = client.data_store().faucet_account(); + faucet_account + .apply_delta(executed_tx.account_delta()) + .context("Failed to apply faucet account delta")?; + // Run transaction prover & send transaction to node info!(target: COMPONENT, "Proving and submitting transaction."); let block_height = client.prove_and_submit_transaction(executed_tx).await?; + // Update data store with the new faucet state + client.data_store().update_faucet_state(faucet_account).await?; + let note_id: NoteId = created_note.id(); let note_details = NoteDetails::new(created_note.assets().clone(), created_note.recipient().clone()); let note_tag = NoteTag::from_account_id(target_account_id, NoteExecutionMode::Local) - .expect("failed to build note tag for local execution"); + .context("failed to build note tag for local execution")?; // Serialize note into bytes let bytes = NoteFile::NoteDetails { @@ -100,24 +109,26 @@ pub async fn get_tokens( .header(header::CONTENT_DISPOSITION, "attachment; filename=note.mno") .header("Note-Id", note_id.to_string()) .body(body::boxed(Full::from(bytes))) - .map_err(|err| ProcessError::InternalServerError(err.to_string())) + .context("Failed to build response") + .map_err(Into::into) } -pub async fn get_index(state: State) -> Result { +pub async fn get_index(state: State) -> Result { get_static_file(state, Path("index.html".to_string())).await } pub async fn get_static_file( State(state): State, Path(path): Path, -) -> Result { +) -> Result { info!(target: COMPONENT, path, "Serving static file"); - let static_file = state.static_files.get(path.as_str()).ok_or(ProcessError::NotFound(path))?; + let static_file = state.static_files.get(path.as_str()).ok_or(HandlerError::NotFound(path))?; Response::builder() .status(StatusCode::OK) .header(header::CONTENT_TYPE, static_file.mime_type) .body(body::boxed(Full::from(static_file.data))) - .map_err(|err| ProcessError::InternalServerError(err.to_string())) + .context("Failed to build response") + .map_err(Into::into) } diff --git a/bin/faucet/src/main.rs b/bin/faucet/src/main.rs index f58f9f184..a172440ad 100644 --- a/bin/faucet/src/main.rs +++ b/bin/faucet/src/main.rs @@ -3,16 +3,27 @@ mod config; mod errors; mod handlers; mod state; +mod store; -use std::{fs::File, io::Write, path::PathBuf}; +use std::path::PathBuf; +use anyhow::Context; use axum::{ routing::{get, post}, Router, }; use clap::{Parser, Subcommand}; use http::HeaderValue; -use miden_node_utils::{config::load_config, version::LongVersion}; +use miden_lib::{accounts::faucets::create_basic_fungible_faucet, AuthScheme}; +use miden_node_utils::{config::load_config, crypto::get_rpo_random_coin, version::LongVersion}; +use miden_objects::{ + accounts::{AccountData, AccountStorageMode, AuthSecretKey}, + assets::TokenSymbol, + crypto::dsa::rpo_falcon512::SecretKey, + Felt, +}; +use rand::Rng; +use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use state::FaucetState; use tokio::net::TcpListener; use tower::ServiceBuilder; @@ -20,10 +31,10 @@ use tower_http::{cors::CorsLayer, set_header::SetResponseHeaderLayer, trace::Tra use tracing::info; use crate::{ - config::FaucetConfig, - errors::InitError, + config::{FaucetConfig, DEFAULT_FAUCET_ACCOUNT_PATH}, handlers::{get_index, get_metadata, get_static_file, get_tokens}, }; + // CONSTANTS // ================================================================================================= @@ -48,10 +59,24 @@ pub enum Command { config: PathBuf, }, - /// Generates default configuration file for the faucet + /// Create a new public faucet account and save to the specified file + CreateFaucetAccount { + #[arg(short, long, value_name = "FILE", default_value = DEFAULT_FAUCET_ACCOUNT_PATH)] + output_path: PathBuf, + #[arg(short, long)] + token_symbol: String, + #[arg(short, long)] + decimals: u8, + #[arg(short, long)] + max_supply: u64, + }, + + /// Generate default configuration file for the faucet Init { #[arg(short, long, default_value = FAUCET_CONFIG_FILE_PATH)] config_path: String, + #[arg(short, long, default_value = DEFAULT_FAUCET_ACCOUNT_PATH)] + faucet_account_path: String, }, } @@ -59,16 +84,15 @@ pub enum Command { // ================================================================================================= #[tokio::main] -async fn main() -> Result<(), InitError> { - miden_node_utils::logging::setup_logging() - .map_err(|err| InitError::FaucetFailedToStart(err.to_string()))?; +async fn main() -> anyhow::Result<()> { + miden_node_utils::logging::setup_logging().context("Failed to initialize logging")?; let cli = Cli::parse(); match &cli.command { Command::Start { config } => { - let config: FaucetConfig = load_config(config) - .map_err(|err| InitError::ConfigurationError(err.to_string()))?; + let config: FaucetConfig = + load_config(config).context("Failed to load configuration file")?; let faucet_state = FaucetState::new(config.clone()).await?; @@ -96,31 +120,67 @@ async fn main() -> Result<(), InitError> { let listener = TcpListener::bind((config.endpoint.host.as_str(), config.endpoint.port)) .await - .map_err(|err| InitError::FaucetFailedToStart(err.to_string()))?; + .context("Failed to bind TCP listener")?; info!(target: COMPONENT, endpoint = %config.endpoint, "Server started"); axum::serve(listener, app).await.unwrap(); }, - Command::Init { config_path } => { - let current_dir = std::env::current_dir().map_err(|err| { - InitError::ConfigurationError(format!("failed to open current directory: {err}")) - })?; + + Command::CreateFaucetAccount { + output_path, + token_symbol, + decimals, + max_supply, + } => { + println!("Generating new faucet account. This may take a few minutes..."); + + let current_dir = + std::env::current_dir().context("Failed to open current directory")?; + + let mut rng = ChaCha20Rng::from_seed(rand::random()); + + let secret = SecretKey::with_rng(&mut get_rpo_random_coin(&mut rng)); + + let (account, account_seed) = create_basic_fungible_faucet( + rng.gen(), + TokenSymbol::try_from(token_symbol.as_str()) + .context("Failed to parse token symbol")?, + *decimals, + Felt::try_from(*max_supply) + .expect("max supply value is greater than or equal to the field modulus"), + AccountStorageMode::Public, + AuthScheme::RpoFalcon512 { pub_key: secret.public_key() }, + ) + .context("Failed to create basic fungible faucet account")?; + + let account_data = + AccountData::new(account, Some(account_seed), AuthSecretKey::RpoFalcon512(secret)); + + let output_path = current_dir.join(output_path); + account_data + .write(&output_path) + .context("Failed to write account data to file")?; + + println!("Faucet account file successfully created at: {output_path:?}"); + }, + + Command::Init { config_path, faucet_account_path } => { + let current_dir = + std::env::current_dir().context("Failed to open current directory")?; let config_file_path = current_dir.join(config_path); - let config = FaucetConfig::default(); - let config_as_toml_string = toml::to_string(&config).map_err(|err| { - InitError::ConfigurationError(format!("Failed to serialize default config: {err}")) - })?; - - let mut file_handle = - File::options().write(true).create_new(true).open(&config_file_path).map_err( - |err| InitError::ConfigurationError(format!("Error opening the file: {err}")), - )?; - - file_handle.write(config_as_toml_string.as_bytes()).map_err(|err| { - InitError::ConfigurationError(format!("Error writing to file: {err}")) - })?; + + let config = FaucetConfig { + faucet_account_path: faucet_account_path.into(), + ..FaucetConfig::default() + }; + + let config_as_toml_string = + toml::to_string(&config).context("Failed to serialize default config")?; + + std::fs::write(&config_file_path, config_as_toml_string) + .context("Error writing config to file")?; println!("Config file successfully created at: {config_file_path:?}"); }, diff --git a/bin/faucet/src/state.rs b/bin/faucet/src/state.rs index 898a5e7bd..fb6940812 100644 --- a/bin/faucet/src/state.rs +++ b/bin/faucet/src/state.rs @@ -5,9 +5,8 @@ use static_files::Resource; use tokio::sync::Mutex; use tracing::info; -use crate::{ - client::FaucetClient, config::FaucetConfig, errors::InitError, static_resources, COMPONENT, -}; +use crate::{client::FaucetClient, config::FaucetConfig, static_resources, COMPONENT}; + // FAUCET STATE // ================================================================================================ @@ -24,8 +23,8 @@ pub struct FaucetState { } impl FaucetState { - pub async fn new(config: FaucetConfig) -> Result { - let client = FaucetClient::new(config.clone()).await?; + pub async fn new(config: FaucetConfig) -> anyhow::Result { + let client = FaucetClient::new(&config).await?; let id = client.get_faucet_id(); let client = Arc::new(Mutex::new(client)); let static_files = Arc::new(static_resources::generate()); diff --git a/bin/faucet/src/store.rs b/bin/faucet/src/store.rs new file mode 100644 index 000000000..02050765e --- /dev/null +++ b/bin/faucet/src/store.rs @@ -0,0 +1,73 @@ +use std::sync::Mutex; + +use miden_objects::{ + accounts::{Account, AccountId}, + notes::NoteId, + transaction::{ChainMmr, InputNotes, TransactionInputs}, + BlockHeader, Word, +}; +use miden_tx::{DataStore, DataStoreError}; + +use crate::errors::HandlerError; + +pub struct FaucetDataStore { + faucet_account: Mutex, + /// Optional initial seed used for faucet account creation. + init_seed: Option, + block_header: BlockHeader, + chain_mmr: ChainMmr, +} + +// FAUCET DATA STORE +// ================================================================================================ + +impl FaucetDataStore { + pub fn new( + faucet_account: Account, + init_seed: Option, + block_header: BlockHeader, + chain_mmr: ChainMmr, + ) -> Self { + Self { + faucet_account: Mutex::new(faucet_account), + init_seed, + block_header, + chain_mmr, + } + } + + /// Returns the stored faucet account. + pub fn faucet_account(&self) -> Account { + self.faucet_account.lock().expect("Poisoned lock").clone() + } + + /// Updates the stored faucet account with the new one. + pub async fn update_faucet_state(&self, new_faucet_state: Account) -> Result<(), HandlerError> { + *self.faucet_account.lock().expect("Poisoned lock") = new_faucet_state; + + Ok(()) + } +} + +impl DataStore for FaucetDataStore { + fn get_transaction_inputs( + &self, + account_id: AccountId, + _block_ref: u32, + _notes: &[NoteId], + ) -> Result { + let account = self.faucet_account.lock().expect("Poisoned lock"); + if account_id != account.id() { + return Err(DataStoreError::AccountNotFound(account_id)); + } + + TransactionInputs::new( + account.clone(), + account.is_new().then_some(self.init_seed).flatten(), + self.block_header, + self.chain_mmr.clone(), + InputNotes::default(), + ) + .map_err(DataStoreError::InvalidTransactionInput) + } +} diff --git a/bin/node/Cargo.toml b/bin/node/Cargo.toml index d544f285f..b855cbe64 100644 --- a/bin/node/Cargo.toml +++ b/bin/node/Cargo.toml @@ -26,6 +26,7 @@ miden-node-rpc = { workspace = true } miden-node-store = { workspace = true } miden-node-utils = { workspace = true } miden-objects = { workspace = true } +rand = { workspace = true } rand_chacha = "0.3" serde = { version = "1.0", features = ["derive"] } tokio = { workspace = true, features = ["rt-multi-thread", "net", "macros"] } diff --git a/bin/node/src/commands/genesis/inputs.rs b/bin/node/src/commands/genesis/inputs.rs index a400fc69f..2f93d1d60 100644 --- a/bin/node/src/commands/genesis/inputs.rs +++ b/bin/node/src/commands/genesis/inputs.rs @@ -23,9 +23,7 @@ pub enum AccountInput { #[derive(Debug, Clone, Deserialize, Serialize)] pub struct BasicFungibleFaucetInputs { - pub init_seed: String, pub auth_scheme: AuthSchemeInput, - pub auth_seed: String, pub token_symbol: String, pub decimals: u8, pub max_supply: u64, @@ -46,11 +44,7 @@ impl Default for GenesisInput { .expect("Current timestamp should be greater than unix epoch") .as_secs() as u32, accounts: Some(vec![AccountInput::BasicFungibleFaucet(BasicFungibleFaucetInputs { - init_seed: "0xc123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - .to_string(), auth_scheme: AuthSchemeInput::RpoFalcon512, - auth_seed: "0xd123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - .to_string(), token_symbol: "POL".to_string(), decimals: 12, max_supply: 1000000, diff --git a/bin/node/src/commands/genesis/mod.rs b/bin/node/src/commands/genesis/mod.rs index 3772b1201..8e9d7f7f3 100644 --- a/bin/node/src/commands/genesis/mod.rs +++ b/bin/node/src/commands/genesis/mod.rs @@ -7,17 +7,15 @@ use anyhow::{anyhow, bail, Context, Result}; pub use inputs::{AccountInput, AuthSchemeInput, GenesisInput}; use miden_lib::{accounts::faucets::create_basic_fungible_faucet, AuthScheme}; use miden_node_store::genesis::GenesisState; -use miden_node_utils::config::load_config; +use miden_node_utils::{config::load_config, crypto::get_rpo_random_coin}; use miden_objects::{ - accounts::{Account, AccountData, AccountStorageMode, AuthSecretKey}, + accounts::{Account, AccountData, AuthSecretKey}, assets::TokenSymbol, - crypto::{ - dsa::rpo_falcon512::SecretKey, - rand::RpoRandomCoin, - utils::{hex_to_bytes, Serializable}, - }, - Digest, Felt, ONE, + crypto::{dsa::rpo_falcon512::SecretKey, utils::Serializable}, + Felt, ONE, }; +use rand::Rng; +use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use tracing::info; mod inputs; @@ -80,13 +78,9 @@ pub fn make_genesis(inputs_path: &PathBuf, output_path: &PathBuf, force: &bool) })?; info!("Genesis input file: {} has successfully been loaded.", inputs_path.display()); + let accounts_path = parent_path.join(DEFAULT_ACCOUNTS_DIR); let accounts = - create_accounts(&genesis_input.accounts.unwrap_or_default(), parent_path, force)?; - info!( - "Accounts have successfully been created at: {}/{}", - parent_path.display(), - DEFAULT_ACCOUNTS_DIR - ); + create_accounts(&genesis_input.accounts.unwrap_or_default(), &accounts_path, force)?; let genesis_state = GenesisState::new(accounts, genesis_input.version, genesis_input.timestamp); fs::write(output_path, genesis_state.to_bytes()).unwrap_or_else(|_| { @@ -102,13 +96,10 @@ pub fn make_genesis(inputs_path: &PathBuf, output_path: &PathBuf, force: &bool) /// This function also writes the account data files into the default accounts directory. fn create_accounts( accounts: &[AccountInput], - parent_path: &Path, + accounts_path: impl AsRef, force: &bool, ) -> Result> { - let mut accounts_path = PathBuf::from(&parent_path); - accounts_path.push(DEFAULT_ACCOUNTS_DIR); - - if accounts_path.try_exists()? { + if accounts_path.as_ref().try_exists()? { if !force { bail!( "Failed to create accounts directory because it already exists. \ @@ -121,21 +112,19 @@ fn create_accounts( fs::create_dir_all(&accounts_path).context("Failed to create accounts directory")?; let mut final_accounts = Vec::new(); + let mut faucet_count = 0; + let mut rng = ChaCha20Rng::from_seed(rand::random()); for account in accounts { // build offchain account data from account inputs - let mut account_data = match account { + let (mut account_data, name) = match account { AccountInput::BasicFungibleFaucet(inputs) => { info!("Creating fungible faucet account..."); - let init_seed = hex_to_bytes(&inputs.init_seed)?; - - let (auth_scheme, auth_secret_key) = - parse_auth_inputs(inputs.auth_scheme, &inputs.auth_seed)?; - - let storage_mode: AccountStorageMode = inputs.storage_mode.as_str().try_into()?; + let (auth_scheme, auth_secret_key) = gen_auth_keys(inputs.auth_scheme, &mut rng)?; + let storage_mode = inputs.storage_mode.as_str().try_into()?; let (account, account_seed) = create_basic_fungible_faucet( - init_seed, + rng.gen(), TokenSymbol::try_from(inputs.token_symbol.as_str())?, inputs.decimals, Felt::try_from(inputs.max_supply) @@ -144,23 +133,28 @@ fn create_accounts( auth_scheme, )?; - AccountData::new(account, Some(account_seed), auth_secret_key) + let name = format!( + "faucet{}", + (faucet_count > 0).then(|| faucet_count.to_string()).unwrap_or_default() + ); + faucet_count += 1; + + (AccountData::new(account, Some(account_seed), auth_secret_key), name) }, }; // write account data to file - let path = format!("{}/account{}.mac", accounts_path.display(), final_accounts.len()); - let path = Path::new(&path); + let path = accounts_path.as_ref().join(format!("{name}.mac")); - if let Ok(path_exists) = path.try_exists() { - if path_exists && !force { - bail!("Failed to generate account file {} because it already exists. Use the --force flag to overwrite.", path.display()); - } + if !force && matches!(path.try_exists(), Ok(true)) { + bail!("Failed to generate account file {} because it already exists. Use the --force flag to overwrite.", path.display()); } account_data.account.set_nonce(ONE)?; - account_data.write(path)?; + account_data.write(&path)?; + + info!("Account \"{name}\" has successfully been saved to: {}", path.display()); final_accounts.push(account_data.account); } @@ -168,21 +162,18 @@ fn create_accounts( Ok(final_accounts) } -fn parse_auth_inputs( +fn gen_auth_keys( auth_scheme_input: AuthSchemeInput, - auth_seed: &str, + rng: &mut ChaCha20Rng, ) -> Result<(AuthScheme, AuthSecretKey)> { match auth_scheme_input { AuthSchemeInput::RpoFalcon512 => { - let auth_seed: [u8; 32] = hex_to_bytes(auth_seed)?; - let rng_seed = Digest::try_from(&auth_seed)?.into(); - let mut rng = RpoRandomCoin::new(rng_seed); - let secret = SecretKey::with_rng(&mut rng); + let secret = SecretKey::with_rng(&mut get_rpo_random_coin(rng)); - let auth_scheme = AuthScheme::RpoFalcon512 { pub_key: secret.public_key() }; - let auth_secret_key = AuthSecretKey::RpoFalcon512(secret); - - Ok((auth_scheme, auth_secret_key)) + Ok(( + AuthScheme::RpoFalcon512 { pub_key: secret.public_key() }, + AuthSecretKey::RpoFalcon512(secret), + )) }, } } @@ -215,9 +206,7 @@ mod tests { [[accounts]] type = "BasicFungibleFaucet" - init_seed = "0xc123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" auth_scheme = "RpoFalcon512" - auth_seed = "0xd123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" token_symbol = "POL" decimals = 12 max_supply = 1000000 @@ -230,7 +219,7 @@ mod tests { // run make_genesis to generate genesis.dat and accounts folder and files make_genesis(&genesis_inputs_file_path, &genesis_dat_file_path, &true).unwrap(); - let a0_file_path = PathBuf::from("accounts/account0.mac"); + let a0_file_path = PathBuf::from("accounts/faucet.mac"); // assert that the genesis.dat and account files exist assert!(genesis_dat_file_path.exists()); diff --git a/bin/node/src/main.rs b/bin/node/src/main.rs index 1ce93c60b..1839d7484 100644 --- a/bin/node/src/main.rs +++ b/bin/node/src/main.rs @@ -127,11 +127,8 @@ async fn main() -> anyhow::Result<()> { let current_dir = std::env::current_dir() .map_err(|err| anyhow!("failed to open current directory: {err}"))?; - let mut config = current_dir.clone(); - let mut genesis = current_dir.clone(); - - config.push(config_path); - genesis.push(genesis_path); + let config = current_dir.join(config_path); + let genesis = current_dir.join(genesis_path); init_config_files(config, genesis) }, diff --git a/config/genesis.toml b/config/genesis.toml index 6a77d9a77..8c74a4dd3 100644 --- a/config/genesis.toml +++ b/config/genesis.toml @@ -5,9 +5,7 @@ timestamp = 1672531200 [[accounts]] type = "BasicFungibleFaucet" storage_mode = "public" -init_seed = "0xc123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" auth_scheme = "RpoFalcon512" -auth_seed = "0xd123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" token_symbol = "POL" decimals = 12 max_supply = 1000000 diff --git a/config/miden-faucet.toml b/config/miden-faucet.toml index a9fdc1428..8124e33db 100644 --- a/config/miden-faucet.toml +++ b/config/miden-faucet.toml @@ -1,9 +1,5 @@ endpoint = { host = "localhost", port = 8080 } node_url = "http://localhost:57291" timeout_ms = 10000 - -# Data used to construct the faucet account of the faucet asset_amount_options = [100, 500, 1000] -token_symbol = "POL" -decimals = 8 -max_supply = 1000000 +faucet_account_path = "accounts/faucet.mac" diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml index e3b4494d5..75f19675b 100644 --- a/crates/utils/Cargo.toml +++ b/crates/utils/Cargo.toml @@ -20,6 +20,7 @@ anyhow = { version = "1.0" } figment = { version = "0.10", features = ["toml", "env"] } itertools = { version = "0.12" } miden-objects = { workspace = true } +rand = { workspace = true } serde = { version = "1.0", features = ["derive"] } thiserror = { workspace = true } tonic = { workspace = true } diff --git a/crates/utils/src/crypto.rs b/crates/utils/src/crypto.rs new file mode 100644 index 000000000..f8a48aef2 --- /dev/null +++ b/crates/utils/src/crypto.rs @@ -0,0 +1,13 @@ +use miden_objects::{ + crypto::{hash::rpo::RpoDigest, rand::RpoRandomCoin}, + Felt, +}; +use rand::{Rng, RngCore}; + +/// Creates a new RPO Random Coin with random seed +pub fn get_rpo_random_coin(rng: &mut T) -> RpoRandomCoin { + let auth_seed: [u64; 4] = rng.gen(); + let rng_seed = RpoDigest::from(auth_seed.map(Felt::new)); + + RpoRandomCoin::new(rng_seed.into()) +} diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index b098bf2d8..275ee7e35 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -1,4 +1,5 @@ pub mod config; +pub mod crypto; pub mod errors; pub mod formatting; pub mod logging; From 573f37b0fd7cd572889cdf2ce20623495e421f3f Mon Sep 17 00:00:00 2001 From: Mirko <48352201+Mirko-von-Leipzig@users.noreply.github.com> Date: Sat, 2 Nov 2024 19:14:47 +0200 Subject: [PATCH 31/37] chore: re-enable blocks_in_conditions lint (#539) Clippy issue https://github.com/rust-lang/rust-clippy/issues/12281 was fixed in v1.81. We now have MSRV of 1.82 allowing us to remove our workaround. More specifically, #[async_trait] was triggering this lint, and as of 1.81 no longer does. --- crates/block-producer/src/batch_builder/mod.rs | 6 ------ crates/block-producer/src/block_builder/mod.rs | 3 --- crates/block-producer/src/server/api.rs | 3 --- crates/block-producer/src/state_view/mod.rs | 6 ------ crates/block-producer/src/store/mod.rs | 6 ------ crates/rpc/src/server/api.rs | 3 --- crates/store/src/server/api.rs | 3 --- 7 files changed, 30 deletions(-) diff --git a/crates/block-producer/src/batch_builder/mod.rs b/crates/block-producer/src/batch_builder/mod.rs index 513321f7e..8151b1442 100644 --- a/crates/block-producer/src/batch_builder/mod.rs +++ b/crates/block-producer/src/batch_builder/mod.rs @@ -57,9 +57,6 @@ pub struct DefaultBatchBuilder { ready_batches: SharedRwVec, } -// FIXME: remove the allow when the upstream clippy issue is fixed: -// https://github.com/rust-lang/rust-clippy/issues/12281 -#[allow(clippy::blocks_in_conditions)] impl DefaultBatchBuilder where S: Store, @@ -146,9 +143,6 @@ where } } -// FIXME: remove the allow when the upstream clippy issue is fixed: -// https://github.com/rust-lang/rust-clippy/issues/12281 -#[allow(clippy::blocks_in_conditions)] #[async_trait] impl BatchBuilder for DefaultBatchBuilder where diff --git a/crates/block-producer/src/block_builder/mod.rs b/crates/block-producer/src/block_builder/mod.rs index 0522d1140..0d120801f 100644 --- a/crates/block-producer/src/block_builder/mod.rs +++ b/crates/block-producer/src/block_builder/mod.rs @@ -58,9 +58,6 @@ where } } -// FIXME: remove the allow when the upstream clippy issue is fixed: -// https://github.com/rust-lang/rust-clippy/issues/12281 -#[allow(clippy::blocks_in_conditions)] #[async_trait] impl BlockBuilder for DefaultBlockBuilder where diff --git a/crates/block-producer/src/server/api.rs b/crates/block-producer/src/server/api.rs index 8a917242e..22405feda 100644 --- a/crates/block-producer/src/server/api.rs +++ b/crates/block-producer/src/server/api.rs @@ -28,9 +28,6 @@ impl BlockProducerApi { } } -// FIXME: remove the allow when the upstream clippy issue is fixed: -// https://github.com/rust-lang/rust-clippy/issues/12281 -#[allow(clippy::blocks_in_conditions)] #[tonic::async_trait] impl api_server::Api for BlockProducerApi where diff --git a/crates/block-producer/src/state_view/mod.rs b/crates/block-producer/src/state_view/mod.rs index f0bcf1b93..7fb69faff 100644 --- a/crates/block-producer/src/state_view/mod.rs +++ b/crates/block-producer/src/state_view/mod.rs @@ -56,9 +56,6 @@ where } } -// FIXME: remove the allow when the upstream clippy issue is fixed: -// https://github.com/rust-lang/rust-clippy/issues/12281 -#[allow(clippy::blocks_in_conditions)] #[async_trait] impl TransactionValidator for DefaultStateView where @@ -136,9 +133,6 @@ where } } -// FIXME: remove the allow when the upstream clippy issue is fixed: -// https://github.com/rust-lang/rust-clippy/issues/12281 -#[allow(clippy::blocks_in_conditions)] #[async_trait] impl ApplyBlock for DefaultStateView where diff --git a/crates/block-producer/src/store/mod.rs b/crates/block-producer/src/store/mod.rs index 8c06005a1..57e4f88f7 100644 --- a/crates/block-producer/src/store/mod.rs +++ b/crates/block-producer/src/store/mod.rs @@ -165,9 +165,6 @@ impl DefaultStore { } } -// FIXME: remove the allow when the upstream clippy issue is fixed: -// https://github.com/rust-lang/rust-clippy/issues/12281 -#[allow(clippy::blocks_in_conditions)] #[async_trait] impl ApplyBlock for DefaultStore { #[instrument(target = "miden-block-producer", skip_all, err)] @@ -185,9 +182,6 @@ impl ApplyBlock for DefaultStore { } } -// FIXME: remove the allow when the upstream clippy issue is fixed: -// https://github.com/rust-lang/rust-clippy/issues/12281 -#[allow(clippy::blocks_in_conditions)] #[async_trait] impl Store for DefaultStore { #[instrument(target = "miden-block-producer", skip_all, err)] diff --git a/crates/rpc/src/server/api.rs b/crates/rpc/src/server/api.rs index 5c25bd480..56f97c788 100644 --- a/crates/rpc/src/server/api.rs +++ b/crates/rpc/src/server/api.rs @@ -56,9 +56,6 @@ impl RpcApi { } } -// FIXME: remove the allow when the upstream clippy issue is fixed: -// https://github.com/rust-lang/rust-clippy/issues/12281 -#[allow(clippy::blocks_in_conditions)] #[tonic::async_trait] impl api_server::Api for RpcApi { #[instrument( diff --git a/crates/store/src/server/api.rs b/crates/store/src/server/api.rs index 51cb21ef4..bd741575c 100644 --- a/crates/store/src/server/api.rs +++ b/crates/store/src/server/api.rs @@ -50,9 +50,6 @@ pub struct StoreApi { pub(super) state: Arc, } -// FIXME: remove the allow when the upstream clippy issue is fixed: -// https://github.com/rust-lang/rust-clippy/issues/12281 -#[allow(clippy::blocks_in_conditions)] #[tonic::async_trait] impl api_server::Api for StoreApi { // CLIENT ENDPOINTS From 1a380357890ce5066c0b47579b30bf03e2e40fec Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Mon, 4 Nov 2024 22:47:29 -0800 Subject: [PATCH 32/37] chore: point miden-vm dependency to crates.io versions (v0.11) --- Cargo.lock | 162 ++++++++++++++++--------------- Cargo.toml | 6 +- crates/block-producer/Cargo.toml | 2 +- crates/store/src/db/tests.rs | 50 ++++++---- 4 files changed, 119 insertions(+), 101 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 67049c24b..f3bdaec30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,9 +55,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -70,9 +70,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" @@ -104,9 +104,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" +checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" [[package]] name = "arrayref" @@ -395,9 +395,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.31" +version = "1.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9" dependencies = [ "jobserver", "libc", @@ -912,8 +912,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -964,9 +966,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] name = "hashlink" @@ -1064,9 +1066,9 @@ dependencies = [ [[package]] name = "hyper-timeout" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ "hyper", "hyper-util", @@ -1146,7 +1148,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.1", ] [[package]] @@ -1284,9 +1286,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00419de735aac21d53b0de5ce2c03bd3627277cf471300f27ebc89f7d828047" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "libredox" @@ -1401,8 +1403,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miden-air" -version = "0.10.5" -source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea00ea451d1547978817a37c1904ff34f4a24de2c23f9b77b282a0bc570ac3f1" dependencies = [ "miden-core", "miden-thiserror", @@ -1412,8 +1415,9 @@ dependencies = [ [[package]] name = "miden-assembly" -version = "0.10.5" -source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58925d5ab3d625b8e828267a64dd555b1fe37cd5a1d89d09224920d3255de5a9" dependencies = [ "aho-corasick", "lalrpop", @@ -1424,13 +1428,14 @@ dependencies = [ "rustc_version 0.4.1", "smallvec", "tracing", - "unicode-width", + "unicode-width 0.2.0", ] [[package]] name = "miden-core" -version = "0.10.5" -source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba2f0ffd0362c91c0eedba391a3c17a8047389e15020ec95b0d7e840375bf03" dependencies = [ "lock_api", "loom", @@ -1448,9 +1453,9 @@ dependencies = [ [[package]] name = "miden-crypto" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0ca714c8242f329b9ea6f1a5bf0e93f1490f348f982e3a606d91b884254308" +checksum = "f50a68deed96cde1f51eb623f75828e320f699e0d798f11592f8958ba8b512c3" dependencies = [ "blake3", "cc", @@ -1500,13 +1505,13 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e392e0a8c34b32671012b439de35fa8987bf14f0f8aac279b97f8b8cc6e263b" dependencies = [ - "unicode-width", + "unicode-width 0.1.14", ] [[package]] name = "miden-lib" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#b624d0810b1b3813f106aa38b796b9d62a39265d" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#ff3c5227c5962cc97cd44562f134b0a545be21cc" dependencies = [ "miden-assembly", "miden-objects", @@ -1542,7 +1547,7 @@ dependencies = [ "terminal_size", "textwrap", "trybuild", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -1702,8 +1707,9 @@ dependencies = [ [[package]] name = "miden-objects" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#b624d0810b1b3813f106aa38b796b9d62a39265d" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#ff3c5227c5962cc97cd44562f134b0a545be21cc" dependencies = [ + "getrandom", "miden-assembly", "miden-core", "miden-crypto", @@ -1715,8 +1721,9 @@ dependencies = [ [[package]] name = "miden-processor" -version = "0.10.6" -source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e1a756be679bfe2bdb209b9f4f12b4b59e8cac7c9f884ad90535b32bbd75923" dependencies = [ "miden-air", "miden-core", @@ -1726,12 +1733,14 @@ dependencies = [ [[package]] name = "miden-prover" -version = "0.10.5" -source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b6c2fc7ed9831493e1c18fb9d15a4b780ec624e9192f494ad3900c19bfe5b17" dependencies = [ "miden-air", "miden-processor", "tracing", + "winter-maybe-async", "winter-prover", ] @@ -1741,8 +1750,9 @@ version = "0.6.0" [[package]] name = "miden-stdlib" -version = "0.10.5" -source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09948fda011d044273d1bbc56669da410ee3167f96bf1ad9885c946cfbed5757" dependencies = [ "miden-assembly", ] @@ -1770,7 +1780,7 @@ dependencies = [ [[package]] name = "miden-tx" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#b624d0810b1b3813f106aa38b796b9d62a39265d" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#ff3c5227c5962cc97cd44562f134b0a545be21cc" dependencies = [ "async-trait", "miden-assembly", @@ -1783,13 +1793,14 @@ dependencies = [ "rand_chacha", "regex", "walkdir", - "winter-maybe-async 0.10.1", + "winter-maybe-async", ] [[package]] name = "miden-verifier" -version = "0.10.5" -source = "git+https://github.com/0xPolygonMiden/miden-vm.git?branch=next#9f9cc63b709d8b7c83841d8e421701dcd33792bb" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "636b2eab9dc0a9fdd6d30d9ece3cf276b012e9ecbccd934d4c0befa07c84cfd0" dependencies = [ "miden-air", "miden-core", @@ -1814,7 +1825,7 @@ dependencies = [ "terminal_size", "textwrap", "thiserror", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -2530,9 +2541,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.38" +version = "0.38.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" +checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" dependencies = [ "bitflags", "errno", @@ -2803,9 +2814,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "2.0.85" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -2881,23 +2892,23 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" dependencies = [ "smawk", "unicode-linebreak", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] name = "thiserror" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", @@ -3340,6 +3351,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "unicode-xid" version = "0.2.6" @@ -3782,9 +3799,9 @@ dependencies = [ [[package]] name = "winter-air" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b72f12b88ebb060b52c0e9aece9bb64a9fc38daf7ba689dd5ce63271b456c883" +checksum = "29bec0b06b741543f43e3a6677b95b200d4cad2daab76e6721e14345345bfd0e" dependencies = [ "libm", "winter-crypto", @@ -3795,9 +3812,9 @@ dependencies = [ [[package]] name = "winter-crypto" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00fbb724d2d9fbfd3aa16ea27f5e461d4fe1d74b0c9e0ed1bf79e9e2a955f4d5" +checksum = "163da45f1d4d65cac361b8df4835a6daa95b3399154e16eb0305c178c6f6c1f4" dependencies = [ "blake3", "sha3", @@ -3807,9 +3824,9 @@ dependencies = [ [[package]] name = "winter-fri" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab6077cf4c23c0411f591f4ba29378e27f26acb8cef3c51cadd93daaf6080b3" +checksum = "3b7b394670d68979a4cc21a37a95ef8ef350cf84be9256c53effe3052df50d26" dependencies = [ "winter-crypto", "winter-math", @@ -3818,24 +3835,13 @@ dependencies = [ [[package]] name = "winter-math" -version = "0.9.3" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0e685b3b872d82e58a86519294a814b7bc7a4d3cd2c93570a7d80c0c5a1aba" +checksum = "5a8ba832121679e79b004b0003018c85873956d742a39c348c247f680fe15e00" dependencies = [ "winter-utils", ] -[[package]] -name = "winter-maybe-async" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ce0f4161cdde50de809b3869c1cb083a09e92e949428ea28f04c0d64045875c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "winter-maybe-async" version = "0.10.1" @@ -3848,24 +3854,24 @@ dependencies = [ [[package]] name = "winter-prover" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17e3dbae97050f58e01ed4f12906e247841575a0518632e052941a1c37468df" +checksum = "2f55f0153d26691caaf969066a13a824bcf3c98719d71b0f569bf8dc40a06fb9" dependencies = [ "tracing", "winter-air", "winter-crypto", "winter-fri", "winter-math", - "winter-maybe-async 0.9.0", + "winter-maybe-async", "winter-utils", ] [[package]] name = "winter-rand-utils" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b827c901ab0c316d89812858ff451d60855c0a5c7ae734b098c62a28624181" +checksum = "4a7616d11fcc26552dada45c803a884ac97c253218835b83a2c63e1c2a988639" dependencies = [ "rand", "winter-utils", @@ -3873,18 +3879,18 @@ dependencies = [ [[package]] name = "winter-utils" -version = "0.9.3" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "961e81e9388877a25db1c034ba38253de2055f569633ae6a665d857a0556391b" +checksum = "76b116c8ade0172506f8bda32dc674cf6b230adc8516e5138a0173ae69158a4f" dependencies = [ "rayon", ] [[package]] name = "winter-verifier" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324002ade90f21e85599d51a232a80781efc8cb46f511f8bc89f9c5a4eb9cb65" +checksum = "2ae1648768f96f5e6321a48a5bff5cc3101d2e51b23a6a095c6c9c9e133ecb61" dependencies = [ "winter-air", "winter-crypto", @@ -3895,9 +3901,9 @@ dependencies = [ [[package]] name = "winterfell" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01151ac5fe2d783950743e8a110e0a2f26994f888b4cbe848699142cb3ea1e5b" +checksum = "39c8336dc6a035698780b8cc624f875e479bd6bf6e1846670f3ef4485c125882" dependencies = [ "winter-air", "winter-prover", diff --git a/Cargo.toml b/Cargo.toml index 9e0d53b99..bcd59f59d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ exclude = [".github/"] readme = "README.md" [workspace.dependencies] -miden-air = { git = "https://github.com/0xPolygonMiden/miden-vm.git", branch = "next" } +miden-air = { version = "0.11" } miden-lib = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } miden-node-block-producer = { path = "crates/block-producer", version = "0.6" } miden-node-faucet = { path = "bin/faucet", version = "0.6" } @@ -36,8 +36,8 @@ miden-node-store = { path = "crates/store", version = "0.6" } miden-node-test-macro = { path = "crates/test-macro" } miden-node-utils = { path = "crates/utils", version = "0.6" } miden-objects = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } -miden-processor = { git = "https://github.com/0xPolygonMiden/miden-vm.git", branch = "next" } -miden-stdlib = { git = "https://github.com/0xPolygonMiden/miden-vm.git", branch = "next", default-features = false } +miden-processor = { version = "0.11" } +miden-stdlib = { version = "0.11", default-features = false } miden-tx = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } prost = { version = "0.13" } rand = { version = "0.8" } diff --git a/crates/block-producer/Cargo.toml b/crates/block-producer/Cargo.toml index 1d1476fdf..ea6f32116 100644 --- a/crates/block-producer/Cargo.toml +++ b/crates/block-producer/Cargo.toml @@ -43,4 +43,4 @@ miden-objects = { workspace = true, features = ["testing"] } miden-tx = { workspace = true, features = ["testing"] } rand_chacha = { version = "0.3", default-features = false } tokio = { workspace = true, features = ["test-util"] } -winterfell = { version = "0.9" } +winterfell = { version = "0.10" } diff --git a/crates/store/src/db/tests.rs b/crates/store/src/db/tests.rs index a79166003..a63f982f4 100644 --- a/crates/store/src/db/tests.rs +++ b/crates/store/src/db/tests.rs @@ -8,8 +8,8 @@ use miden_objects::{ ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_OFF_CHAIN, }, delta::AccountUpdateDetails, - Account, AccountCode, AccountDelta, AccountId, AccountStorage, AccountStorageDelta, - AccountVaultDelta, StorageSlot, + Account, AccountCode, AccountComponent, AccountDelta, AccountId, AccountStorage, + AccountStorageDelta, AccountType, AccountVaultDelta, StorageSlot, }, assets::{Asset, AssetVault, FungibleAsset, NonFungibleAsset, NonFungibleAssetDetails}, block::{BlockAccountUpdate, BlockNoteIndex, BlockNoteTree}, @@ -334,14 +334,6 @@ fn test_sql_public_account_details() { let non_fungible_faucet_id = AccountId::try_from(ACCOUNT_ID_NON_FUNGIBLE_FAUCET_ON_CHAIN).unwrap(); - let mut storage = AccountStorage::new( - std::iter::repeat(StorageSlot::Value(Word::default())).take(6).collect(), - ) - .unwrap(); - storage.set_item(1, num_to_word(1)).unwrap(); - storage.set_item(3, num_to_word(3)).unwrap(); - storage.set_item(5, num_to_word(5)).unwrap(); - let nft1 = Asset::NonFungible( NonFungibleAsset::new( &NonFungibleAssetDetails::new(non_fungible_faucet_id, vec![1, 2, 3]).unwrap(), @@ -349,6 +341,8 @@ fn test_sql_public_account_details() { .unwrap(), ); + let (code, storage) = mock_account_code_and_storage(account_id.account_type()); + let mut account = Account::from_parts( account_id, AssetVault::new(&[ @@ -357,7 +351,7 @@ fn test_sql_public_account_details() { ]) .unwrap(), storage, - mock_account_code(), + code, ZERO, ); @@ -983,12 +977,30 @@ fn insert_transactions(conn: &mut Connection) -> usize { count } -pub fn mock_account_code() -> AccountCode { - let account_code = "\ - export.account_procedure_1 - push.1.2 - add - end - "; - AccountCode::compile(account_code, TransactionKernel::assembler(), false).unwrap() +fn mock_account_code_and_storage(account_type: AccountType) -> (AccountCode, AccountStorage) { + let component_code = "\ + export.account_procedure_1 + push.1.2 + add + end + "; + + let component_storage = vec![ + StorageSlot::Value(Word::default()), + StorageSlot::Value(num_to_word(1)), + StorageSlot::Value(Word::default()), + StorageSlot::Value(num_to_word(3)), + StorageSlot::Value(Word::default()), + StorageSlot::Value(num_to_word(5)), + ]; + + let component = AccountComponent::compile( + component_code, + TransactionKernel::testing_assembler(), + component_storage, + ) + .unwrap() + .with_supported_type(account_type); + + Account::initialize_from_components(account_type, &[component]).unwrap() } From 8865f4c4e3bf58b7754f608f8fa9c9ec82e13d51 Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Tue, 5 Nov 2024 16:01:27 +0500 Subject: [PATCH 33/37] refactor(node): improve `ApplyBlockError` variants in the store (#535) * refactor: improve `ApplyBlockErrors` variants * docs: update `CHANGELOG.md` * refactor: address review comments --- CHANGELOG.md | 1 + crates/store/src/db/mod.rs | 4 +- crates/store/src/db/sql.rs | 4 +- crates/store/src/errors.rs | 147 +++++++++++++++++++-------------- crates/store/src/server/api.rs | 3 +- crates/store/src/state.rs | 43 ++++++---- 6 files changed, 117 insertions(+), 85 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed2ecf837..8f5a7ef48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - [BREAKING] Migrated to v0.11 version of Miden VM (#528). - Reduce cloning in the store's `apply_block` (#532). - [BREAKING] Changed faucet storage type in the genesis to public. Using faucet from the genesis for faucet web app. Added support for faucet restarting without blockchain restarting (#517). +- [BREAKING] Improved `ApplyBlockError` in the store (#535). ## 0.5.1 (2024-09-12) diff --git a/crates/store/src/db/mod.rs b/crates/store/src/db/mod.rs index 6e04e67b1..45c462cf4 100644 --- a/crates/store/src/db/mod.rs +++ b/crates/store/src/db/mod.rs @@ -443,9 +443,7 @@ impl Db { )?; let _ = allow_acquire.send(()); - acquire_done - .blocking_recv() - .map_err(DatabaseError::ApplyBlockFailedClosedChannel)?; + acquire_done.blocking_recv()?; transaction.commit()?; diff --git a/crates/store/src/db/sql.rs b/crates/store/src/db/sql.rs index 9980f40dd..8320f0db4 100644 --- a/crates/store/src/db/sql.rs +++ b/crates/store/src/db/sql.rs @@ -254,7 +254,7 @@ pub fn upsert_accounts( debug_assert_eq!(account_id, u64::from(account.id())); if account.hash() != update.new_state_hash() { - return Err(DatabaseError::ApplyBlockFailedAccountHashesMismatch { + return Err(DatabaseError::AccountHashesMismatch { calculated: account.hash(), expected: update.new_state_hash(), }); @@ -1151,7 +1151,7 @@ fn apply_delta( let actual_hash = account.hash(); if &actual_hash != final_state_hash { - return Err(DatabaseError::ApplyBlockFailedAccountHashesMismatch { + return Err(DatabaseError::AccountHashesMismatch { calculated: actual_hash, expected: *final_state_hash, }); diff --git a/crates/store/src/errors.rs b/crates/store/src/errors.rs index 700c9d3c5..bb563c36a 100644 --- a/crates/store/src/errors.rs +++ b/crates/store/src/errors.rs @@ -37,50 +37,56 @@ pub enum NullifierTreeError { #[derive(Debug, Error)] pub enum DatabaseError { - #[error("Missing database connection: {0}")] - MissingDbConnection(#[from] PoolError), - #[error("SQLite error: {0}")] - SqliteError(#[from] rusqlite::Error), - #[error("SQLite error: {0}")] - FromSqlError(#[from] FromSqlError), - #[error("Hex parsing error: {0}")] - FromHexError(#[from] hex::FromHexError), - #[error("I/O error: {0}")] - IoError(#[from] io::Error), + // ERRORS WITH AUTOMATIC CONVERSIONS FROM NESTED ERROR TYPES + // --------------------------------------------------------------------------------------------- #[error("Account error: {0}")] AccountError(#[from] AccountError), - #[error("Block error: {0}")] - BlockError(#[from] BlockError), - #[error("Note error: {0}")] - NoteError(#[from] NoteError), - #[error("Migration error: {0}")] - MigrationError(#[from] rusqlite_migration::Error), #[error("Account delta error: {0}")] AccountDeltaError(#[from] AccountDeltaError), - #[error("SQLite pool interaction task failed: {0}")] - InteractError(String), + #[error("Block error: {0}")] + BlockError(#[from] BlockError), + #[error("Closed channel: {0}")] + ClosedChannel(#[from] RecvError), #[error("Deserialization of BLOB data from database failed: {0}")] DeserializationError(DeserializationError), - #[error("Invalid Felt: {0}")] - InvalidFelt(String), - #[error("Block applying was broken because of closed channel on state side: {0}")] - ApplyBlockFailedClosedChannel(RecvError), + #[error("Hex parsing error: {0}")] + FromHexError(#[from] hex::FromHexError), + #[error("SQLite error: {0}")] + FromSqlError(#[from] FromSqlError), + #[error("I/O error: {0}")] + IoError(#[from] io::Error), + #[error("Migration error: {0}")] + MigrationError(#[from] rusqlite_migration::Error), + #[error("Missing database connection: {0}")] + MissingDbConnection(#[from] PoolError), + #[error("Note error: {0}")] + NoteError(#[from] NoteError), + #[error("SQLite error: {0}")] + SqliteError(#[from] rusqlite::Error), + + // OTHER ERRORS + // --------------------------------------------------------------------------------------------- + #[error("Account hashes mismatch (expected {expected}, but calculated is {calculated})")] + AccountHashesMismatch { + expected: RpoDigest, + calculated: RpoDigest, + }, #[error("Account {0} not found in the database")] AccountNotFoundInDb(AccountId), #[error("Accounts {0:?} not found in the database")] AccountsNotFoundInDb(Vec), #[error("Account {0} is not on the chain")] AccountNotOnChain(AccountId), - #[error("Failed to apply block because of public account final hashes mismatch (expected {expected}, \ - but calculated is {calculated}")] - ApplyBlockFailedAccountHashesMismatch { - expected: RpoDigest, - calculated: RpoDigest, - }, #[error("Block {0} not found in the database")] BlockNotFoundInDb(BlockNumber), - #[error("Unsupported database version. There is no migration chain from/to this version. Remove database files \ - and try again.")] + #[error("SQLite pool interaction task failed: {0}")] + InteractError(String), + #[error("Invalid Felt: {0}")] + InvalidFelt(String), + #[error( + "Unsupported database version. There is no migration chain from/to this version. \ + Remove all database files and try again." + )] UnsupportedDatabaseVersion, } @@ -132,12 +138,17 @@ pub enum DatabaseSetupError { #[derive(Debug, Error)] pub enum GenesisError { + // ERRORS WITH AUTOMATIC CONVERSIONS FROM NESTED ERROR TYPES + // --------------------------------------------------------------------------------------------- #[error("Database error: {0}")] DatabaseError(#[from] DatabaseError), #[error("Block error: {0}")] BlockError(#[from] BlockError), #[error("Merkle error: {0}")] MerkleError(#[from] MerkleError), + + // OTHER ERRORS + // --------------------------------------------------------------------------------------------- #[error("Apply block failed: {0}")] ApplyBlockFailed(String), #[error("Failed to read genesis file \"{genesis_filepath}\": {error}")] @@ -145,58 +156,74 @@ pub enum GenesisError { genesis_filepath: String, error: io::Error, }, - #[error("Failed to deserialize genesis file: {0}")] - GenesisFileDeserializationError(DeserializationError), #[error("Block header in store doesn't match block header in genesis file. Expected {expected_genesis_header:?}, but store contained {block_header_in_store:?}")] GenesisBlockHeaderMismatch { expected_genesis_header: Box, block_header_in_store: Box, }, + #[error("Failed to deserialize genesis file: {0}")] + GenesisFileDeserializationError(DeserializationError), #[error("Retrieving genesis block header failed: {0}")] SelectBlockHeaderByBlockNumError(Box), } // ENDPOINT ERRORS // ================================================================================================= +#[derive(Error, Debug)] +pub enum InvalidBlockError { + #[error("Duplicated nullifiers {0:?}")] + DuplicatedNullifiers(Vec), + #[error("Invalid output note type: {0:?}")] + InvalidOutputNoteType(Box), + #[error("Invalid tx hash: expected {expected}, but got {actual}")] + InvalidTxHash { expected: RpoDigest, actual: RpoDigest }, + #[error("Received invalid account tree root")] + NewBlockInvalidAccountRoot, + #[error("New block number must be 1 greater than the current block number")] + NewBlockInvalidBlockNum, + #[error("New block chain root is not consistent with chain MMR")] + NewBlockInvalidChainRoot, + #[error("Received invalid note root")] + NewBlockInvalidNoteRoot, + #[error("Received invalid nullifier root")] + NewBlockInvalidNullifierRoot, + #[error("New block `prev_hash` must match the chain's tip")] + NewBlockInvalidPrevHash, +} #[derive(Error, Debug)] pub enum ApplyBlockError { + // ERRORS WITH AUTOMATIC CONVERSIONS FROM NESTED ERROR TYPES + // --------------------------------------------------------------------------------------------- #[error("Database error: {0}")] DatabaseError(#[from] DatabaseError), #[error("I/O error: {0}")] IoError(#[from] io::Error), #[error("Task join error: {0}")] TokioJoinError(#[from] tokio::task::JoinError), + #[error("Invalid block error: {0}")] + InvalidBlockError(#[from] InvalidBlockError), + + // OTHER ERRORS + // --------------------------------------------------------------------------------------------- + #[error("Block applying was cancelled because of closed channel on database side: {0}")] + ClosedChannel(RecvError), #[error("Concurrent write detected")] ConcurrentWrite, - #[error("New block number must be 1 greater than the current block number")] - NewBlockInvalidBlockNum, - #[error("New block `prev_hash` must match the chain's tip")] - NewBlockInvalidPrevHash, - #[error("New block chain root is not consistent with chain MMR")] - NewBlockInvalidChainRoot, - #[error("Received invalid account tree root")] - NewBlockInvalidAccountRoot, - #[error("Received invalid note root")] - NewBlockInvalidNoteRoot, - #[error("Received invalid nullifier root")] - NewBlockInvalidNullifierRoot, - #[error("Duplicated nullifiers {0:?}")] - DuplicatedNullifiers(Vec), - #[error("Block applying was broken because of closed channel on database side: {0}")] - BlockApplyingBrokenBecauseOfClosedChannel(RecvError), - #[error("Failed to create notes tree: {0}")] - FailedToCreateNoteTree(MerkleError), #[error("Database doesn't have any block header data")] DbBlockHeaderEmpty, - #[error("Failed to get MMR peaks for forest ({forest}): {error}")] - FailedToGetMmrPeaksForForest { forest: usize, error: MmrError }, - #[error("Failed to update nullifier tree: {0}")] - FailedToUpdateNullifierTree(NullifierTreeError), - #[error("Invalid output note type: {0:?}")] - InvalidOutputNoteType(OutputNote), - #[error("Invalid tx hash: expected {expected}, but got {actual}")] - InvalidTxHash { expected: RpoDigest, actual: RpoDigest }, + #[error("Database update task failed: {0}")] + DbUpdateTaskFailed(String), +} + +impl From for Status { + fn from(err: ApplyBlockError) -> Self { + match err { + ApplyBlockError::InvalidBlockError(_) => Status::invalid_argument(err.to_string()), + + _ => Status::internal(err.to_string()), + } + } } #[derive(Error, Debug)] @@ -209,10 +236,10 @@ pub enum GetBlockHeaderError { #[derive(Error, Debug)] pub enum GetBlockInputsError { - #[error("Database error: {0}")] - DatabaseError(#[from] DatabaseError), #[error("Account error: {0}")] AccountError(#[from] AccountError), + #[error("Database error: {0}")] + DatabaseError(#[from] DatabaseError), #[error("Database doesn't have any block header data")] DbBlockHeaderEmpty, #[error("Failed to get MMR peaks for forest ({forest}): {error}")] diff --git a/crates/store/src/server/api.rs b/crates/store/src/server/api.rs index bd741575c..3b6db4bd1 100644 --- a/crates/store/src/server/api.rs +++ b/crates/store/src/server/api.rs @@ -369,8 +369,7 @@ impl api_server::Api for StoreApi { nullifier_count = block.nullifiers().len(), ); - // TODO: Why the error is swallowed here? Fix or add a comment with explanation. - let _ = self.state.apply_block(block).await; + self.state.apply_block(block).await?; Ok(Response::new(ApplyBlockResponse {})) } diff --git a/crates/store/src/state.rs b/crates/store/src/state.rs index 3ff4c4197..174ac68e0 100644 --- a/crates/store/src/state.rs +++ b/crates/store/src/state.rs @@ -41,13 +41,13 @@ use crate::{ db::{Db, NoteRecord, NoteSyncUpdate, NullifierInfo, StateSyncUpdate}, errors::{ ApplyBlockError, DatabaseError, GetBlockHeaderError, GetBlockInputsError, - GetNoteInclusionProofError, NoteSyncError, StateInitializationError, StateSyncError, + GetNoteInclusionProofError, InvalidBlockError, NoteSyncError, StateInitializationError, + StateSyncError, }, nullifier_tree::NullifierTree, types::{AccountId, BlockNumber}, COMPONENT, }; - // STRUCTURES // ================================================================================================ @@ -173,10 +173,11 @@ impl State { let tx_hash = block.compute_tx_hash(); if header.tx_hash() != tx_hash { - return Err(ApplyBlockError::InvalidTxHash { + return Err(InvalidBlockError::InvalidTxHash { expected: tx_hash, actual: header.tx_hash(), - }); + } + .into()); } let block_num = header.block_num(); @@ -190,10 +191,10 @@ impl State { .ok_or(ApplyBlockError::DbBlockHeaderEmpty)?; if block_num != prev_block.block_num() + 1 { - return Err(ApplyBlockError::NewBlockInvalidBlockNum); + return Err(InvalidBlockError::NewBlockInvalidBlockNum.into()); } if header.prev_hash() != prev_block.hash() { - return Err(ApplyBlockError::NewBlockInvalidPrevHash); + return Err(InvalidBlockError::NewBlockInvalidPrevHash.into()); } let block_data = block.to_bytes(); @@ -227,7 +228,7 @@ impl State { .cloned() .collect(); if !duplicate_nullifiers.is_empty() { - return Err(ApplyBlockError::DuplicatedNullifiers(duplicate_nullifiers)); + return Err(InvalidBlockError::DuplicatedNullifiers(duplicate_nullifiers).into()); } // compute updates for the in-memory data structures @@ -235,7 +236,7 @@ impl State { // new_block.chain_root must be equal to the chain MMR root prior to the update let peaks = inner.chain_mmr.peaks(); if peaks.hash_peaks() != header.chain_root() { - return Err(ApplyBlockError::NewBlockInvalidChainRoot); + return Err(InvalidBlockError::NewBlockInvalidChainRoot.into()); } // compute update for nullifier tree @@ -244,7 +245,7 @@ impl State { ); if nullifier_tree_update.root() != header.nullifier_root() { - return Err(ApplyBlockError::NewBlockInvalidNullifierRoot); + return Err(InvalidBlockError::NewBlockInvalidNullifierRoot.into()); } // compute update for account tree @@ -258,7 +259,7 @@ impl State { ); if account_tree_update.root() != header.account_root() { - return Err(ApplyBlockError::NewBlockInvalidAccountRoot); + return Err(InvalidBlockError::NewBlockInvalidAccountRoot.into()); } ( @@ -272,7 +273,7 @@ impl State { // build note tree let note_tree = block.build_note_tree(); if note_tree.root() != header.note_root() { - return Err(ApplyBlockError::NewBlockInvalidNoteRoot); + return Err(InvalidBlockError::NewBlockInvalidNoteRoot.into()); } let notes = block @@ -281,7 +282,11 @@ impl State { let details = match note { OutputNote::Full(note) => Some(note.to_bytes()), OutputNote::Header(_) => None, - note => return Err(ApplyBlockError::InvalidOutputNoteType(note.clone())), + note => { + return Err(InvalidBlockError::InvalidOutputNoteType(Box::new( + note.clone(), + ))) + }, }; let merkle_path = note_tree.get_note_path(note_index); @@ -295,7 +300,7 @@ impl State { merkle_path, }) }) - .collect::, ApplyBlockError>>()?; + .collect::, InvalidBlockError>>()?; // Signals the transaction is ready to be committed, and the write lock can be acquired let (allow_acquire, acquired_allowed) = oneshot::channel::<()>(); @@ -313,9 +318,7 @@ impl State { ); // Wait for the message from the DB update task, that we ready to commit the DB transaction - acquired_allowed - .await - .map_err(ApplyBlockError::BlockApplyingBrokenBecauseOfClosedChannel)?; + acquired_allowed.await.map_err(ApplyBlockError::ClosedChannel)?; // Awaiting the block saving task to complete without errors block_save_task.await??; @@ -339,13 +342,17 @@ impl State { // Notify the DB update task that the write lock has been acquired, so it can commit // the DB transaction - let _ = inform_acquire_done.send(()); + inform_acquire_done + .send(()) + .map_err(|_| ApplyBlockError::DbUpdateTaskFailed("Receiver was dropped".into()))?; // TODO: shutdown #91 // Await for successful commit of the DB transaction. If the commit fails, we mustn't // change in-memory state, so we return a block applying error and don't proceed with // in-memory updates. - db_update_task.await??; + db_update_task + .await? + .map_err(|err| ApplyBlockError::DbUpdateTaskFailed(err.to_string()))?; // Update the in-memory data structures after successful commit of the DB transaction inner From abed5406e3a2cc8bd4943734c29858f962f95fa4 Mon Sep 17 00:00:00 2001 From: igamigo Date: Tue, 5 Nov 2024 17:53:05 -0300 Subject: [PATCH 34/37] fix: Return correct latest block number (#545) * Update state.rs * docs: Update expect() * chore: Lints --- crates/store/src/state.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/store/src/state.rs b/crates/store/src/state.rs index 174ac68e0..597219dac 100644 --- a/crates/store/src/state.rs +++ b/crates/store/src/state.rs @@ -99,7 +99,9 @@ struct InnerState { impl InnerState { /// Returns the latest block number. fn latest_block_num(&self) -> BlockNumber { - (self.chain_mmr.forest() + 1).try_into().expect("block number overflow") + (self.chain_mmr.forest() - 1) + .try_into() + .expect("chain_mmr always has, at least, the genesis block") } } From 6e6f1e210a5bc8182a7480a5445e440d62ec4a58 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Tue, 5 Nov 2024 13:19:56 -0800 Subject: [PATCH 35/37] chore: update to the latest versions of miden-base crates --- Cargo.lock | 10 +++++----- bin/node/Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f3bdaec30..da702879d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -395,9 +395,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.34" +version = "1.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9" +checksum = "0f57c4b4da2a9d619dd035f27316d7a426305b75be93d09e92f2b9229c34feaf" dependencies = [ "jobserver", "libc", @@ -1511,7 +1511,7 @@ dependencies = [ [[package]] name = "miden-lib" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#ff3c5227c5962cc97cd44562f134b0a545be21cc" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#804da570c00c4a6a2ef48598c05cb7f3a191f4c0" dependencies = [ "miden-assembly", "miden-objects", @@ -1707,7 +1707,7 @@ dependencies = [ [[package]] name = "miden-objects" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#ff3c5227c5962cc97cd44562f134b0a545be21cc" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#804da570c00c4a6a2ef48598c05cb7f3a191f4c0" dependencies = [ "getrandom", "miden-assembly", @@ -1780,7 +1780,7 @@ dependencies = [ [[package]] name = "miden-tx" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#ff3c5227c5962cc97cd44562f134b0a545be21cc" +source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#804da570c00c4a6a2ef48598c05cb7f3a191f4c0" dependencies = [ "async-trait", "miden-assembly", diff --git a/bin/node/Cargo.toml b/bin/node/Cargo.toml index b855cbe64..d2d9b5d91 100644 --- a/bin/node/Cargo.toml +++ b/bin/node/Cargo.toml @@ -14,7 +14,7 @@ repository.workspace = true [features] # Makes `make-genesis` subcommand run faster. Is only suitable for testing. # INFO: Make sure that all your components have matching features for them to function. -testing = ["miden-lib/testing"] +testing = ["miden-lib/testing", "miden-objects/testing"] tracing-forest = ["miden-node-block-producer/tracing-forest"] [dependencies] From 857b757799c7489aebee3573d156255edf2dcf55 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Tue, 5 Nov 2024 18:26:45 -0800 Subject: [PATCH 36/37] chore: update miden-base dependencies to crates.io versions --- Cargo.lock | 9 ++++++--- Cargo.toml | 6 +++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index da702879d..6dff0370d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1511,7 +1511,8 @@ dependencies = [ [[package]] name = "miden-lib" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#804da570c00c4a6a2ef48598c05cb7f3a191f4c0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "816404c10b0799f12d3b53b3a9baa9af99fa340fe1a579e0919bba57718fa97a" dependencies = [ "miden-assembly", "miden-objects", @@ -1707,7 +1708,8 @@ dependencies = [ [[package]] name = "miden-objects" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#804da570c00c4a6a2ef48598c05cb7f3a191f4c0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a6f54dde939928e438488b36651485a0e80057025b7e30343d4340a524a1651" dependencies = [ "getrandom", "miden-assembly", @@ -1780,7 +1782,8 @@ dependencies = [ [[package]] name = "miden-tx" version = "0.6.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#804da570c00c4a6a2ef48598c05cb7f3a191f4c0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d433744a3f02233ec53b151bfe88b7a008b4eae5dfd41bb38a9889eb67efaf7" dependencies = [ "async-trait", "miden-assembly", diff --git a/Cargo.toml b/Cargo.toml index bcd59f59d..ce5eb685e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ readme = "README.md" [workspace.dependencies] miden-air = { version = "0.11" } -miden-lib = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } +miden-lib = { version = "0.6" } miden-node-block-producer = { path = "crates/block-producer", version = "0.6" } miden-node-faucet = { path = "bin/faucet", version = "0.6" } miden-node-proto = { path = "crates/proto", version = "0.6" } @@ -35,10 +35,10 @@ miden-node-rpc-proto = { path = "crates/rpc-proto", version = "0.6" } miden-node-store = { path = "crates/store", version = "0.6" } miden-node-test-macro = { path = "crates/test-macro" } miden-node-utils = { path = "crates/utils", version = "0.6" } -miden-objects = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } +miden-objects = { version = "0.6"} miden-processor = { version = "0.11" } miden-stdlib = { version = "0.11", default-features = false } -miden-tx = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } +miden-tx = { version = "0.6"} prost = { version = "0.13" } rand = { version = "0.8" } thiserror = { version = "1.0" } From f05a40c14856b4048ca944cac15508d81229e5bb Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Tue, 5 Nov 2024 18:32:12 -0800 Subject: [PATCH 37/37] chore: update changelog --- CHANGELOG.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f5a7ef48..ed4c12a1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,13 @@ # Changelog -## v0.6.0 (TBD) +## v0.6.0 (2024-11-05) + +### Enhancements + +- Added `GetAccountProofs` endpoint (#506). + +### Changes -- Added `AccountCode` as part of `GetAccountProofs` endpoint response (#521). - [BREAKING] Added `kernel_root` to block header's protobuf message definitions (#496). - [BREAKING] Renamed `off-chain` and `on-chain` to `private` and `public` respectively for the account storage modes (#489). - Optimized state synchronizations by removing unnecessary fetching and parsing of note details (#462). @@ -10,10 +15,10 @@ - Improve `--version` by adding build metadata (#495). - [BREAKING] Introduced additional limits for note/account number (#503). - [BREAKING] Removed support for basic wallets in genesis creation (#510). -- Added `GetAccountProofs` endpoint (#506). - Migrated faucet from actix-web to axum (#511). - Changed the `BlockWitness` to pass the inputs to the VM using only advice provider (#516). - [BREAKING] Improved store API errors (return "not found" instead of "internal error" status if requested account(s) not found) (#518). +- Added `AccountCode` as part of `GetAccountProofs` endpoint response (#521). - [BREAKING] Migrated to v0.11 version of Miden VM (#528). - Reduce cloning in the store's `apply_block` (#532). - [BREAKING] Changed faucet storage type in the genesis to public. Using faucet from the genesis for faucet web app. Added support for faucet restarting without blockchain restarting (#517).