From 28d44fb9b701794af156d9a535d02d5d8bf800c9 Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Fri, 29 Mar 2024 12:50:46 +0500 Subject: [PATCH] refactor: keep only domain object changes --- Cargo.lock | 159 ------------------ Cargo.toml | 1 - block-producer/src/batch_builder/batch.rs | 17 +- block-producer/src/block.rs | 4 +- block-producer/src/block_builder/mod.rs | 8 +- .../src/block_builder/prover/block_witness.rs | 6 +- .../src/block_builder/prover/tests.rs | 2 +- block-producer/src/state_view/mod.rs | 15 +- .../src/state_view/tests/apply_block.rs | 6 +- block-producer/src/test_utils/block.rs | 19 +-- block-producer/src/test_utils/store.rs | 2 +- proto/proto/requests.proto | 7 - proto/proto/responses.proto | 5 - proto/proto/rpc.proto | 1 - proto/proto/store.proto | 1 - proto/src/domain/accounts.rs | 7 +- proto/src/generated/requests.rs | 11 -- proto/src/generated/responses.rs | 8 - proto/src/generated/rpc.rs | 86 ---------- proto/src/generated/store.rs | 86 ---------- rpc/src/server/api.rs | 25 +-- store/Cargo.toml | 1 - store/README.md | 55 ++---- store/src/db/migrations.rs | 30 +--- store/src/db/mod.rs | 22 +-- store/src/db/sql.rs | 152 ++++------------- store/src/db/tests.rs | 144 +--------------- store/src/errors.rs | 27 +-- store/src/server/api.rs | 43 +---- store/src/state.rs | 14 +- 30 files changed, 111 insertions(+), 853 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0393c81e1..279ea0a24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -167,15 +167,6 @@ dependencies = [ "bytemuck", ] -[[package]] -name = "atomic-polyfill" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" -dependencies = [ - "critical-section", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -344,12 +335,6 @@ version = "1.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.5.0" @@ -446,12 +431,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" -[[package]] -name = "cobs" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" - [[package]] name = "colorchoice" version = "1.0.0" @@ -479,12 +458,6 @@ dependencies = [ "libc", ] -[[package]] -name = "critical-section" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" - [[package]] name = "crypto-common" version = "0.1.6" @@ -573,35 +546,6 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" -[[package]] -name = "embedded-io" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" - -[[package]] -name = "env_filter" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "humantime", - "log", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -755,15 +699,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "hash32" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" -dependencies = [ - "byteorder", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -789,20 +724,6 @@ dependencies = [ "hashbrown 0.14.3", ] -[[package]] -name = "heapless" -version = "0.7.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" -dependencies = [ - "atomic-polyfill", - "hash32", - "rustc_version", - "serde", - "spin", - "stable_deref_trait", -] - [[package]] name = "heck" version = "0.4.1" @@ -864,12 +785,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "hyper" version = "0.14.28" @@ -1187,7 +1102,6 @@ dependencies = [ "cc", "glob", "libc", - "serde", "winter-crypto", "winter-math", "winter-utils", @@ -1203,23 +1117,6 @@ dependencies = [ "miden-stdlib", ] -[[package]] -name = "miden-mock" -version = "0.2.0" -source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#cc2bec3511ad9a22416a8be0fc7977eb42c4014c" -dependencies = [ - "env_logger", - "hex", - "miden-lib", - "miden-objects", - "miden-processor", - "miden-prover", - "postcard", - "rand", - "rand_pcg", - "winter-rand-utils", -] - [[package]] name = "miden-node" version = "0.2.0" @@ -1320,7 +1217,6 @@ dependencies = [ "figment", "hex", "miden-lib", - "miden-mock", "miden-node-proto", "miden-node-utils", "miden-objects", @@ -1364,13 +1260,11 @@ name = "miden-objects" version = "0.2.0" source = "git+https://github.com/0xPolygonMiden/miden-base.git?branch=next#cc2bec3511ad9a22416a8be0fc7977eb42c4014c" dependencies = [ - "log", "miden-assembly", "miden-core", "miden-crypto", "miden-processor", "miden-verifier", - "serde", "winter-rand-utils", ] @@ -1694,18 +1588,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" -[[package]] -name = "postcard" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" -dependencies = [ - "cobs", - "embedded-io", - "heapless", - "serde", -] - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1912,16 +1794,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rand_pcg" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" -dependencies = [ - "rand_core", - "serde", -] - [[package]] name = "rand_xorshift" version = "0.3.0" @@ -2031,15 +1903,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - [[package]] name = "rustix" version = "0.38.31" @@ -2083,12 +1946,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "semver" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" - [[package]] name = "serde" version = "1.0.197" @@ -2185,21 +2042,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "strsim" version = "0.11.0" @@ -2956,7 +2798,6 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0dff7a27296595fbdc653751b3718acd9518288df646e860ecb48915ff0d6c3" dependencies = [ - "serde", "winter-utils", ] diff --git a/Cargo.toml b/Cargo.toml index 1da084dcf..9018bfd66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,6 @@ exclude = [".github/"] [workspace.dependencies] miden-air = { version = "0.8", default-features = false } miden-lib = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } -miden-mock = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } miden-objects = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } miden-processor = { version = "0.8" } miden-stdlib = { version = "0.8", default-features = false } diff --git a/block-producer/src/batch_builder/batch.rs b/block-producer/src/batch_builder/batch.rs index 4976a15ab..2f4752f1d 100644 --- a/block-producer/src/batch_builder/batch.rs +++ b/block-producer/src/batch_builder/batch.rs @@ -7,7 +7,6 @@ use miden_objects::{ merkle::SimpleSmt, }, notes::{NoteEnvelope, Nullifier}, - transaction::AccountDetails, Digest, BATCH_OUTPUT_NOTES_TREE_DEPTH, MAX_NOTES_PER_BATCH, }; use tracing::instrument; @@ -56,7 +55,6 @@ impl TransactionBatch { AccountStates { initial_state: tx.initial_account_hash(), final_state: tx.final_account_hash(), - details: tx.account_details().cloned(), }, ) }) @@ -110,14 +108,12 @@ impl TransactionBatch { .map(|(account_id, account_states)| (*account_id, account_states.initial_state)) } - /// Returns an iterator over (account_id, details, new_state_hash) tuples for accounts that were + /// 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, Digest)> + '_ { - self.updated_accounts.iter().map(|(account_id, account_states)| { - (*account_id, account_states.details.clone(), account_states.final_state) - }) + pub fn updated_accounts(&self) -> impl Iterator + '_ { + self.updated_accounts + .iter() + .map(|(account_id, account_states)| (*account_id, account_states.final_state)) } /// Returns an iterator over produced nullifiers for all consumed notes. @@ -151,9 +147,8 @@ impl TransactionBatch { /// account. /// /// TODO: should this be moved into domain objects? -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] struct AccountStates { initial_state: Digest, final_state: Digest, - details: Option, } diff --git a/block-producer/src/block.rs b/block-producer/src/block.rs index 99b21ce60..1f1c677b6 100644 --- a/block-producer/src/block.rs +++ b/block-producer/src/block.rs @@ -9,7 +9,6 @@ use miden_objects::{ accounts::AccountId, crypto::merkle::{MerklePath, MmrPeaks, SmtProof}, notes::{NoteEnvelope, Nullifier}, - transaction::AccountDetails, BlockHeader, Digest, }; @@ -18,10 +17,11 @@ use crate::store::BlockInputsError; #[derive(Debug, Clone)] pub struct Block { pub header: BlockHeader, - pub updated_accounts: Vec<(AccountId, Option, Digest)>, + pub updated_accounts: Vec<(AccountId, Digest)>, pub created_notes: BTreeMap, pub produced_nullifiers: Vec, // TODO: + // - full states for updated public accounts // - full states for created public notes // - zk proof } diff --git a/block-producer/src/block_builder/mod.rs b/block-producer/src/block_builder/mod.rs index f3924e81f..d92bd7943 100644 --- a/block-producer/src/block_builder/mod.rs +++ b/block-producer/src/block_builder/mod.rs @@ -2,9 +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, transaction::AccountDetails, Digest, MAX_NOTES_PER_BATCH, -}; +use miden_objects::{accounts::AccountId, notes::Nullifier, Digest, MAX_NOTES_PER_BATCH}; use tracing::{debug, info, instrument}; use crate::{ @@ -79,7 +77,7 @@ where batches = %format_array(batches.iter().map(|batch| format_blake3_digest(batch.id()))), ); - let updated_accounts: Vec<(AccountId, Option, Digest)> = + let updated_accounts: Vec<(AccountId, Digest)> = batches.iter().flat_map(TransactionBatch::updated_accounts).collect(); let created_notes = batches .iter() @@ -97,7 +95,7 @@ where let block_inputs = self .store .get_block_inputs( - updated_accounts.iter().map(|(account_id, _, _)| account_id), + updated_accounts.iter().map(|(account_id, _)| 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 25f18dccb..87bcbcd0e 100644 --- a/block-producer/src/block_builder/prover/block_witness.rs +++ b/block-producer/src/block_builder/prover/block_witness.rs @@ -37,7 +37,7 @@ impl BlockWitness { let updated_accounts = { let mut account_initial_states: BTreeMap = - batches.iter().flat_map(TransactionBatch::account_initial_states).collect(); + batches.iter().flat_map(|batch| batch.account_initial_states()).collect(); let mut account_merkle_proofs: BTreeMap = block_inputs .accounts @@ -47,8 +47,8 @@ impl BlockWitness { batches .iter() - .flat_map(TransactionBatch::updated_accounts) - .map(|(account_id, _details, final_state_hash)| { + .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"); diff --git a/block-producer/src/block_builder/prover/tests.rs b/block-producer/src/block_builder/prover/tests.rs index c0d691d35..10d23502e 100644 --- a/block-producer/src/block_builder/prover/tests.rs +++ b/block-producer/src/block_builder/prover/tests.rs @@ -235,7 +235,7 @@ async fn test_compute_account_root_success() { account_ids .iter() .zip(account_final_states.iter()) - .map(|(&account_id, &account_hash)| (account_id, None, account_hash.into())) + .map(|(&account_id, &account_hash)| (account_id, account_hash.into())) .collect(), ) .build(); diff --git a/block-producer/src/state_view/mod.rs b/block-producer/src/state_view/mod.rs index 9742a626e..bafbf4e2d 100644 --- a/block-producer/src/state_view/mod.rs +++ b/block-producer/src/state_view/mod.rs @@ -121,23 +121,24 @@ where &self, block: Block, ) -> Result<(), ApplyBlockError> { - let account_ids_in_block: Vec = - block.updated_accounts.iter().map(|(account_id, _, _)| *account_id).collect(); - let produced_nullifiers = block.produced_nullifiers.clone(); - - self.store.apply_block(block).await?; + self.store.apply_block(block.clone()).await?; let mut locked_accounts_in_flight = self.accounts_in_flight.write().await; let mut locked_nullifiers_in_flight = self.nullifiers_in_flight.write().await; // Remove account ids of transactions in block - for account_id in account_ids_in_block.iter() { + 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); debug_assert!(was_in_flight); } // Remove new nullifiers of transactions in block - for nullifier in produced_nullifiers.iter() { + for nullifier in block.produced_nullifiers.iter() { 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 410d2219d..ac4a52348 100644 --- a/block-producer/src/state_view/tests/apply_block.rs +++ b/block-producer/src/state_view/tests/apply_block.rs @@ -32,7 +32,7 @@ async fn test_apply_block_ab1() { .await .account_updates( std::iter::once(account) - .map(|mock_account| (mock_account.id, None, mock_account.states[1])) + .map(|mock_account| (mock_account.id, mock_account.states[1])) .collect(), ) .build(); @@ -75,7 +75,7 @@ async fn test_apply_block_ab2() { .account_updates( accounts_in_block .into_iter() - .map(|mock_account| (mock_account.id, None, mock_account.states[1])) + .map(|mock_account| (mock_account.id, mock_account.states[1])) .collect(), ) .build(); @@ -120,7 +120,7 @@ async fn test_apply_block_ab3() { accounts .clone() .into_iter() - .map(|mock_account| (mock_account.id, None, mock_account.states[1])) + .map(|mock_account| (mock_account.id, mock_account.states[1])) .collect(), ) .build(); diff --git a/block-producer/src/test_utils/block.rs b/block-producer/src/test_utils/block.rs index 9aa12e1c4..a158a8d72 100644 --- a/block-producer/src/test_utils/block.rs +++ b/block-producer/src/test_utils/block.rs @@ -4,7 +4,6 @@ use miden_objects::{ accounts::AccountId, crypto::merkle::{Mmr, SimpleSmt}, notes::{NoteEnvelope, Nullifier}, - transaction::AccountDetails, BlockHeader, Digest, ACCOUNT_TREE_DEPTH, BLOCK_OUTPUT_NOTES_TREE_DEPTH, MAX_NOTES_PER_BATCH, ONE, ZERO, }; @@ -26,11 +25,11 @@ 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, Option, Digest)> = + let updated_accounts: Vec<(AccountId, Digest)> = batches.iter().flat_map(TransactionBatch::updated_accounts).collect(); let new_account_root = { let mut store_accounts = store.accounts.read().await.clone(); - for (account_id, _details, new_account_state) in updated_accounts { + for (account_id, new_account_state) in updated_accounts { store_accounts.insert(account_id.into(), new_account_state.into()); } @@ -68,14 +67,14 @@ pub async fn build_actual_block_header( store: &MockStoreSuccess, batches: Vec, ) -> BlockHeader { - let updated_accounts: Vec<(AccountId, Option, Digest)> = - batches.iter().flat_map(TransactionBatch::updated_accounts).collect(); + let updated_accounts: Vec<(AccountId, Digest)> = + batches.iter().flat_map(|batch| batch.updated_accounts()).collect(); let produced_nullifiers: Vec = - batches.iter().flat_map(TransactionBatch::produced_nullifiers).collect(); + 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(|(account_id, _)| account_id), produced_nullifiers.iter(), ) .await @@ -92,7 +91,7 @@ pub struct MockBlockBuilder { store_chain_mmr: Mmr, last_block_header: BlockHeader, - updated_accounts: Option, Digest)>>, + updated_accounts: Option>, created_notes: Option>, produced_nullifiers: Option>, } @@ -112,9 +111,9 @@ impl MockBlockBuilder { pub fn account_updates( mut self, - updated_accounts: Vec<(AccountId, Option, Digest)>, + updated_accounts: Vec<(AccountId, Digest)>, ) -> Self { - for &(account_id, ref _details, new_account_state) in updated_accounts.iter() { + for &(account_id, new_account_state) in updated_accounts.iter() { self.store_accounts.insert(account_id.into(), new_account_state.into()); } diff --git a/block-producer/src/test_utils/store.rs b/block-producer/src/test_utils/store.rs index 9e7844676..00f26a2a1 100644 --- a/block-producer/src/test_utils/store.rs +++ b/block-producer/src/test_utils/store.rs @@ -180,7 +180,7 @@ impl ApplyBlock for MockStoreSuccess { let mut locked_produced_nullifiers = self.produced_nullifiers.write().await; // update accounts - for &(account_id, ref _details, account_hash) in block.updated_accounts.iter() { + for &(account_id, account_hash) in block.updated_accounts.iter() { locked_accounts.insert(account_id.into(), account_hash.into()); } debug_assert_eq!(locked_accounts.root(), block.header.account_root()); diff --git a/proto/proto/requests.proto b/proto/proto/requests.proto index 8c271696d..d872b3d58 100644 --- a/proto/proto/requests.proto +++ b/proto/proto/requests.proto @@ -10,8 +10,6 @@ import "note.proto"; message AccountUpdate { account.AccountId account_id = 1; digest.Digest account_hash = 2; - // Details for public (on-chain) account. - account.AccountDetails details = 3; } message ApplyBlockRequest { @@ -86,8 +84,3 @@ message ListNullifiersRequest {} message ListAccountsRequest {} message ListNotesRequest {} - -message GetPublicAccountDetailsRequest { - // Public account ID to get details. - account.AccountId account_id = 1; -} diff --git a/proto/proto/responses.proto b/proto/proto/responses.proto index 2740bcf6f..d7b8f487b 100644 --- a/proto/proto/responses.proto +++ b/proto/proto/responses.proto @@ -113,8 +113,3 @@ message ListNotesResponse { // Lists all notes of the current chain repeated note.Note notes = 1; } - -message GetPublicAccountDetailsResponse { - // Public account full details. - account.AccountFullDetails details = 1; -} diff --git a/proto/proto/rpc.proto b/proto/proto/rpc.proto index 39ae944f4..015b0a9d3 100644 --- a/proto/proto/rpc.proto +++ b/proto/proto/rpc.proto @@ -10,5 +10,4 @@ service Api { rpc GetBlockHeaderByNumber(requests.GetBlockHeaderByNumberRequest) returns (responses.GetBlockHeaderByNumberResponse) {} rpc SyncState(requests.SyncStateRequest) returns (responses.SyncStateResponse) {} rpc SubmitProvenTransaction(requests.SubmitProvenTransactionRequest) returns (responses.SubmitProvenTransactionResponse) {} - rpc GetPublicAccountDetails(requests.GetPublicAccountDetailsRequest) returns (responses.GetPublicAccountDetailsResponse) {} } diff --git a/proto/proto/store.proto b/proto/proto/store.proto index 58054da48..4c5557755 100644 --- a/proto/proto/store.proto +++ b/proto/proto/store.proto @@ -17,5 +17,4 @@ service Api { rpc ListNullifiers(requests.ListNullifiersRequest) returns (responses.ListNullifiersResponse) {} rpc ListAccounts(requests.ListAccountsRequest) returns (responses.ListAccountsResponse) {} rpc ListNotes(requests.ListNotesRequest) returns (responses.ListNotesResponse) {} - rpc GetPublicAccountDetails(requests.GetPublicAccountDetailsRequest) returns (responses.GetPublicAccountDetailsResponse) {} } diff --git a/proto/src/domain/accounts.rs b/proto/src/domain/accounts.rs index fe6cd1587..337a1c77d 100644 --- a/proto/src/domain/accounts.rs +++ b/proto/src/domain/accounts.rs @@ -388,14 +388,11 @@ impl TryFrom<&AccountDetailsPb> for AccountDetails { // INTO ACCOUNT UPDATE // ================================================================================================ -impl From<(AccountId, Option, Digest)> for AccountUpdate { - fn from( - (account_id, details, account_hash): (AccountId, Option, Digest) - ) -> Self { +impl From<(AccountId, Digest)> for AccountUpdate { + fn from((account_id, account_hash): (AccountId, Digest)) -> Self { Self { account_id: Some(account_id.into()), account_hash: Some(account_hash.into()), - details: details.as_ref().map(Into::into), } } } diff --git a/proto/src/generated/requests.rs b/proto/src/generated/requests.rs index 796ef4bb8..799551253 100644 --- a/proto/src/generated/requests.rs +++ b/proto/src/generated/requests.rs @@ -6,9 +6,6 @@ pub struct AccountUpdate { pub account_id: ::core::option::Option, #[prost(message, optional, tag = "2")] pub account_hash: ::core::option::Option, - /// Details for public (on-chain) account. - #[prost(message, optional, tag = "3")] - pub details: ::core::option::Option, } #[derive(Eq, PartialOrd, Ord, Hash)] #[allow(clippy::derive_partial_eq_without_eq)] @@ -115,11 +112,3 @@ pub struct ListAccountsRequest {} #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListNotesRequest {} -#[derive(Eq, PartialOrd, Ord, Hash)] -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct GetPublicAccountDetailsRequest { - /// Public account ID to get details. - #[prost(message, optional, tag = "1")] - pub account_id: ::core::option::Option, -} diff --git a/proto/src/generated/responses.rs b/proto/src/generated/responses.rs index 482bf2a49..a0d00f301 100644 --- a/proto/src/generated/responses.rs +++ b/proto/src/generated/responses.rs @@ -158,11 +158,3 @@ pub struct ListNotesResponse { #[prost(message, repeated, tag = "1")] pub notes: ::prost::alloc::vec::Vec, } -#[derive(Eq, PartialOrd, Ord, Hash)] -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct GetPublicAccountDetailsResponse { - /// Public account full details. - #[prost(message, optional, tag = "1")] - pub details: ::core::option::Option, -} diff --git a/proto/src/generated/rpc.rs b/proto/src/generated/rpc.rs index dd327ccd3..75d47961e 100644 --- a/proto/src/generated/rpc.rs +++ b/proto/src/generated/rpc.rs @@ -183,33 +183,6 @@ pub mod api_client { .insert(GrpcMethod::new("rpc.Api", "SubmitProvenTransaction")); self.inner.unary(req, path, codec).await } - pub async fn get_public_account_details( - &mut self, - request: impl tonic::IntoRequest< - super::super::requests::GetPublicAccountDetailsRequest, - >, - ) -> std::result::Result< - tonic::Response, - tonic::Status, - > { - self.inner - .ready() - .await - .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, - format!("Service was not ready: {}", e.into()), - ) - })?; - let codec = tonic::codec::ProstCodec::default(); - let path = http::uri::PathAndQuery::from_static( - "/rpc.Api/GetPublicAccountDetails", - ); - let mut req = request.into_request(); - req.extensions_mut() - .insert(GrpcMethod::new("rpc.Api", "GetPublicAccountDetails")); - self.inner.unary(req, path, codec).await - } } } /// Generated server implementations. @@ -251,15 +224,6 @@ pub mod api_server { tonic::Response, tonic::Status, >; - async fn get_public_account_details( - &self, - request: tonic::Request< - super::super::requests::GetPublicAccountDetailsRequest, - >, - ) -> std::result::Result< - tonic::Response, - tonic::Status, - >; } #[derive(Debug)] pub struct ApiServer { @@ -537,56 +501,6 @@ pub mod api_server { }; Box::pin(fut) } - "/rpc.Api/GetPublicAccountDetails" => { - #[allow(non_camel_case_types)] - struct GetPublicAccountDetailsSvc(pub Arc); - impl< - T: Api, - > tonic::server::UnaryService< - super::super::requests::GetPublicAccountDetailsRequest, - > for GetPublicAccountDetailsSvc { - type Response = super::super::responses::GetPublicAccountDetailsResponse; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; - fn call( - &mut self, - request: tonic::Request< - super::super::requests::GetPublicAccountDetailsRequest, - >, - ) -> Self::Future { - let inner = Arc::clone(&self.0); - let fut = async move { - ::get_public_account_details(&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 inner = inner.0; - let method = GetPublicAccountDetailsSvc(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) - } _ => { Box::pin(async move { Ok( diff --git a/proto/src/generated/store.rs b/proto/src/generated/store.rs index 0bc063e7e..d2f62f986 100644 --- a/proto/src/generated/store.rs +++ b/proto/src/generated/store.rs @@ -299,33 +299,6 @@ pub mod api_client { req.extensions_mut().insert(GrpcMethod::new("store.Api", "ListNotes")); self.inner.unary(req, path, codec).await } - pub async fn get_public_account_details( - &mut self, - request: impl tonic::IntoRequest< - super::super::requests::GetPublicAccountDetailsRequest, - >, - ) -> std::result::Result< - tonic::Response, - tonic::Status, - > { - self.inner - .ready() - .await - .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, - format!("Service was not ready: {}", e.into()), - ) - })?; - let codec = tonic::codec::ProstCodec::default(); - let path = http::uri::PathAndQuery::from_static( - "/store.Api/GetPublicAccountDetails", - ); - let mut req = request.into_request(); - req.extensions_mut() - .insert(GrpcMethod::new("store.Api", "GetPublicAccountDetails")); - self.inner.unary(req, path, codec).await - } } } /// Generated server implementations. @@ -400,15 +373,6 @@ pub mod api_server { tonic::Response, tonic::Status, >; - async fn get_public_account_details( - &self, - request: tonic::Request< - super::super::requests::GetPublicAccountDetailsRequest, - >, - ) -> std::result::Result< - tonic::Response, - tonic::Status, - >; } #[derive(Debug)] pub struct ApiServer { @@ -931,56 +895,6 @@ pub mod api_server { }; Box::pin(fut) } - "/store.Api/GetPublicAccountDetails" => { - #[allow(non_camel_case_types)] - struct GetPublicAccountDetailsSvc(pub Arc); - impl< - T: Api, - > tonic::server::UnaryService< - super::super::requests::GetPublicAccountDetailsRequest, - > for GetPublicAccountDetailsSvc { - type Response = super::super::responses::GetPublicAccountDetailsResponse; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; - fn call( - &mut self, - request: tonic::Request< - super::super::requests::GetPublicAccountDetailsRequest, - >, - ) -> Self::Future { - let inner = Arc::clone(&self.0); - let fut = async move { - ::get_public_account_details(&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 inner = inner.0; - let method = GetPublicAccountDetailsSvc(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) - } _ => { Box::pin(async move { Ok( diff --git a/rpc/src/server/api.rs b/rpc/src/server/api.rs index 72e4c3812..9b98f1dd1 100644 --- a/rpc/src/server/api.rs +++ b/rpc/src/server/api.rs @@ -2,12 +2,12 @@ use anyhow::Result; use miden_node_proto::generated::{ block_producer::api_client as block_producer_client, requests::{ - CheckNullifiersRequest, GetBlockHeaderByNumberRequest, GetPublicAccountDetailsRequest, - SubmitProvenTransactionRequest, SyncStateRequest, + CheckNullifiersRequest, GetBlockHeaderByNumberRequest, SubmitProvenTransactionRequest, + SyncStateRequest, }, responses::{ - CheckNullifiersResponse, GetBlockHeaderByNumberResponse, GetPublicAccountDetailsResponse, - SubmitProvenTransactionResponse, SyncStateResponse, + CheckNullifiersResponse, GetBlockHeaderByNumberResponse, SubmitProvenTransactionResponse, + SyncStateResponse, }, rpc::api_server, store::api_client as store_client, @@ -132,21 +132,4 @@ impl api_server::Api for RpcApi { self.block_producer.clone().submit_proven_transaction(request).await } - - /// Returns details for public (on-chain) account by id. - #[instrument( - target = "miden-rpc", - name = "rpc:get_public_account_details", - skip_all, - ret(level = "debug"), - err - )] - async fn get_public_account_details( - &self, - request: tonic::Request, - ) -> std::result::Result, Status> { - debug!(target: COMPONENT, request = ?request.get_ref()); - - self.store.clone().get_public_account_details(request).await - } } diff --git a/store/Cargo.toml b/store/Cargo.toml index 20b6fb9b2..db5f8b0a3 100644 --- a/store/Cargo.toml +++ b/store/Cargo.toml @@ -42,5 +42,4 @@ tracing-subscriber = { workspace = true } [dev-dependencies] figment = { version = "0.10", features = ["toml", "env", "test"] } -miden-mock = { workspace = true } miden-node-utils = { path = "../utils", version = "0.2", features = ["tracing-forest"] } diff --git a/store/README.md b/store/README.md index 927df8bf5..a3a95fc69 100644 --- a/store/README.md +++ b/store/README.md @@ -1,7 +1,7 @@ # Miden node store -The **Store** maintains the state of the chain. It serves as the "source of truth" for the chain - i.e., if it is not in -the store, the node does not consider it to be part of the chain. +The **Store** maintains the state of the chain. It serves as the "source of truth" for the chain - i.e., if it is not in +the store, the node does not consider it to be part of the chain. **Store** is one of components of the [Miden node](..). ## Architecture @@ -22,11 +22,9 @@ cargo install --path store ### Running the Store -In order to run Store, you must provide a genesis file. To generate a genesis file you will need to -use [Miden node](../README.md#generating-the-genesis-file)'s `make-genesis` command. +In order to run Store, you must provide a genesis file. To generate a genesis file you will need to use [Miden node](../README.md#generating-the-genesis-file)'s `make-genesis` command. -You will also need to provide a configuration file. We have an example config file -in [store-example.toml](store-example.toml). +You will also need to provide a configuration file. We have an example config file in [store-example.toml](store-example.toml). Then, to run the Store: @@ -36,8 +34,7 @@ miden-node-store serve --config ## API -The **Store** serves connections using the [gRPC protocol](https://grpc.io) on a port, set in the previously mentioned -configuration file. +The **Store** serves connections using the [gRPC protocol](https://grpc.io) on a port, set in the previously mentioned configuration file. Here is a brief description of supported methods. ### ApplyBlock @@ -73,8 +70,7 @@ Retrieves block header by given block number. **Parameters** -* `block_num`: `uint32` *(optional)* – the block number of the target block. If not provided, the latest known block - will be returned. +* `block_num`: `uint32` *(optional)* – the block number of the target block. If not provided, the latest known block will be returned. **Returns:** @@ -86,7 +82,7 @@ Returns data needed by the block producer to construct and prove the next block. **Parameters** -* `account_ids`: `[AccountId]` – array of account IDs. +* `account_ids`: `[AccountId]` – array of account IDs. * `nullifiers`: `[Digest]` – array of nullifier hashes (not currently in use). **Returns** @@ -98,7 +94,7 @@ Returns data needed by the block producer to construct and prove the next block. ### GetTransactionInputs -Returns the data needed by the block producer to check validity of an incoming transaction. +Returns the data needed by the block producer to check validity of an incoming transaction. **Parameters** @@ -107,26 +103,21 @@ Returns the data needed by the block producer to check validity of an incoming t **Returns** -* `account_state`: `AccountTransactionInputRecord` – account's descriptors. -* `nullifiers`: `[NullifierTransactionInputRecord]` – the block numbers at which corresponding nullifiers have been - consumed, zero if not consumed. +* `account_state`: `AccountTransactionInputRecord` – account's descriptors. +* `nullifiers`: `[NullifierTransactionInputRecord]` – the block numbers at which corresponding nullifiers have been consumed, zero if not consumed. ### SyncState Returns info which can be used by the client to sync up to the latest state of the chain for the objects (accounts, notes, nullifiers) the client is interested in. -This request returns the next block containing requested data. It also returns `chain_tip` which is the latest block -number in the chain. -Client is expected to repeat these requests in a loop until `response.block_header.block_num == response.chain_tip`, at -which point the client is fully synchronized with the chain. +This request returns the next block containing requested data. It also returns `chain_tip` which is the latest block number in the chain. +Client is expected to repeat these requests in a loop until `response.block_header.block_num == response.chain_tip`, at which point the client is fully synchronized with the chain. -Each request also returns info about new notes, nullifiers etc. created. It also returns Chain MMR delta that can be -used to update the state of Chain MMR. +Each request also returns info about new notes, nullifiers etc. created. It also returns Chain MMR delta that can be used to update the state of Chain MMR. This includes both chain MMR peaks and chain MMR nodes. -For preserving some degree of privacy, note tags and nullifiers filters contain only high part of hashes. Thus, returned -data +For preserving some degree of privacy, note tags and nullifiers filters contain only high part of hashes. Thus, returned data contains excessive notes and nullifiers, client can make additional filtering of that data on its side. **Parameters** @@ -141,23 +132,10 @@ contains excessive notes and nullifiers, client can make additional filtering of * `chain_tip`: `uint32` – number of the latest block in the chain. * `block_header`: `BlockHeader` – block header of the block with the first note matching the specified criteria. * `mmr_delta`: `MmrDelta` – data needed to update the partial MMR from `block_num + 1` to `block_header.block_num`. -* `accounts`: `[AccountHashUpdate]` – a list of account hashes updated after `block_num + 1` but not - after `block_header.block_num`. +* `accounts`: `[AccountHashUpdate]` – a list of account hashes updated after `block_num + 1` but not after `block_header.block_num`. * `notes`: `[NoteSyncRecord]` – a list of all notes together with the Merkle paths from `block_header.note_root`. * `nullifiers`: `[NullifierUpdate]` – a list of nullifiers created between `block_num + 1` and `block_header.block_num`. -### GetPublicAccountDetails - -Returns details for public (on-chain) account by id. - -**Parameters** - -* `account_id`: `AccountId` – account id. - -**Returns** - -* `details`: `AccountFullDetails` – public account full details. - ## Methods for testing purposes ### ListNullifiers @@ -170,7 +148,7 @@ This request doesn't have any parameters. **Returns** -* `nullifiers`: `[NullifierLeaf]` – lists of all nullifiers of the current chain. +* `nullifiers`: `[NullifierLeaf]` – lists of all nullifiers of the current chain. ### ListAccounts @@ -197,5 +175,4 @@ This request doesn't have any parameters. * `notes`: `[Note]` – list of all notes of the current chain. ## License - This project is [MIT licensed](../LICENSE). diff --git a/store/src/db/migrations.rs b/store/src/db/migrations.rs index 6ef7028a6..3eec2bc0b 100644 --- a/store/src/db/migrations.rs +++ b/store/src/db/migrations.rs @@ -11,7 +11,7 @@ pub static MIGRATIONS: Lazy = Lazy::new(|| { block_header BLOB NOT NULL, PRIMARY KEY (block_num), - CONSTRAINT block_header_block_num_is_u32 CHECK (block_num BETWEEN 0 AND 0xFFFFFFFF) + CONSTRAINT block_header_block_num_is_u32 CHECK (block_num >= 0 AND block_num < 4294967296) ) STRICT, WITHOUT ROWID; CREATE TABLE @@ -26,8 +26,8 @@ pub static MIGRATIONS: Lazy = Lazy::new(|| { PRIMARY KEY (block_num, note_index), CONSTRAINT fk_block_num FOREIGN KEY (block_num) REFERENCES block_headers (block_num), - CONSTRAINT notes_block_num_is_u32 CHECK (block_num BETWEEN 0 AND 0xFFFFFFFF), - CONSTRAINT notes_note_index_is_u32 CHECK (note_index BETWEEN 0 AND 0xFFFFFFFF) + CONSTRAINT notes_block_number_is_u32 CHECK (block_num >= 0 AND block_num < 4294967296), + CONSTRAINT notes_note_index_is_u32 CHECK (note_index >= 0 AND note_index < 4294967296) ) STRICT, WITHOUT ROWID; CREATE TABLE @@ -39,21 +39,7 @@ pub static MIGRATIONS: Lazy = Lazy::new(|| { PRIMARY KEY (account_id), CONSTRAINT fk_block_num FOREIGN KEY (block_num) REFERENCES block_headers (block_num), - CONSTRAINT accounts_block_num_is_u32 CHECK (block_num BETWEEN 0 AND 0xFFFFFFFF) - ) STRICT, WITHOUT ROWID; - - CREATE TABLE - account_details - ( - account_id INTEGER NOT NULL, - nonce INTEGER NOT NULL, - vault BLOB NOT NULL, - storage BLOB NOT NULL, - code BLOB NOT NULL, - - PRIMARY KEY (account_id), - CONSTRAINT account_details_nonce_non_negative CHECK (nonce >= 0), - FOREIGN KEY (account_id) REFERENCES accounts (account_id) + CONSTRAINT accounts_block_num_is_u32 CHECK (block_num >= 0 AND block_num < 4294967296) ) STRICT, WITHOUT ROWID; CREATE TABLE @@ -61,13 +47,13 @@ pub static MIGRATIONS: Lazy = Lazy::new(|| { ( nullifier BLOB NOT NULL, nullifier_prefix INTEGER NOT NULL, - block_num INTEGER NOT NULL, + block_number INTEGER NOT NULL, PRIMARY KEY (nullifier), - CONSTRAINT fk_block_num FOREIGN KEY (block_num) REFERENCES block_headers (block_num), + CONSTRAINT fk_block_num FOREIGN KEY (block_number) REFERENCES block_headers (block_num), CONSTRAINT nullifiers_nullifier_is_digest CHECK (length(nullifier) = 32), - CONSTRAINT nullifiers_nullifier_prefix_is_u16 CHECK (nullifier_prefix BETWEEN 0 AND 0xFFFF), - CONSTRAINT nullifiers_block_num_is_u32 CHECK (block_num BETWEEN 0 AND 0xFFFFFFFF) + CONSTRAINT nullifiers_nullifier_prefix_is_u16 CHECK (nullifier_prefix >= 0 AND nullifier_prefix < 65536), + CONSTRAINT nullifiers_block_number_is_u32 CHECK (block_number >= 0 AND block_number < 4294967296) ) STRICT, WITHOUT ROWID; ", )]) diff --git a/store/src/db/mod.rs b/store/src/db/mod.rs index e0b47652d..e6ea9ee76 100644 --- a/store/src/db/mod.rs +++ b/store/src/db/mod.rs @@ -2,10 +2,8 @@ use std::fs::{self, create_dir_all}; use deadpool_sqlite::{Config as SqliteConfig, Hook, HookError, Pool, Runtime}; use miden_objects::{ - accounts::Account, crypto::{hash::rpo::RpoDigest, merkle::MerklePath, utils::Deserializable}, notes::Nullifier, - transaction::AccountDetails, BlockHeader, GENESIS_BLOCK, }; use rusqlite::vtab::array; @@ -201,22 +199,6 @@ impl Db { })? } - /// Loads public account details from the DB. - #[instrument(target = "miden-store", skip_all, ret(level = "debug"), err)] - pub async fn get_account_details( - &self, - id: AccountId, - ) -> Result { - self.pool - .get() - .await? - .interact(move |conn| sql::get_account_details(conn, id)) - .await - .map_err(|err| { - DatabaseError::InteractError(format!("Get account details task failed: {err}")) - })? - } - #[instrument(target = "miden-store", skip_all, ret(level = "debug"), err)] pub async fn get_state_sync( &self, @@ -261,7 +243,7 @@ impl Db { block_header: BlockHeader, notes: Vec, nullifiers: Vec, - accounts: Vec<(AccountId, Option, RpoDigest)>, + accounts: Vec<(AccountId, RpoDigest)>, ) -> Result<()> { self.pool .get() @@ -344,7 +326,7 @@ impl Db { let transaction = conn.transaction()?; let accounts: Vec<_> = account_smt .leaves() - .map(|(account_id, state_hash)| (account_id, None, state_hash.into())) + .map(|(account_id, state_hash)| (account_id, state_hash.into())) .collect(); sql::apply_block( &transaction, diff --git a/store/src/db/sql.rs b/store/src/db/sql.rs index c0cc11ea3..55d2ddf65 100644 --- a/store/src/db/sql.rs +++ b/store/src/db/sql.rs @@ -2,11 +2,8 @@ use std::rc::Rc; use miden_objects::{ - accounts::{Account, AccountCode, AccountStorage}, - assets::AssetVault, - crypto::{hash::rpo::RpoDigest, merkle::MerklePath}, + crypto::hash::rpo::RpoDigest, notes::Nullifier, - transaction::AccountDetails, utils::serde::{Deserializable, Serializable}, BlockHeader, }; @@ -33,7 +30,7 @@ pub fn select_accounts(conn: &mut Connection) -> Result> { let mut accounts = vec![]; while let Some(row) = rows.next()? { let account_hash_data = row.get_ref(1)?.as_blob()?; - let account_hash = RpoDigest::read_from_bytes(account_hash_data)?; + let account_hash = deserialize(account_hash_data)?; let account_id = column_value_as_u64(row, 0)?; let block_num = row.get(2)?; @@ -60,7 +57,7 @@ pub fn select_account_hashes(conn: &mut Connection) -> Result Result { - let mut stmt = conn.prepare( - "SELECT nonce, vault, storage, code FROM account_details WHERE account_id = ?1;", - )?; - - let mut rows = stmt.query(params![u64_to_value(account_id)])?; - let Some(row) = rows.next()? else { - return Err(DatabaseError::AccountNotOnChain(account_id)); - }; - - let account = Account::new( - account_id.try_into()?, - AssetVault::read_from_bytes(row.get_ref(1)?.as_blob()?)?, - AccountStorage::read_from_bytes(row.get_ref(2)?.as_blob()?)?, - AccountCode::read_from_bytes(row.get_ref(3)?.as_blob()?)?, - column_value_as_u64(row, 0)?.try_into().map_err(DatabaseError::CorruptedData)?, - ); - - Ok(account) -} - /// Inserts or updates accounts to the DB using the given [Transaction]. /// /// # Returns @@ -157,83 +125,16 @@ pub fn get_account_details( /// transaction. pub fn upsert_accounts( transaction: &Transaction, - accounts: &[(AccountId, Option, RpoDigest)], + accounts: &[(AccountId, RpoDigest)], block_num: BlockNumber, ) -> Result { - let mut acc_stmt = transaction.prepare( - "INSERT OR REPLACE INTO accounts (account_id, account_hash, block_num) VALUES (?1, ?2, ?3);", - )?; - let mut select_details_stmt = transaction.prepare( - "SELECT nonce, vault, storage, code FROM account_details WHERE account_id = ?1;", - )?; - let mut new_details_stmt = transaction.prepare( - "INSERT INTO account_details (account_id, nonce, vault, storage, code) VALUES (?1, ?2, ?3, ?4, ?5);" - )?; - let mut update_details_stmt = transaction.prepare( - "UPDATE account_details SET nonce = ?2, vault = ?3, storage = ?4 WHERE account_id = ?1;", - )?; + let mut stmt = transaction.prepare("INSERT OR REPLACE INTO accounts (account_id, account_hash, block_num) VALUES (?1, ?2, ?3);")?; let mut count = 0; - for (account_id, details, account_hash) in accounts.iter() { - let account_id = *account_id; - count += acc_stmt.execute(params![ - u64_to_value(account_id), - account_hash.to_bytes(), - block_num - ])?; - if let Some(details) = details { - match details { - AccountDetails::Full(account) => { - debug_assert!(account.is_new()); - debug_assert_eq!(account_id, u64::from(account.id())); - let inserted = new_details_stmt.execute(params![ - u64_to_value(account.id().into()), - u64_to_value(account.nonce().as_int()), - account.vault().to_bytes(), - account.storage().to_bytes(), - account.code().to_bytes(), - ])?; - - debug_assert_eq!(inserted, 1); - }, - AccountDetails::Delta(delta) => { - let mut rows = select_details_stmt.query(params![u64_to_value(account_id)])?; - let Some(row) = rows.next()? else { - return Err(DatabaseError::AccountNotOnChain(account_id)); - }; - - let mut account = Account::new( - account_id.try_into()?, - AssetVault::read_from_bytes(row.get_ref(1)?.as_blob()?)?, - AccountStorage::read_from_bytes(row.get_ref(2)?.as_blob()?)?, - AccountCode::read_from_bytes(row.get_ref(3)?.as_blob()?)?, - column_value_as_u64(row, 0)? - .try_into() - .map_err(DatabaseError::CorruptedData)?, - ); - - account.apply_delta(delta)?; - - if &account.hash() != account_hash { - return Err(DatabaseError::ApplyBlockFailedAccountHashesMismatch { - calculated: account.hash(), - expected: *account_hash, - }); - } - - let updated = update_details_stmt.execute(params![ - u64_to_value(account.id().into()), - u64_to_value(account.nonce().as_int()), - account.vault().to_bytes(), - account.storage().to_bytes(), - ])?; - - debug_assert_eq!(updated, 1); - }, - } - } + for (account_id, account_hash) in accounts.iter() { + count += + stmt.execute(params![u64_to_value(*account_id), account_hash.to_bytes(), block_num])? } - Ok(count) } @@ -256,7 +157,7 @@ pub fn insert_nullifiers_for_block( block_num: BlockNumber, ) -> Result { let mut stmt = transaction.prepare( - "INSERT INTO nullifiers (nullifier, nullifier_prefix, block_num) VALUES (?1, ?2, ?3);", + "INSERT INTO nullifiers (nullifier, nullifier_prefix, block_number) VALUES (?1, ?2, ?3);", )?; let mut count = 0; @@ -274,13 +175,13 @@ pub fn insert_nullifiers_for_block( /// A vector with nullifiers and the block height at which they were created, or an error. pub fn select_nullifiers(conn: &mut Connection) -> Result> { let mut stmt = - conn.prepare("SELECT nullifier, block_num FROM nullifiers ORDER BY block_num ASC;")?; + conn.prepare("SELECT nullifier, block_number FROM nullifiers ORDER BY block_number ASC;")?; let mut rows = stmt.query([])?; let mut result = vec![]; while let Some(row) = rows.next()? { let nullifier_data = row.get_ref(0)?.as_blob()?; - let nullifier = Nullifier::read_from_bytes(nullifier_data)?; + let nullifier = deserialize(nullifier_data)?; let block_number = row.get(1)?; result.push((nullifier, block_number)); } @@ -310,15 +211,15 @@ pub fn select_nullifiers_by_block_range( " SELECT nullifier, - block_num + block_number FROM nullifiers WHERE - block_num > ?1 AND - block_num <= ?2 AND + block_number > ?1 AND + block_number <= ?2 AND nullifier_prefix IN rarray(?3) ORDER BY - block_num ASC + block_number ASC ", )?; @@ -327,7 +228,7 @@ pub fn select_nullifiers_by_block_range( let mut result = Vec::new(); while let Some(row) = rows.next()? { let nullifier_data = row.get_ref(0)?.as_blob()?; - let nullifier = Nullifier::read_from_bytes(nullifier_data)?; + let nullifier = deserialize(nullifier_data)?; let block_num = row.get(1)?; result.push(NullifierInfo { nullifier, @@ -353,10 +254,10 @@ pub fn select_notes(conn: &mut Connection) -> Result> { let mut notes = vec![]; while let Some(row) = rows.next()? { let note_id_data = row.get_ref(2)?.as_blob()?; - let note_id = RpoDigest::read_from_bytes(note_id_data)?; + let note_id = deserialize(note_id_data)?; let merkle_path_data = row.get_ref(5)?.as_blob()?; - let merkle_path = MerklePath::read_from_bytes(merkle_path_data)?; + let merkle_path = deserialize(merkle_path_data)?; notes.push(Note { block_num: row.get(0)?, @@ -477,11 +378,11 @@ pub fn select_notes_since_block_by_tag_and_sender( let block_num = row.get(0)?; let note_index = row.get(1)?; let note_id_data = row.get_ref(2)?.as_blob()?; - let note_id = RpoDigest::read_from_bytes(note_id_data)?; + let note_id = deserialize(note_id_data)?; let sender = column_value_as_u64(row, 3)?; let tag = column_value_as_u64(row, 4)?; let merkle_path_data = row.get_ref(5)?.as_blob()?; - let merkle_path = MerklePath::read_from_bytes(merkle_path_data)?; + let merkle_path = deserialize(merkle_path_data)?; let note = Note { block_num, @@ -547,7 +448,7 @@ pub fn select_block_header_by_block_num( match rows.next()? { Some(row) => { let data = row.get_ref(0)?.as_blob()?; - Ok(Some(BlockHeader::read_from_bytes(data)?)) + Ok(Some(deserialize(data)?)) }, None => Ok(None), } @@ -565,7 +466,7 @@ pub fn select_block_headers(conn: &mut Connection) -> Result> { let mut result = vec![]; while let Some(row) = rows.next()? { let block_header_data = row.get_ref(0)?.as_blob()?; - let block_header = BlockHeader::read_from_bytes(block_header_data)?; + let block_header = deserialize(block_header_data)?; result.push(block_header); } @@ -637,7 +538,7 @@ pub fn apply_block( block_header: &BlockHeader, notes: &[Note], nullifiers: &[Nullifier], - accounts: &[(AccountId, Option, RpoDigest)], + accounts: &[(AccountId, RpoDigest)], ) -> Result { let mut count = 0; count += insert_block_header(transaction, block_header)?; @@ -650,6 +551,11 @@ pub fn apply_block( // UTILITIES // ================================================================================================ +/// Decodes a blob from the database into a corresponding deserializable. +fn deserialize(data: &[u8]) -> Result { + T::read_from_bytes(data).map_err(DatabaseError::DeserializationError) +} + /// Returns the high 16 bits of the provided nullifier. pub(crate) fn get_nullifier_prefix(nullifier: &Nullifier) -> u32 { (nullifier.most_significant_felt().as_int() >> 48) as u32 diff --git a/store/src/db/tests.rs b/store/src/db/tests.rs index 406a72b34..57af54176 100644 --- a/store/src/db/tests.rs +++ b/store/src/db/tests.rs @@ -1,26 +1,15 @@ -use miden_lib::transaction::TransactionKernel; -use miden_mock::mock::account::{ - generate_account_seed, mock_account_code, AccountSeedType, - ACCOUNT_ID_NON_FUNGIBLE_FAUCET_ON_CHAIN, -}; use miden_objects::{ - accounts::{ - Account, AccountDelta, AccountId, AccountStorage, AccountStorageDelta, AccountVaultDelta, - ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN, - }, - assets::{Asset, AssetVault, FungibleAsset, NonFungibleAsset, NonFungibleAssetDetails}, crypto::{ hash::rpo::RpoDigest, merkle::{LeafIndex, MerklePath, SimpleSmt}, }, notes::{Nullifier, NOTE_LEAF_DEPTH}, - transaction::AccountDetails, - BlockHeader, Felt, FieldElement, Word, ONE, ZERO, + BlockHeader, Felt, FieldElement, }; use rusqlite::{vtab::array, Connection}; use super::{sql, AccountInfo, Note, NoteCreated, NullifierInfo}; -use crate::{db::migrations, errors::DatabaseError}; +use crate::db::migrations; fn create_db() -> Connection { let mut conn = Connection::open_in_memory().unwrap(); @@ -181,8 +170,7 @@ fn test_sql_select_accounts() { }); let transaction = conn.transaction().unwrap(); - let res = - sql::upsert_accounts(&transaction, &[(account_id, None, account_hash)], block_num); + let res = sql::upsert_accounts(&transaction, &[(account_id, account_hash)], block_num); assert_eq!(res.unwrap(), 1, "One element must have been inserted"); transaction.commit().unwrap(); let accounts = sql::select_accounts(&mut conn).unwrap(); @@ -190,124 +178,6 @@ fn test_sql_select_accounts() { } } -#[test] -fn test_sql_public_account_details() { - let mut conn = create_db(); - - let block_num = 1; - create_block(&mut conn, block_num); - - let (account_id, _seed) = - generate_account_seed(AccountSeedType::RegularAccountUpdatableCodeOnChain); - let fungible_faucet_id = AccountId::try_from(ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN).unwrap(); - let non_fungible_faucet_id = - AccountId::try_from(ACCOUNT_ID_NON_FUNGIBLE_FAUCET_ON_CHAIN).unwrap(); - - let mut storage = AccountStorage::new(vec![]).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(), - ) - .unwrap(), - ); - - let mut account = Account::new( - account_id, - AssetVault::new(&[ - Asset::Fungible(FungibleAsset::new(fungible_faucet_id, 150).unwrap()), - nft1, - ]) - .unwrap(), - storage, - mock_account_code(&TransactionKernel::assembler()), - ZERO, - ); - - // test querying empty table - let res = sql::get_account_details(&mut conn, account_id.into()); - assert!(matches!(res, Err(DatabaseError::AccountNotOnChain(_)))); - - let transaction = conn.transaction().unwrap(); - let inserted = sql::upsert_accounts( - &transaction, - &[(account_id.into(), Some(AccountDetails::Full(account.clone())), account.hash())], - block_num, - ) - .unwrap(); - - assert_eq!(inserted, 1, "One element must have been inserted"); - - transaction.commit().unwrap(); - - let account_read = sql::get_account_details(&mut conn, account_id.into()).unwrap(); - - // TODO: substitute by a single check, once code imports deserialization is fixed: - // assert_eq!(account_read, account); - assert_eq!(account_read.id(), account.id()); - assert_eq!(account_read.vault(), account.vault()); - assert_eq!(account_read.storage(), account.storage()); - assert_eq!(account_read.nonce(), account.nonce()); - - let storage_delta = AccountStorageDelta { - cleared_items: vec![3], - updated_items: vec![(4, num_to_word(5)), (5, num_to_word(6))], - }; - - let nft2 = Asset::NonFungible( - NonFungibleAsset::new( - &NonFungibleAssetDetails::new(non_fungible_faucet_id, vec![4, 5, 6]).unwrap(), - ) - .unwrap(), - ); - - let vault_delta = AccountVaultDelta { - added_assets: vec![nft2], - removed_assets: vec![nft1], - }; - - let delta = AccountDelta::new(storage_delta, vault_delta, Some(ONE)).unwrap(); - - account.apply_delta(&delta).unwrap(); - - let transaction = conn.transaction().unwrap(); - let inserted = sql::upsert_accounts( - &transaction, - &[(account_id.into(), Some(AccountDetails::Delta(delta.clone())), account.hash())], - block_num, - ) - .unwrap(); - - assert_eq!(inserted, 1, "One element must have been inserted"); - - transaction.commit().unwrap(); - - let mut account_read = sql::get_account_details(&mut conn, account_id.into()).unwrap(); - - assert_eq!(account_read.id(), account.id()); - assert_eq!(account_read.vault(), account.vault()); - 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()); - - let storage_delta = AccountStorageDelta { - cleared_items: vec![3], - updated_items: vec![], - }; - account_read - .apply_delta( - &AccountDelta::new(storage_delta, AccountVaultDelta::default(), Some(Felt::new(2))) - .unwrap(), - ) - .unwrap(); - - assert_eq!(account_read.storage(), account.storage()); -} - #[test] fn test_sql_select_nullifiers_by_block_range() { let mut conn = create_db(); @@ -515,7 +385,7 @@ fn test_db_account() { let transaction = conn.transaction().unwrap(); let row_count = - sql::upsert_accounts(&transaction, &[(account_id, None, account_hash)], block_num).unwrap(); + sql::upsert_accounts(&transaction, &[(account_id, account_hash)], block_num).unwrap(); transaction.commit().unwrap(); assert_eq!(row_count, 1); @@ -648,11 +518,7 @@ fn test_notes() { // UTILITIES // ------------------------------------------------------------------------------------------- fn num_to_rpo_digest(n: u64) -> RpoDigest { - RpoDigest::new(num_to_word(n)) -} - -fn num_to_word(n: u64) -> Word { - [Felt::ZERO, Felt::ZERO, Felt::ZERO, Felt::new(n)] + RpoDigest::new([Felt::ZERO, Felt::ZERO, Felt::ZERO, Felt::new(n)]) } fn num_to_nullifier(n: u64) -> Nullifier { diff --git a/store/src/errors.rs b/store/src/errors.rs index c5b8d4d13..2856b5f96 100644 --- a/store/src/errors.rs +++ b/store/src/errors.rs @@ -3,7 +3,6 @@ use std::io; use deadpool_sqlite::PoolError; use miden_objects::{ crypto::{ - hash::rpo::RpoDigest, merkle::{MerkleError, MmrError}, utils::DeserializationError, }, @@ -14,7 +13,7 @@ use rusqlite::types::FromSqlError; use thiserror::Error; use tokio::sync::oneshot::error::RecvError; -use crate::types::{AccountId, BlockNumber}; +use crate::types::BlockNumber; // INTERNAL ERRORS // ================================================================================================= @@ -47,32 +46,8 @@ pub enum DatabaseError { InteractError(String), #[error("Deserialization of BLOB data from database failed: {0}")] DeserializationError(DeserializationError), - #[error("Corrupted data: {0}")] - CorruptedData(String), - #[error("Account error: {0}")] - AccountError(AccountError), #[error("Block applying was broken because of closed channel on state side: {0}")] ApplyBlockFailedClosedChannel(RecvError), - #[error("Public account ({0}) details not found on-chain")] - AccountNotOnChain(AccountId), - #[error("Failed to apply block because of on-chain account final hashes mismatch (expected {expected}, \ - but calculated is {calculated}")] - ApplyBlockFailedAccountHashesMismatch { - expected: RpoDigest, - calculated: RpoDigest, - }, -} - -impl From for DatabaseError { - fn from(value: DeserializationError) -> Self { - Self::DeserializationError(value) - } -} - -impl From for DatabaseError { - fn from(value: AccountError) -> Self { - Self::AccountError(value) - } } // INITIALIZATION ERRORS diff --git a/store/src/server/api.rs b/store/src/server/api.rs index d229c374e..aa64855bd 100644 --- a/store/src/server/api.rs +++ b/store/src/server/api.rs @@ -8,22 +8,22 @@ use miden_node_proto::{ note::NoteSyncRecord, requests::{ ApplyBlockRequest, CheckNullifiersRequest, GetBlockHeaderByNumberRequest, - GetBlockInputsRequest, GetPublicAccountDetailsRequest, GetTransactionInputsRequest, - ListAccountsRequest, ListNotesRequest, ListNullifiersRequest, SyncStateRequest, + GetBlockInputsRequest, GetTransactionInputsRequest, ListAccountsRequest, + ListNotesRequest, ListNullifiersRequest, SyncStateRequest, }, responses::{ AccountHashUpdate, AccountTransactionInputRecord, ApplyBlockResponse, CheckNullifiersResponse, GetBlockHeaderByNumberResponse, GetBlockInputsResponse, - GetPublicAccountDetailsResponse, GetTransactionInputsResponse, ListAccountsResponse, - ListNotesResponse, ListNullifiersResponse, NullifierTransactionInputRecord, - NullifierUpdate, SyncStateResponse, + GetTransactionInputsResponse, ListAccountsResponse, ListNotesResponse, + ListNullifiersResponse, NullifierTransactionInputRecord, NullifierUpdate, + SyncStateResponse, }, smt::SmtLeafEntry, store::api_server, }, AccountState, }; -use miden_objects::{notes::Nullifier, transaction::AccountDetails, BlockHeader, Felt, ZERO}; +use miden_objects::{notes::Nullifier, BlockHeader, Felt, ZERO}; use tonic::{Response, Status}; use tracing::{debug, info, instrument}; @@ -159,32 +159,6 @@ impl api_server::Api for StoreApi { })) } - /// Returns details for public (on-chain) account by id. - #[instrument( - target = "miden-store", - name = "store:get_public_account_details", - skip_all, - ret(level = "debug"), - err - )] - async fn get_public_account_details( - &self, - request: tonic::Request, - ) -> Result, Status> { - let request = request.into_inner(); - let account = self - .state - .get_account_details( - request.account_id.ok_or(invalid_argument("Account missing id"))?.into(), - ) - .await - .map_err(internal_error)?; - - Ok(Response::new(GetPublicAccountDetailsResponse { - details: Some((&account).into()), - })) - } - // BLOCK PRODUCER ENDPOINTS // -------------------------------------------------------------------------------------------- @@ -216,16 +190,11 @@ impl api_server::Api for StoreApi { .accounts .into_iter() .map(|account_update| { - let account_details: Option = - account_update.details.as_ref().map(TryInto::try_into).transpose().map_err( - |err: ConversionError| Status::invalid_argument(err.to_string()), - )?; let account_state: AccountState = account_update .try_into() .map_err(|err: ConversionError| Status::invalid_argument(err.to_string()))?; Ok(( account_state.account_id.into(), - account_details, account_state .account_hash .ok_or(invalid_argument("Account update missing account hash"))?, diff --git a/store/src/state.rs b/store/src/state.rs index e53d54386..d27bb2611 100644 --- a/store/src/state.rs +++ b/store/src/state.rs @@ -7,13 +7,11 @@ use std::{mem, sync::Arc}; use miden_node_proto::{AccountInputRecord, NullifierWitness}; use miden_node_utils::formatting::{format_account_id, format_array}; use miden_objects::{ - accounts::Account, crypto::{ hash::rpo::RpoDigest, merkle::{LeafIndex, Mmr, MmrDelta, MmrPeaks, SimpleSmt, SmtProof, ValuePath}, }, notes::{NoteMetadata, NoteType, Nullifier, NOTE_LEAF_DEPTH}, - transaction::AccountDetails, AccountError, BlockHeader, Word, ACCOUNT_TREE_DEPTH, }; use tokio::{ @@ -107,7 +105,7 @@ impl State { &self, block_header: BlockHeader, nullifiers: Vec, - accounts: Vec<(AccountId, Option, RpoDigest)>, + accounts: Vec<(AccountId, RpoDigest)>, notes: Vec, ) -> Result<(), ApplyBlockError> { let _ = self.writer.try_lock().map_err(|_| ApplyBlockError::ConcurrentWrite)?; @@ -181,7 +179,7 @@ impl State { // update account tree let mut account_tree = inner.account_tree.clone(); - for (account_id, _, account_hash) in accounts.iter() { + for (account_id, account_hash) in accounts.iter() { account_tree.insert(LeafIndex::new_max_depth(*account_id), account_hash.into()); } @@ -469,14 +467,6 @@ impl State { pub async fn list_notes(&self) -> Result, DatabaseError> { self.db.select_notes().await } - - /// Returns details for public (on-chain) account. - pub async fn get_account_details( - &self, - id: AccountId, - ) -> Result { - self.db.get_account_details(id).await - } } // UTILITIES