Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Chain Data tables #63

Merged
merged 26 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cli/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ pub fn show_account(

println!(
"Storage: {}\n",
serde_json::to_string(&account_storage)
serde_json::to_string(&account_storage.slots())
.map_err(|_| "Error serializing account storage")?
);
}
Expand Down
3 changes: 2 additions & 1 deletion src/cli/input_notes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ use std::path::PathBuf;

use super::{Client, Parser};
use comfy_table::{presets, Attribute, Cell, ContentArrangement, Table};
use crypto::utils::{Deserializable, Serializable};
use miden_client::store::notes::InputNoteFilter;

use crypto::utils::{Deserializable, Serializable};
use objects::notes::RecordedNote;
use objects::Digest;

Expand Down
1 change: 1 addition & 0 deletions src/cli/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use comfy_table::Attribute;
use comfy_table::Cell;
use comfy_table::ContentArrangement;
use comfy_table::Table;

use miden_client::client::transactions::PaymentTransactionData;
use miden_client::client::transactions::TransactionStub;
use miden_client::client::transactions::TransactionTemplate;
Expand Down
12 changes: 3 additions & 9 deletions src/client/accounts.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use super::Client;

use std::collections::BTreeMap;

use crypto::{Felt, Word};
use crypto::Felt;
use miden_lib::{faucets, AuthScheme};
use objects::{
accounts::{Account, AccountId, AccountStub, AccountType},
accounts::{Account, AccountId, AccountStorage, AccountStub, AccountType},
assembly::ModuleAst,
assets::{Asset, TokenSymbol},
Digest,
Expand Down Expand Up @@ -188,10 +185,7 @@ impl Client {
}

/// Returns account storage data from a storage root.
pub fn get_account_storage(
&self,
storage_root: Digest,
) -> Result<BTreeMap<u64, Word>, ClientError> {
pub fn get_account_storage(&self, storage_root: Digest) -> Result<AccountStorage, ClientError> {
self.store
.get_account_storage(storage_root)
.map_err(|err| err.into())
Expand Down
24 changes: 24 additions & 0 deletions src/client/chain_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use super::Client;

#[cfg(test)]
use crate::errors::ClientError;
#[cfg(test)]
use objects::BlockHeader;

impl Client {
#[cfg(test)]
pub fn get_block_headers(
&self,
start: u32,
finish: u32,
) -> Result<Vec<BlockHeader>, ClientError> {
let mut headers = Vec::new();
for block_number in start..=finish {
if let Ok(block_header) = self.store.get_block_header_by_num(block_number) {
headers.push(block_header)
}
}

Ok(headers)
}
juan518munoz marked this conversation as resolved.
Show resolved Hide resolved
}
29 changes: 17 additions & 12 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ use crate::{
store::{mock_executor_data_store::MockDataStore, Store},
};

#[cfg(not(any(test, feature = "testing")))]
use crate::errors::RpcApiError;

use miden_tx::TransactionExecutor;

#[cfg(any(test, feature = "testing"))]
#[cfg(feature = "testing")]
use crate::mock::MockRpcApi;

pub mod accounts;
pub mod chain_data;
pub mod notes;
pub mod sync_state;
pub mod transactions;
Expand All @@ -37,11 +35,9 @@ pub const FILTER_ID_SHIFT: u8 = 48;
pub struct Client {
/// Local database containing information about the accounts managed by this client.
pub(crate) store: Store,
#[cfg(not(any(test, feature = "testing")))]
/// Api client for interacting with the Miden node.
rpc_api: miden_node_proto::rpc::api_client::ApiClient<tonic::transport::Channel>,
#[cfg(any(test, feature = "testing"))]
pub rpc_api: MockRpcApi,
#[cfg(any(test, feature = "testing"))]
pub(crate) tx_executor: TransactionExecutor<MockDataStore>,
}

Expand All @@ -54,17 +50,26 @@ impl Client {
/// # Errors
/// Returns an error if the client could not be instantiated.
pub async fn new(config: ClientConfig) -> Result<Self, ClientError> {
Ok(Self {
#[cfg(not(any(test, feature = "testing")))]
return Ok(Self {
store: Store::new((&config).into())?,
#[cfg(not(any(test, feature = "testing")))]
rpc_api: miden_node_proto::rpc::api_client::ApiClient::connect(
config.node_endpoint.to_string(),
)
.await
.map_err(|err| ClientError::RpcApiError(RpcApiError::ConnectionError(err)))?,
#[cfg(any(test, feature = "testing"))]
.map_err(|err| {
ClientError::RpcApiError(crate::errors::RpcApiError::ConnectionError(err))
})?,
tx_executor: TransactionExecutor::new(crate::store::data_store::SqliteDataStore::new(
Store::new((&config).into())?,
)),
});

#[cfg(any(test, feature = "testing"))]
return Ok(Self {
store: Store::new((&config).into())?,
rpc_api: Default::default(),
tx_executor: TransactionExecutor::new(MockDataStore::new()),
})
});
}
}
36 changes: 30 additions & 6 deletions src/client/sync_state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::Client;

use crypto::StarkField;
use miden_node_proto::{
account_id::AccountId as ProtoAccountId, requests::SyncStateRequest,
Expand All @@ -9,6 +8,11 @@ use objects::{accounts::AccountId, Digest};

use crate::errors::{ClientError, RpcApiError};

pub enum SyncStatus {
SyncedToLastBlock(u32),
SyncedToBlock(u32),
}

// CONSTANTS
// ================================================================================================

Expand Down Expand Up @@ -47,16 +51,25 @@ impl Client {
///
/// Returns the block number the client has been synced to.
pub async fn sync_state(&mut self) -> Result<u32, ClientError> {
loop {
let response = self.single_sync_state().await?;
if let SyncStatus::SyncedToLastBlock(v) = response {
return Ok(v);
}
}
}

async fn single_sync_state(&mut self) -> Result<SyncStatus, ClientError> {
let block_num = self.store.get_latest_block_number()?;
let account_ids = self.store.get_account_ids()?;
let note_tags = self.store.get_note_tags()?;
let nullifiers = self.store.get_unspent_input_note_nullifiers()?; // breaks

let nullifiers = self.store.get_unspent_input_note_nullifiers()?;
let response = self
.sync_state_request(block_num, &account_ids, &note_tags, &nullifiers)
.await?;
let incoming_block_header = response.block_header.unwrap();

let new_block_num = response.chain_tip;
let new_block_num = incoming_block_header.block_num;
let new_nullifiers = response
.nullifiers
.into_iter()
Expand All @@ -71,10 +84,21 @@ impl Client {
.collect::<Vec<_>>();

self.store
.apply_state_sync(new_block_num, new_nullifiers)
.apply_state_sync(
incoming_block_header
.try_into()
.map_err(ClientError::RpcTypeConversionFailure)?,
new_nullifiers,
response.accounts,
response.mmr_delta,
)
.map_err(ClientError::StoreError)?;

Ok(new_block_num)
if response.chain_tip == new_block_num {
Ok(SyncStatus::SyncedToLastBlock(response.chain_tip))
} else {
Ok(SyncStatus::SyncedToBlock(new_block_num))
}
}

// HELPERS
Expand Down
13 changes: 6 additions & 7 deletions src/client/transactions.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use crate::{
errors::{self, ClientError},
store::mock_executor_data_store::{self, MockDataStore},
};
use crypto::utils::Serializable;
use miden_lib::notes::{create_note, Script};
use miden_node_proto::{
Expand All @@ -14,11 +18,6 @@ use objects::{
};
use rand::Rng;

use crate::{
errors::{self, ClientError},
store::{self, mock_executor_data_store::MockDataStore},
};

use super::Client;

pub enum TransactionTemplate {
Expand Down Expand Up @@ -143,8 +142,8 @@ impl Client {
) -> Result<(TransactionResult, TransactionScript), ClientError> {
// Create assets
let (target_pub_key, target_sk_pk_felt) =
store::mock_executor_data_store::get_new_key_pair_with_advice_map();
let target_account = store::mock_executor_data_store::get_account_with_default_account_code(
mock_executor_data_store::get_new_key_pair_with_advice_map();
let target_account = mock_executor_data_store::get_account_with_default_account_code(
target_account_id,
target_pub_key,
None,
Expand Down
29 changes: 25 additions & 4 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use core::fmt;
use crypto::{
dsa::rpo_falcon512::FalconError,
utils::{DeserializationError, HexParseError},
};
use crypto::merkle::MmrError;
use crypto::utils::DeserializationError;
use crypto::{dsa::rpo_falcon512::FalconError, utils::HexParseError};
use miden_node_proto::error::ParseError;
use miden_tx::{TransactionExecutorError, TransactionProverError};
use objects::AssetError;
use objects::{accounts::AccountId, AccountError, Digest, NoteError, TransactionScriptError};
use tonic::{transport::Error as TransportError, Status as TonicStatus};

Expand All @@ -13,7 +14,9 @@ use tonic::{transport::Error as TransportError, Status as TonicStatus};
#[derive(Debug)]
pub enum ClientError {
AccountError(AccountError),
AssetError(AssetError),
AuthError(FalconError),
RpcTypeConversionFailure(ParseError),
NoteError(NoteError),
RpcApiError(RpcApiError),
StoreError(StoreError),
Expand All @@ -25,7 +28,11 @@ impl fmt::Display for ClientError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ClientError::AccountError(err) => write!(f, "account error: {err}"),
ClientError::AssetError(err) => write!(f, "asset error: {err}"),
ClientError::AuthError(err) => write!(f, "account auth error: {err}"),
ClientError::RpcTypeConversionFailure(err) => {
write!(f, "failed to convert data: {err}")
}
ClientError::NoteError(err) => write!(f, "note error: {err}"),
ClientError::RpcApiError(err) => write!(f, "rpc api error: {err}"),
ClientError::StoreError(err) => write!(f, "store error: {err}"),
Expand Down Expand Up @@ -56,7 +63,9 @@ pub enum StoreError {
AccountCodeDataNotFound(Digest),
AccountDataNotFound(AccountId),
AccountError(AccountError),
AccountHashMismatch(AccountId),
AccountStorageNotFound(Digest),
ChainMmrNodeNotFound(u64),
ColumnParsingError(rusqlite::Error),
ConnectionError(rusqlite::Error),
DataDeserializationError(DeserializationError),
Expand All @@ -65,9 +74,11 @@ pub enum StoreError {
InputSerializationError(serde_json::Error),
JsonDataDeserializationError(serde_json::Error),
MigrationError(rusqlite_migration::Error),
MmrError(MmrError),
NoteTagAlreadyTracked(u64),
QueryError(rusqlite::Error),
TransactionError(rusqlite::Error),
BlockHeaderNotFound(u32),
TransactionScriptError(TransactionScriptError),
VaultDataNotFound(Digest),
}
Expand All @@ -83,12 +94,18 @@ impl fmt::Display for StoreError {
write!(f, "Account data was not found for Account Id {account_id}")
}
AccountError(err) => write!(f, "error instantiating Account: {err}"),
AccountHashMismatch(account_id) => {
write!(f, "account hash mismatch for account {account_id}")
}
AccountStorageNotFound(root) => {
write!(f, "account storage data with root {} not found", root)
}
ColumnParsingError(err) => {
write!(f, "failed to parse data retrieved from the database: {err}")
}
ChainMmrNodeNotFound(node_index) => {
write!(f, "chain mmr node at index {} not found", node_index)
}
ConnectionError(err) => write!(f, "failed to connect to the database: {err}"),
DataDeserializationError(err) => {
write!(f, "error deserializing data from the store: {err}")
Expand All @@ -107,13 +124,17 @@ impl fmt::Display for StoreError {
)
}
MigrationError(err) => write!(f, "failed to update the database: {err}"),
MmrError(err) => write!(f, "error constructing mmr: {err}"),
NoteTagAlreadyTracked(tag) => write!(f, "note tag {} is already being tracked", tag),
QueryError(err) => write!(f, "failed to retrieve data from the database: {err}"),
TransactionError(err) => write!(f, "failed to instantiate a new transaction: {err}"),
TransactionScriptError(err) => {
write!(f, "error instantiating transaction script: {err}")
}
VaultDataNotFound(root) => write!(f, "account vault data for root {} not found", root),
BlockHeaderNotFound(block_num) => {
write!(f, "block header for block {} not found", block_num)
}
}
}
}
Expand Down
Loading
Loading