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

Implemented GetAccountProofs endpoint #506

Merged
merged 14 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from 9 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- [BREAKING] Changed `GetAccountDetailsResponse` field to `details` (#481).
- Improve `--version` by adding build metadata (#495).
- [BREAKING] Introduced additional limits for note/account number (#503).
- Added `GetAccountStates` endpoint (#506).

## 0.5.1 (2024-09-12)

Expand Down
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 14 additions & 3 deletions crates/proto/src/domain/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt::{Debug, Display, Formatter};

use miden_node_utils::formatting::format_opt;
use miden_objects::{
accounts::{Account, AccountId},
accounts::{Account, AccountHeader, AccountId},
crypto::{hash::rpo::RpoDigest, merkle::MerklePath},
utils::Serializable,
Digest,
Expand All @@ -12,8 +12,8 @@ use crate::{
errors::{ConversionError, MissingFieldHelper},
generated::{
account::{
AccountId as AccountIdPb, AccountInfo as AccountInfoPb,
AccountSummary as AccountSummaryPb,
AccountHeader as AccountHeaderPb, AccountId as AccountIdPb,
AccountInfo as AccountInfoPb, AccountSummary as AccountSummaryPb,
},
responses::{AccountBlockInputRecord, AccountTransactionInputRecord},
},
Expand Down Expand Up @@ -180,6 +180,17 @@ impl From<AccountState> for AccountTransactionInputRecord {
}
}

impl From<AccountHeader> for AccountHeaderPb {
fn from(from: AccountHeader) -> Self {
Self {
vault_root: Some(from.vault_root().into()),
storage_commitment: Some(from.storage_commitment().into()),
code_commitment: Some(from.code_commitment().into()),
nonce: from.nonce().into(),
}
}
}

impl TryFrom<AccountTransactionInputRecord> for AccountState {
type Error = ConversionError;

Expand Down
6 changes: 6 additions & 0 deletions crates/proto/src/domain/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ impl From<&MerklePath> for generated::merkle::MerklePath {
}
}

impl From<MerklePath> for generated::merkle::MerklePath {
fn from(value: MerklePath) -> Self {
(&value).into()
}
}

impl TryFrom<&generated::merkle::MerklePath> for MerklePath {
type Error = ConversionError;

Expand Down
15 changes: 15 additions & 0 deletions crates/proto/src/generated/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,18 @@ pub struct AccountInfo {
#[prost(bytes = "vec", optional, tag = "2")]
pub details: ::core::option::Option<::prost::alloc::vec::Vec<u8>>,
}
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct AccountHeader {
/// Vault root hash.
#[prost(message, optional, tag = "1")]
pub vault_root: ::core::option::Option<super::digest::Digest>,
/// Storage root hash.
#[prost(message, optional, tag = "2")]
pub storage_commitment: ::core::option::Option<super::digest::Digest>,
/// Code root hash.
#[prost(message, optional, tag = "3")]
pub code_commitment: ::core::option::Option<super::digest::Digest>,
/// Account nonce.
#[prost(uint64, tag = "4")]
pub nonce: u64,
}
9 changes: 9 additions & 0 deletions crates/proto/src/generated/requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,12 @@ pub struct GetAccountStateDeltaRequest {
#[prost(fixed32, tag = "3")]
pub to_block_num: u32,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetAccountStatesRequest {
/// List of account IDs to get states.
#[prost(message, repeated, tag = "1")]
pub account_ids: ::prost::alloc::vec::Vec<super::account::AccountId>,
/// Optional flag to include header in the response. `false` by default.
#[prost(bool, optional, tag = "2")]
pub include_headers: ::core::option::Option<bool>,
}
33 changes: 33 additions & 0 deletions crates/proto/src/generated/responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,36 @@ pub struct GetAccountStateDeltaResponse {
#[prost(bytes = "vec", optional, tag = "1")]
pub delta: ::core::option::Option<::prost::alloc::vec::Vec<u8>>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetAccountStatesResponse {
/// Block number at which the state of the account was returned.
#[prost(fixed32, tag = "1")]
pub block_num: u32,
/// List of account state infos for the requested account keys.
#[prost(message, repeated, tag = "2")]
pub account_state_infos: ::prost::alloc::vec::Vec<AccountStateResponse>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AccountStateResponse {
/// Account ID.
#[prost(message, optional, tag = "1")]
pub account_id: ::core::option::Option<super::account::AccountId>,
/// Account hash.
#[prost(message, optional, tag = "2")]
pub account_hash: ::core::option::Option<super::digest::Digest>,
/// Authentication path from the `account_root` of the block header to the account.
#[prost(message, optional, tag = "3")]
pub account_proof: ::core::option::Option<super::merkle::MerklePath>,
/// / State header for public accounts. Filled only if `include_headers` flag is set to `true`.
#[prost(message, optional, tag = "4")]
pub state_header: ::core::option::Option<AccountStateHeader>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AccountStateHeader {
/// Account header.
#[prost(message, optional, tag = "1")]
pub header: ::core::option::Option<super::account::AccountHeader>,
/// / Values of all account storage slots (max 255).
#[prost(bytes = "vec", tag = "2")]
pub storage_header: ::prost::alloc::vec::Vec<u8>,
}
78 changes: 78 additions & 0 deletions crates/proto/src/generated/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,29 @@ pub mod api_client {
req.extensions_mut().insert(GrpcMethod::new("rpc.Api", "GetAccountDetails"));
self.inner.unary(req, path, codec).await
}
pub async fn get_account_states(
&mut self,
request: impl tonic::IntoRequest<
super::super::requests::GetAccountStatesRequest,
>,
) -> std::result::Result<
tonic::Response<super::super::responses::GetAccountStatesResponse>,
tonic::Status,
> {
self.inner
.ready()
.await
.map_err(|e| {
tonic::Status::unknown(
format!("Service was not ready: {}", e.into()),
)
})?;
let codec = tonic::codec::ProstCodec::default();
let path = http::uri::PathAndQuery::from_static("/rpc.Api/GetAccountStates");
let mut req = request.into_request();
req.extensions_mut().insert(GrpcMethod::new("rpc.Api", "GetAccountStates"));
self.inner.unary(req, path, codec).await
}
pub async fn get_account_state_delta(
&mut self,
request: impl tonic::IntoRequest<
Expand Down Expand Up @@ -366,6 +389,13 @@ pub mod api_server {
tonic::Response<super::super::responses::GetAccountDetailsResponse>,
tonic::Status,
>;
async fn get_account_states(
&self,
request: tonic::Request<super::super::requests::GetAccountStatesRequest>,
) -> std::result::Result<
tonic::Response<super::super::responses::GetAccountStatesResponse>,
tonic::Status,
>;
async fn get_account_state_delta(
&self,
request: tonic::Request<super::super::requests::GetAccountStateDeltaRequest>,
Expand Down Expand Up @@ -641,6 +671,54 @@ pub mod api_server {
};
Box::pin(fut)
}
"/rpc.Api/GetAccountStates" => {
#[allow(non_camel_case_types)]
struct GetAccountStatesSvc<T: Api>(pub Arc<T>);
impl<
T: Api,
> tonic::server::UnaryService<
super::super::requests::GetAccountStatesRequest,
> for GetAccountStatesSvc<T> {
type Response = super::super::responses::GetAccountStatesResponse;
type Future = BoxFuture<
tonic::Response<Self::Response>,
tonic::Status,
>;
fn call(
&mut self,
request: tonic::Request<
super::super::requests::GetAccountStatesRequest,
>,
) -> Self::Future {
let inner = Arc::clone(&self.0);
let fut = async move {
<T as Api>::get_account_states(&inner, request).await
};
Box::pin(fut)
}
}
let accept_compression_encodings = self.accept_compression_encodings;
let send_compression_encodings = self.send_compression_encodings;
let max_decoding_message_size = self.max_decoding_message_size;
let max_encoding_message_size = self.max_encoding_message_size;
let inner = self.inner.clone();
let fut = async move {
let method = GetAccountStatesSvc(inner);
let codec = tonic::codec::ProstCodec::default();
let mut grpc = tonic::server::Grpc::new(codec)
.apply_compression_config(
accept_compression_encodings,
send_compression_encodings,
)
.apply_max_message_size_config(
max_decoding_message_size,
max_encoding_message_size,
);
let res = grpc.unary(method, req).await;
Ok(res)
};
Box::pin(fut)
}
"/rpc.Api/GetAccountStateDelta" => {
#[allow(non_camel_case_types)]
struct GetAccountStateDeltaSvc<T: Api>(pub Arc<T>);
Expand Down
81 changes: 81 additions & 0 deletions crates/proto/src/generated/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,32 @@ pub mod api_client {
.insert(GrpcMethod::new("store.Api", "GetAccountDetails"));
self.inner.unary(req, path, codec).await
}
pub async fn get_account_states(
&mut self,
request: impl tonic::IntoRequest<
super::super::requests::GetAccountStatesRequest,
>,
) -> std::result::Result<
tonic::Response<super::super::responses::GetAccountStatesResponse>,
tonic::Status,
> {
self.inner
.ready()
.await
.map_err(|e| {
tonic::Status::unknown(
format!("Service was not ready: {}", e.into()),
)
})?;
let codec = tonic::codec::ProstCodec::default();
let path = http::uri::PathAndQuery::from_static(
"/store.Api/GetAccountStates",
);
let mut req = request.into_request();
req.extensions_mut()
.insert(GrpcMethod::new("store.Api", "GetAccountStates"));
self.inner.unary(req, path, codec).await
}
pub async fn get_account_state_delta(
&mut self,
request: impl tonic::IntoRequest<
Expand Down Expand Up @@ -514,6 +540,13 @@ pub mod api_server {
tonic::Response<super::super::responses::GetAccountDetailsResponse>,
tonic::Status,
>;
async fn get_account_states(
&self,
request: tonic::Request<super::super::requests::GetAccountStatesRequest>,
) -> std::result::Result<
tonic::Response<super::super::responses::GetAccountStatesResponse>,
tonic::Status,
>;
async fn get_account_state_delta(
&self,
request: tonic::Request<super::super::requests::GetAccountStateDeltaRequest>,
Expand Down Expand Up @@ -872,6 +905,54 @@ pub mod api_server {
};
Box::pin(fut)
}
"/store.Api/GetAccountStates" => {
#[allow(non_camel_case_types)]
struct GetAccountStatesSvc<T: Api>(pub Arc<T>);
impl<
T: Api,
> tonic::server::UnaryService<
super::super::requests::GetAccountStatesRequest,
> for GetAccountStatesSvc<T> {
type Response = super::super::responses::GetAccountStatesResponse;
type Future = BoxFuture<
tonic::Response<Self::Response>,
tonic::Status,
>;
fn call(
&mut self,
request: tonic::Request<
super::super::requests::GetAccountStatesRequest,
>,
) -> Self::Future {
let inner = Arc::clone(&self.0);
let fut = async move {
<T as Api>::get_account_states(&inner, request).await
};
Box::pin(fut)
}
}
let accept_compression_encodings = self.accept_compression_encodings;
let send_compression_encodings = self.send_compression_encodings;
let max_decoding_message_size = self.max_decoding_message_size;
let max_encoding_message_size = self.max_encoding_message_size;
let inner = self.inner.clone();
let fut = async move {
let method = GetAccountStatesSvc(inner);
let codec = tonic::codec::ProstCodec::default();
let mut grpc = tonic::server::Grpc::new(codec)
.apply_compression_config(
accept_compression_encodings,
send_compression_encodings,
)
.apply_max_message_size_config(
max_decoding_message_size,
max_encoding_message_size,
);
let res = grpc.unary(method, req).await;
Ok(res)
};
Box::pin(fut)
}
"/store.Api/GetAccountStateDelta" => {
#[allow(non_camel_case_types)]
struct GetAccountStateDeltaSvc<T: Api>(pub Arc<T>);
Expand Down
11 changes: 11 additions & 0 deletions crates/rpc-proto/proto/account.proto
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,14 @@ message AccountInfo {
AccountSummary summary = 1;
optional bytes details = 2;
}

message AccountHeader {
// Vault root hash.
digest.Digest vault_root = 1;
// Storage root hash.
digest.Digest storage_commitment = 2;
// Code root hash.
digest.Digest code_commitment = 3;
// Account nonce.
uint64 nonce = 4;
}
7 changes: 7 additions & 0 deletions crates/rpc-proto/proto/requests.proto
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,10 @@ message GetAccountStateDeltaRequest {
// Block number up to which the delta is requested (inclusive).
fixed32 to_block_num = 3;
}

message GetAccountStatesRequest {
// List of account IDs to get states.
repeated account.AccountId account_ids = 1;
// Optional flag to include header in the response. `false` by default.
optional bool include_headers = 2;
}
Loading