From 12701209f149638ff91371f3b0f679f874f37364 Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Fri, 5 Apr 2024 15:12:01 +0500 Subject: [PATCH] On-chain accounts protobuf & domain objects (#287) * feat: add `account_details` table to the DB * refactor: rename `block_number` column in nullifiers table to `block_num` * refactor: use `BETWEEN` in interval comparison checks * feat: implement account details protobuf messages, domain objects and conversions * feat: (WIP) implement account details support * feat: (WIP) implement account details support * feat: (WIP) implement account details support * feat: (WIP) implement account details support * fix: db creation * docs: remove TODO * refactor: apply formatting * feat: implement endpoint for getting public account details * tests: add test for storage * feat: add rpc endpoint for getting account details * refactor: keep only domain object changes * fix: compilation errors * fix: use note tag conversion from `u64` * refactor: remove account details protobuf messages * fix: remove unused error invariants * refactor: introduce `UpdatedAccount` struct * fix: rollback details conversion * fix: compilation error * format: reformat using rustfmt --- .gitignore | 9 ++- block-producer/src/batch_builder/batch.rs | 9 ++- block-producer/src/block.rs | 9 +-- block-producer/src/block_builder/mod.rs | 6 +- .../src/block_builder/prover/block_witness.rs | 41 ++++++++------ .../src/block_builder/prover/tests.rs | 7 ++- block-producer/src/block_builder/tests.rs | 12 +++- block-producer/src/errors.rs | 8 +-- block-producer/src/state_view/mod.rs | 11 +--- .../src/state_view/tests/apply_block.rs | 20 ++++++- block-producer/src/store/mod.rs | 6 +- block-producer/src/test_utils/block.rs | 23 ++++---- block-producer/src/test_utils/store.rs | 4 +- proto/src/domain/accounts.rs | 56 +++++++++++-------- proto/src/domain/blocks.rs | 6 +- proto/src/domain/digest.rs | 18 +++--- proto/src/domain/merkle.rs | 14 ++--- proto/src/domain/nullifiers.rs | 6 +- proto/src/errors.rs | 12 ++-- store/src/server/api.rs | 12 ++-- 20 files changed, 167 insertions(+), 122 deletions(-) diff --git a/.gitignore b/.gitignore index 4cc60b600..b3359a675 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,11 @@ target/ # VS Code .vscode/ +# JetBrains IDEs +.idea/ +.code/ +.fleet/ + # Genesis files /accounts genesis.dat @@ -26,12 +31,10 @@ genesis.dat *.sqlite3-wal # Docs ignore -.code -.idea site/ venv/ env/ *.out node_modules/ *DS_Store -*.iml +*.iml \ No newline at end of file diff --git a/block-producer/src/batch_builder/batch.rs b/block-producer/src/batch_builder/batch.rs index 864948cec..b5784c433 100644 --- a/block-producer/src/batch_builder/batch.rs +++ b/block-producer/src/batch_builder/batch.rs @@ -1,5 +1,6 @@ use std::collections::BTreeMap; +use miden_node_proto::domain::accounts::UpdatedAccount; use miden_objects::{ accounts::AccountId, batches::BatchNoteTree, @@ -108,10 +109,14 @@ impl TransactionBatch { /// Returns an iterator over (account_id, new_state_hash) tuples for accounts that were /// modified in this transaction batch. - pub fn updated_accounts(&self) -> impl Iterator + '_ { + pub fn updated_accounts(&self) -> impl Iterator + '_ { self.updated_accounts .iter() - .map(|(account_id, account_states)| (*account_id, account_states.final_state)) + .map(|(&account_id, account_states)| UpdatedAccount { + account_id, + final_state_hash: account_states.final_state, + details: None, // TODO: In the next PR: account_states.details.clone(), + }) } /// Returns an iterator over produced nullifiers for all consumed notes. diff --git a/block-producer/src/block.rs b/block-producer/src/block.rs index cfc026aee..6e43674c5 100644 --- a/block-producer/src/block.rs +++ b/block-producer/src/block.rs @@ -1,7 +1,8 @@ use std::collections::BTreeMap; use miden_node_proto::{ - errors::{MissingFieldHelper, ParseError}, + domain::accounts::UpdatedAccount, + errors::{ConversionError, MissingFieldHelper}, generated::responses::GetBlockInputsResponse, AccountInputRecord, NullifierWitness, }; @@ -17,7 +18,7 @@ use crate::store::BlockInputsError; #[derive(Debug, Clone)] pub struct Block { pub header: BlockHeader, - pub updated_accounts: Vec<(AccountId, Digest)>, + pub updated_accounts: Vec, pub created_notes: Vec<(usize, usize, NoteEnvelope)>, pub produced_nullifiers: Vec, // TODO: @@ -94,7 +95,7 @@ impl TryFrom for BlockInputs { }; Ok((domain.account_id, witness)) }) - .collect::, ParseError>>()?; + .collect::, ConversionError>>()?; let nullifiers = get_block_inputs .nullifiers @@ -103,7 +104,7 @@ impl TryFrom for BlockInputs { let witness: NullifierWitness = entry.try_into()?; Ok((witness.nullifier, witness.proof)) }) - .collect::, ParseError>>()?; + .collect::, ConversionError>>()?; Ok(Self { block_header, diff --git a/block-producer/src/block_builder/mod.rs b/block-producer/src/block_builder/mod.rs index 615b687e3..cb0502528 100644 --- a/block-producer/src/block_builder/mod.rs +++ b/block-producer/src/block_builder/mod.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use async_trait::async_trait; use miden_node_utils::formatting::{format_array, format_blake3_digest}; -use miden_objects::{accounts::AccountId, notes::Nullifier, Digest}; +use miden_objects::notes::Nullifier; use tracing::{debug, info, instrument}; use crate::{ @@ -77,7 +77,7 @@ where batches = %format_array(batches.iter().map(|batch| format_blake3_digest(batch.id()))), ); - let updated_accounts: Vec<(AccountId, Digest)> = + let updated_accounts: Vec<_> = batches.iter().flat_map(TransactionBatch::updated_accounts).collect(); let created_notes = batches .iter() @@ -95,7 +95,7 @@ where let block_inputs = self .store .get_block_inputs( - updated_accounts.iter().map(|(account_id, _)| account_id), + updated_accounts.iter().map(|update| &update.account_id), produced_nullifiers.iter(), ) .await?; diff --git a/block-producer/src/block_builder/prover/block_witness.rs b/block-producer/src/block_builder/prover/block_witness.rs index ba7e7f6a5..c72c84ddc 100644 --- a/block-producer/src/block_builder/prover/block_witness.rs +++ b/block-producer/src/block_builder/prover/block_witness.rs @@ -1,5 +1,6 @@ use std::collections::{BTreeMap, BTreeSet}; +use miden_node_proto::domain::accounts::UpdatedAccount; use miden_objects::{ accounts::AccountId, crypto::merkle::{EmptySubtreeRoots, MerklePath, MerkleStore, MmrPeaks, SmtProof}, @@ -48,23 +49,29 @@ impl BlockWitness { batches .iter() .flat_map(|batch| batch.updated_accounts()) - .map(|(account_id, final_state_hash)| { - let initial_state_hash = account_initial_states - .remove(&account_id) - .expect("already validated that key exists"); - let proof = account_merkle_proofs - .remove(&account_id) - .expect("already validated that key exists"); - - ( - account_id, - AccountUpdate { - initial_state_hash, - final_state_hash, - proof, - }, - ) - }) + .map( + |UpdatedAccount { + account_id, + final_state_hash, + .. + }| { + let initial_state_hash = account_initial_states + .remove(&account_id) + .expect("already validated that key exists"); + let proof = account_merkle_proofs + .remove(&account_id) + .expect("already validated that key exists"); + + ( + account_id, + AccountUpdate { + initial_state_hash, + final_state_hash, + proof, + }, + ) + }, + ) .collect() }; diff --git a/block-producer/src/block_builder/prover/tests.rs b/block-producer/src/block_builder/prover/tests.rs index 5c698cfa0..3869064d1 100644 --- a/block-producer/src/block_builder/prover/tests.rs +++ b/block-producer/src/block_builder/prover/tests.rs @@ -1,5 +1,6 @@ use std::{collections::BTreeMap, iter}; +use miden_node_proto::domain::accounts::UpdatedAccount; use miden_objects::{ accounts::AccountId, crypto::merkle::{ @@ -235,7 +236,11 @@ async fn test_compute_account_root_success() { account_ids .iter() .zip(account_final_states.iter()) - .map(|(&account_id, &account_hash)| (account_id, account_hash.into())) + .map(|(&account_id, &account_hash)| UpdatedAccount { + account_id, + final_state_hash: account_hash.into(), + details: None, + }) .collect(), ) .build(); diff --git a/block-producer/src/block_builder/tests.rs b/block-producer/src/block_builder/tests.rs index bb2e4b985..df3ce2f2b 100644 --- a/block-producer/src/block_builder/tests.rs +++ b/block-producer/src/block_builder/tests.rs @@ -1,9 +1,15 @@ // block builder tests (higher level) // `apply_block()` is called -use miden_objects::Felt; -use super::*; -use crate::test_utils::{MockProvenTxBuilder, MockStoreFailure, MockStoreSuccessBuilder}; +use std::sync::Arc; + +use miden_objects::{accounts::AccountId, Digest, Felt}; + +use crate::{ + batch_builder::TransactionBatch, + block_builder::{BlockBuilder, BuildBlockError, DefaultBlockBuilder}, + test_utils::{MockProvenTxBuilder, MockStoreFailure, MockStoreSuccessBuilder}, +}; /// Tests that `build_block()` succeeds when the transaction batches are not empty #[tokio::test] diff --git a/block-producer/src/errors.rs b/block-producer/src/errors.rs index e8cc22dd2..8242f2b92 100644 --- a/block-producer/src/errors.rs +++ b/block-producer/src/errors.rs @@ -1,4 +1,4 @@ -use miden_node_proto::errors::ParseError; +use miden_node_proto::errors::ConversionError; use miden_node_utils::formatting::format_opt; use miden_objects::{ accounts::AccountId, @@ -101,7 +101,7 @@ pub enum BlockProverError { #[derive(Debug, PartialEq, Eq, Error)] pub enum BlockInputsError { #[error("failed to parse protobuf message: {0}")] - ParseError(#[from] ParseError), + ConversionError(#[from] ConversionError), #[error("MmrPeaks error: {0}")] MmrPeaksError(#[from] MmrError), #[error("gRPC client failed with error: {0}")] @@ -113,8 +113,6 @@ pub enum BlockInputsError { #[derive(Debug, PartialEq, Eq, Error)] pub enum ApplyBlockError { - #[error("Merkle error: {0}")] - MerkleError(#[from] MerkleError), #[error("gRPC client failed with error: {0}")] GrpcClientError(String), } @@ -153,7 +151,7 @@ pub enum TxInputsError { #[error("malformed response from store: {0}")] MalformedResponse(String), #[error("failed to parse protobuf message: {0}")] - ParseError(#[from] ParseError), + ConversionError(#[from] ConversionError), #[error("dummy")] Dummy, } diff --git a/block-producer/src/state_view/mod.rs b/block-producer/src/state_view/mod.rs index bafbf4e2d..8af9ebff6 100644 --- a/block-producer/src/state_view/mod.rs +++ b/block-producer/src/state_view/mod.rs @@ -127,18 +127,13 @@ where let mut locked_nullifiers_in_flight = self.nullifiers_in_flight.write().await; // Remove account ids of transactions in block - let account_ids_in_block = block - .updated_accounts - .iter() - .map(|(account_id, _final_account_hash)| account_id); - - for account_id in account_ids_in_block { - let was_in_flight = locked_accounts_in_flight.remove(account_id); + for update in &block.updated_accounts { + let was_in_flight = locked_accounts_in_flight.remove(&update.account_id); debug_assert!(was_in_flight); } // Remove new nullifiers of transactions in block - for nullifier in block.produced_nullifiers.iter() { + for nullifier in &block.produced_nullifiers { let was_in_flight = locked_nullifiers_in_flight.remove(nullifier); debug_assert!(was_in_flight); } diff --git a/block-producer/src/state_view/tests/apply_block.rs b/block-producer/src/state_view/tests/apply_block.rs index ac4a52348..0db199277 100644 --- a/block-producer/src/state_view/tests/apply_block.rs +++ b/block-producer/src/state_view/tests/apply_block.rs @@ -6,6 +6,8 @@ use std::iter; +use miden_node_proto::domain::accounts::UpdatedAccount; + use super::*; use crate::test_utils::{block::MockBlockBuilder, MockStoreSuccessBuilder}; @@ -32,7 +34,11 @@ async fn test_apply_block_ab1() { .await .account_updates( std::iter::once(account) - .map(|mock_account| (mock_account.id, mock_account.states[1])) + .map(|mock_account| UpdatedAccount { + account_id: mock_account.id, + final_state_hash: mock_account.states[1], + details: None, + }) .collect(), ) .build(); @@ -75,7 +81,11 @@ async fn test_apply_block_ab2() { .account_updates( accounts_in_block .into_iter() - .map(|mock_account| (mock_account.id, mock_account.states[1])) + .map(|mock_account| UpdatedAccount { + account_id: mock_account.id, + final_state_hash: mock_account.states[1], + details: None, + }) .collect(), ) .build(); @@ -120,7 +130,11 @@ async fn test_apply_block_ab3() { accounts .clone() .into_iter() - .map(|mock_account| (mock_account.id, mock_account.states[1])) + .map(|mock_account| UpdatedAccount { + account_id: mock_account.id, + final_state_hash: mock_account.states[1], + details: None, + }) .collect(), ) .build(); diff --git a/block-producer/src/store/mod.rs b/block-producer/src/store/mod.rs index 542c47d31..b02f9fa41 100644 --- a/block-producer/src/store/mod.rs +++ b/block-producer/src/store/mod.rs @@ -6,7 +6,7 @@ use std::{ use async_trait::async_trait; use miden_node_proto::{ convert, - errors::{MissingFieldHelper, ParseError}, + errors::{ConversionError, MissingFieldHelper}, generated::{ account, digest, requests::{ApplyBlockRequest, GetBlockInputsRequest, GetTransactionInputsRequest}, @@ -83,7 +83,7 @@ impl Display for TransactionInputs { } impl TryFrom for TransactionInputs { - type Error = ParseError; + type Error = ConversionError; fn try_from(response: GetTransactionInputsResponse) -> Result { let AccountState { @@ -135,7 +135,7 @@ impl ApplyBlock for DefaultStore { ) -> Result<(), ApplyBlockError> { let request = tonic::Request::new(ApplyBlockRequest { block: Some(block.header.into()), - accounts: convert(block.updated_accounts), + accounts: convert(&block.updated_accounts), nullifiers: convert(block.produced_nullifiers), notes: convert(block.created_notes), }); diff --git a/block-producer/src/test_utils/block.rs b/block-producer/src/test_utils/block.rs index 5bfd2c00f..02c8a28cd 100644 --- a/block-producer/src/test_utils/block.rs +++ b/block-producer/src/test_utils/block.rs @@ -1,5 +1,5 @@ +use miden_node_proto::domain::accounts::UpdatedAccount; use miden_objects::{ - accounts::AccountId, block::BlockNoteTree, crypto::merkle::{Mmr, SimpleSmt}, notes::{NoteEnvelope, Nullifier}, @@ -23,12 +23,12 @@ pub async fn build_expected_block_header( let last_block_header = *store.last_block_header.read().await; // Compute new account root - let updated_accounts: Vec<(AccountId, Digest)> = + let updated_accounts: Vec<_> = batches.iter().flat_map(TransactionBatch::updated_accounts).collect(); let new_account_root = { let mut store_accounts = store.accounts.read().await.clone(); - for (account_id, new_account_state) in updated_accounts { - store_accounts.insert(account_id.into(), new_account_state.into()); + for update in updated_accounts { + store_accounts.insert(update.account_id.into(), update.final_state_hash.into()); } store_accounts.root() @@ -65,14 +65,14 @@ pub async fn build_actual_block_header( store: &MockStoreSuccess, batches: Vec, ) -> BlockHeader { - let updated_accounts: Vec<(AccountId, Digest)> = - batches.iter().flat_map(|batch| batch.updated_accounts()).collect(); + let updated_accounts: Vec<_> = + batches.iter().flat_map(TransactionBatch::updated_accounts).collect(); let produced_nullifiers: Vec = batches.iter().flat_map(|batch| batch.produced_nullifiers()).collect(); let block_inputs_from_store: BlockInputs = store .get_block_inputs( - updated_accounts.iter().map(|(account_id, _)| account_id), + updated_accounts.iter().map(|update| &update.account_id), produced_nullifiers.iter(), ) .await @@ -89,7 +89,7 @@ pub struct MockBlockBuilder { store_chain_mmr: Mmr, last_block_header: BlockHeader, - updated_accounts: Option>, + updated_accounts: Option>, created_notes: Option>, produced_nullifiers: Option>, } @@ -109,10 +109,11 @@ impl MockBlockBuilder { pub fn account_updates( mut self, - updated_accounts: Vec<(AccountId, Digest)>, + updated_accounts: Vec, ) -> Self { - for &(account_id, new_account_state) in updated_accounts.iter() { - self.store_accounts.insert(account_id.into(), new_account_state.into()); + for update in &updated_accounts { + self.store_accounts + .insert(update.account_id.into(), update.final_state_hash.into()); } self.updated_accounts = Some(updated_accounts); diff --git a/block-producer/src/test_utils/store.rs b/block-producer/src/test_utils/store.rs index 1fbb675e4..abd6cba22 100644 --- a/block-producer/src/test_utils/store.rs +++ b/block-producer/src/test_utils/store.rs @@ -181,8 +181,8 @@ impl ApplyBlock for MockStoreSuccess { let mut locked_produced_nullifiers = self.produced_nullifiers.write().await; // update accounts - for &(account_id, account_hash) in block.updated_accounts.iter() { - locked_accounts.insert(account_id.into(), account_hash.into()); + for update in &block.updated_accounts { + locked_accounts.insert(update.account_id.into(), update.final_state_hash.into()); } debug_assert_eq!(locked_accounts.root(), block.header.account_root()); diff --git a/proto/src/domain/accounts.rs b/proto/src/domain/accounts.rs index 2cc367018..9669fea75 100644 --- a/proto/src/domain/accounts.rs +++ b/proto/src/domain/accounts.rs @@ -1,12 +1,14 @@ use std::fmt::{Debug, Display, Formatter}; use miden_node_utils::formatting::format_opt; -use miden_objects::{accounts::AccountId, crypto::merkle::MerklePath, Digest}; +use miden_objects::{ + accounts::AccountId, crypto::merkle::MerklePath, transaction::AccountDetails, Digest, +}; use crate::{ - errors::{MissingFieldHelper, ParseError}, + errors::{ConversionError, MissingFieldHelper}, generated::{ - self, + account::AccountId as AccountIdPb, requests::AccountUpdate, responses::{AccountBlockInputRecord, AccountTransactionInputRecord}, }, @@ -15,7 +17,7 @@ use crate::{ // ACCOUNT ID // ================================================================================================ -impl Display for generated::account::AccountId { +impl Display for AccountIdPb { fn fmt( &self, f: &mut Formatter<'_>, @@ -24,7 +26,7 @@ impl Display for generated::account::AccountId { } } -impl Debug for generated::account::AccountId { +impl Debug for AccountIdPb { fn fmt( &self, f: &mut Formatter<'_>, @@ -36,13 +38,13 @@ impl Debug for generated::account::AccountId { // INTO PROTO ACCOUNT ID // ------------------------------------------------------------------------------------------------ -impl From for generated::account::AccountId { +impl From for AccountIdPb { fn from(value: u64) -> Self { - generated::account::AccountId { id: value } + AccountIdPb { id: value } } } -impl From for generated::account::AccountId { +impl From for AccountIdPb { fn from(account_id: AccountId) -> Self { Self { id: account_id.into(), @@ -53,28 +55,36 @@ impl From for generated::account::AccountId { // FROM PROTO ACCOUNT ID // ------------------------------------------------------------------------------------------------ -impl From for u64 { - fn from(value: generated::account::AccountId) -> Self { +impl From for u64 { + fn from(value: AccountIdPb) -> Self { value.id } } -impl TryFrom for AccountId { - type Error = ParseError; +impl TryFrom for AccountId { + type Error = ConversionError; - fn try_from(account_id: generated::account::AccountId) -> Result { - account_id.id.try_into().map_err(|_| ParseError::NotAValidFelt) + fn try_from(account_id: AccountIdPb) -> Result { + account_id.id.try_into().map_err(|_| ConversionError::NotAValidFelt) } } -// INTO ACCOUNT UPDATE +// ACCOUNT UPDATE // ================================================================================================ -impl From<(AccountId, Digest)> for AccountUpdate { - fn from((account_id, account_hash): (AccountId, Digest)) -> Self { +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct UpdatedAccount { + pub account_id: AccountId, + pub final_state_hash: Digest, + pub details: Option, +} + +impl From<&UpdatedAccount> for AccountUpdate { + fn from(update: &UpdatedAccount) -> Self { Self { - account_id: Some(account_id.into()), - account_hash: Some(account_hash.into()), + account_id: Some(update.account_id.into()), + account_hash: Some(update.final_state_hash.into()), + // details: update.details.to_bytes(), } } } @@ -100,7 +110,7 @@ impl From for AccountBlockInputRecord { } impl TryFrom for AccountInputRecord { - type Error = ParseError; + type Error = ConversionError; fn try_from(account_input_record: AccountBlockInputRecord) -> Result { Ok(Self { @@ -155,7 +165,7 @@ impl From for AccountTransactionInputRecord { } impl TryFrom for AccountState { - type Error = ParseError; + type Error = ConversionError; fn try_from(from: AccountTransactionInputRecord) -> Result { let account_id = from @@ -185,7 +195,7 @@ impl TryFrom for AccountState { } impl TryFrom for AccountState { - type Error = ParseError; + type Error = ConversionError; fn try_from(value: AccountUpdate) -> Result { Ok(Self { @@ -199,7 +209,7 @@ impl TryFrom for AccountState { } impl TryFrom<&AccountUpdate> for AccountState { - type Error = ParseError; + type Error = ConversionError; fn try_from(value: &AccountUpdate) -> Result { value.clone().try_into() diff --git a/proto/src/domain/blocks.rs b/proto/src/domain/blocks.rs index 3916308d1..c33ace75f 100644 --- a/proto/src/domain/blocks.rs +++ b/proto/src/domain/blocks.rs @@ -1,7 +1,7 @@ use miden_objects::BlockHeader; use crate::{ - errors::{MissingFieldHelper, ParseError}, + errors::{ConversionError, MissingFieldHelper}, generated::block_header, }; @@ -28,7 +28,7 @@ impl From for block_header::BlockHeader { } impl TryFrom<&block_header::BlockHeader> for BlockHeader { - type Error = ParseError; + type Error = ConversionError; fn try_from(value: &block_header::BlockHeader) -> Result { value.clone().try_into() @@ -36,7 +36,7 @@ impl TryFrom<&block_header::BlockHeader> for BlockHeader { } impl TryFrom for BlockHeader { - type Error = ParseError; + type Error = ConversionError; fn try_from(value: block_header::BlockHeader) -> Result { Ok(BlockHeader::new( diff --git a/proto/src/domain/digest.rs b/proto/src/domain/digest.rs index 8b2d14a66..e9bfb00a8 100644 --- a/proto/src/domain/digest.rs +++ b/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::ParseError, generated::digest}; +use crate::{errors::ConversionError, generated::digest}; // CONSTANTS // ================================================================================================ @@ -62,17 +62,17 @@ impl ToHex for digest::Digest { } impl FromHex for digest::Digest { - type Error = ParseError; + type Error = ConversionError; fn from_hex>(hex: T) -> Result { let data = hex::decode(hex)?; match data.len() { - size if size < DIGEST_DATA_SIZE => Err(ParseError::InsufficientData { + size if size < DIGEST_DATA_SIZE => Err(ConversionError::InsufficientData { expected: DIGEST_DATA_SIZE, got: size, }), - size if size > DIGEST_DATA_SIZE => Err(ParseError::TooMuchData { + size if size > DIGEST_DATA_SIZE => Err(ConversionError::TooMuchData { expected: DIGEST_DATA_SIZE, got: size, }), @@ -164,14 +164,14 @@ impl From for [u64; 4] { } impl TryFrom for [Felt; 4] { - type Error = ParseError; + type Error = ConversionError; fn try_from(value: digest::Digest) -> Result { if ![value.d0, value.d1, value.d2, value.d3] .iter() .all(|v| *v < ::MODULUS) { - Err(ParseError::NotAValidFelt) + Err(ConversionError::NotAValidFelt) } else { Ok([ Felt::new(value.d0), @@ -184,7 +184,7 @@ impl TryFrom for [Felt; 4] { } impl TryFrom for Digest { - type Error = ParseError; + type Error = ConversionError; fn try_from(value: digest::Digest) -> Result { Ok(Self::new(value.try_into()?)) @@ -192,7 +192,7 @@ impl TryFrom for Digest { } impl TryFrom<&digest::Digest> for [Felt; 4] { - type Error = ParseError; + type Error = ConversionError; fn try_from(value: &digest::Digest) -> Result { value.clone().try_into() @@ -200,7 +200,7 @@ impl TryFrom<&digest::Digest> for [Felt; 4] { } impl TryFrom<&digest::Digest> for Digest { - type Error = ParseError; + type Error = ConversionError; fn try_from(value: &digest::Digest) -> Result { value.clone().try_into() diff --git a/proto/src/domain/merkle.rs b/proto/src/domain/merkle.rs index a038ef033..04d890247 100644 --- a/proto/src/domain/merkle.rs +++ b/proto/src/domain/merkle.rs @@ -5,7 +5,7 @@ use miden_objects::{ use super::{convert, try_convert}; use crate::{ - errors::{MissingFieldHelper, ParseError}, + errors::{ConversionError, MissingFieldHelper}, generated, }; @@ -20,7 +20,7 @@ impl From for generated::merkle::MerklePath { } impl TryFrom for MerklePath { - type Error = ParseError; + type Error = ConversionError; fn try_from(merkle_path: generated::merkle::MerklePath) -> Result { merkle_path.siblings.into_iter().map(Digest::try_from).collect() @@ -41,10 +41,10 @@ impl From for generated::mmr::MmrDelta { } impl TryFrom for MmrDelta { - type Error = ParseError; + type Error = ConversionError; fn try_from(value: generated::mmr::MmrDelta) -> Result { - let data: Result, ParseError> = + let data: Result, ConversionError> = value.data.into_iter().map(Digest::try_from).collect(); Ok(MmrDelta { @@ -61,7 +61,7 @@ impl TryFrom for MmrDelta { // ------------------------------------------------------------------------------------------------ impl TryFrom for SmtLeaf { - type Error = ParseError; + type Error = ConversionError; fn try_from(value: generated::smt::SmtLeaf) -> Result { let leaf = value.leaf.ok_or(generated::smt::SmtLeaf::missing_field(stringify!(leaf)))?; @@ -104,7 +104,7 @@ impl From for generated::smt::SmtLeaf { // ------------------------------------------------------------------------------------------------ impl TryFrom for (Digest, Word) { - type Error = ParseError; + type Error = ConversionError; fn try_from(entry: generated::smt::SmtLeafEntry) -> Result { let key: Digest = entry @@ -133,7 +133,7 @@ impl From<(Digest, Word)> for generated::smt::SmtLeafEntry { // ------------------------------------------------------------------------------------------------ impl TryFrom for SmtProof { - type Error = ParseError; + type Error = ConversionError; fn try_from(opening: generated::smt::SmtOpening) -> Result { let path: MerklePath = opening diff --git a/proto/src/domain/nullifiers.rs b/proto/src/domain/nullifiers.rs index ef0179b6e..0b3cc0d0c 100644 --- a/proto/src/domain/nullifiers.rs +++ b/proto/src/domain/nullifiers.rs @@ -4,7 +4,7 @@ use miden_objects::{ }; use crate::{ - errors::{MissingFieldHelper, ParseError}, + errors::{ConversionError, MissingFieldHelper}, generated::{digest::Digest, responses::NullifierBlockInputRecord}, }; @@ -27,7 +27,7 @@ impl From for Digest { // ================================================================================================ impl TryFrom for Nullifier { - type Error = ParseError; + type Error = ConversionError; fn try_from(value: Digest) -> Result { let digest: RpoDigest = value.try_into()?; @@ -45,7 +45,7 @@ pub struct NullifierWitness { } impl TryFrom for NullifierWitness { - type Error = ParseError; + type Error = ConversionError; fn try_from(nullifier_input_record: NullifierBlockInputRecord) -> Result { Ok(Self { diff --git a/proto/src/errors.rs b/proto/src/errors.rs index da0e29577..e8bf4c598 100644 --- a/proto/src/errors.rs +++ b/proto/src/errors.rs @@ -4,7 +4,7 @@ use miden_objects::crypto::merkle::{SmtLeafError, SmtProofError}; use thiserror::Error; #[derive(Debug, Clone, PartialEq, Error)] -pub enum ParseError { +pub enum ConversionError { #[error("Hex error: {0}")] HexError(#[from] hex::FromHexError), #[error("SMT leaf error: {0}")] @@ -15,8 +15,6 @@ pub enum ParseError { TooMuchData { expected: usize, got: usize }, #[error("Not enough data, expected {expected}, got {got}")] InsufficientData { expected: usize, got: usize }, - #[error("Number of MmrPeaks doesn't fit into memory")] - TooManyMmrPeaks, #[error("Value is not in the range 0..MODULUS")] NotAValidFelt, #[error("Field `{field_name}` required to be filled in protobuf representation of {entity}")] @@ -26,15 +24,15 @@ pub enum ParseError { }, } -impl Eq for ParseError {} +impl Eq for ConversionError {} pub trait MissingFieldHelper { - fn missing_field(field_name: &'static str) -> ParseError; + fn missing_field(field_name: &'static str) -> ConversionError; } impl MissingFieldHelper for T { - fn missing_field(field_name: &'static str) -> ParseError { - ParseError::MissingFieldInProtobufRepresentation { + fn missing_field(field_name: &'static str) -> ConversionError { + ConversionError::MissingFieldInProtobufRepresentation { entity: type_name::(), field_name, } diff --git a/store/src/server/api.rs b/store/src/server/api.rs index abfbb84d4..5e48207da 100644 --- a/store/src/server/api.rs +++ b/store/src/server/api.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use miden_node_proto::{ convert, - errors::ParseError, + errors::ConversionError, generated::{ self, note::NoteSyncRecord, @@ -181,7 +181,7 @@ impl api_server::Api for StoreApi { .block .ok_or(invalid_argument("Apply block missing block header"))? .try_into() - .map_err(|err: ParseError| Status::invalid_argument(err.to_string()))?; + .map_err(|err: ConversionError| Status::invalid_argument(err.to_string()))?; info!(target: COMPONENT, block_num = block_header.block_num(), block_hash = %block_header.hash()); @@ -192,7 +192,7 @@ impl api_server::Api for StoreApi { .map(|account_update| { let account_state: AccountState = account_update .try_into() - .map_err(|err: ParseError| Status::invalid_argument(err.to_string()))?; + .map_err(|err: ConversionError| Status::invalid_argument(err.to_string()))?; Ok(( account_state.account_id.into(), account_state @@ -213,7 +213,9 @@ impl api_server::Api for StoreApi { .note_id .ok_or(invalid_argument("Note missing id"))? .try_into() - .map_err(|err: ParseError| Status::invalid_argument(err.to_string()))?, + .map_err(|err: ConversionError| { + Status::invalid_argument(err.to_string()) + })?, sender: note.sender.ok_or(invalid_argument("Note missing sender"))?.into(), tag: note.tag, }) @@ -394,6 +396,6 @@ fn validate_nullifiers(nullifiers: &[generated::digest::Digest]) -> Result>() + .collect::>() .map_err(|_| invalid_argument("Digest field is not in the modulus range")) }