Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
135 commits
Select commit Hold shift + click to select a range
4ff0970
for account queries, now return partials too
drahnr Dec 1, 2025
5ee1043
drop all tables as part of migration
drahnr Dec 1, 2025
8eca359
externalize storage and vault blobs to separate tables
drahnr Dec 1, 2025
e7f17ed
trailing .
drahnr Dec 1, 2025
c8b43ab
smt forest
drahnr Dec 1, 2025
19164be
changset, should go away after rebase
drahnr Dec 1, 2025
8eb49af
improve
drahnr Dec 1, 2025
6725461
TODO and deprecation
drahnr Dec 1, 2025
ee65a88
account queries
drahnr Dec 1, 2025
741df6f
yes
drahnr Dec 2, 2025
6a64077
why
drahnr Dec 2, 2025
9d5806e
y
drahnr Dec 2, 2025
2964a93
y
drahnr Dec 2, 2025
9416a63
review comments
drahnr Dec 2, 2025
ccc2d63
sanitize comments
drahnr Dec 2, 2025
66ea831
remove
drahnr Dec 4, 2025
1c4f8b1
cleanup
drahnr Dec 4, 2025
80e0393
fix queries with _at suffix
drahnr Dec 4, 2025
e7bf1aa
cleanup
drahnr Dec 4, 2025
dad90e7
simplify
drahnr Dec 4, 2025
e441245
fix
drahnr Dec 4, 2025
0a319d1
cleanup
drahnr Dec 4, 2025
8897939
remove dead code
drahnr Dec 4, 2025
7d7fefc
add test
drahnr Dec 5, 2025
0f53fa9
add block exists helper
drahnr Dec 5, 2025
7400134
Merge remote-tracking branch 'origin' into bernhard-integrate-smtforest
drahnr Dec 9, 2025
0e2d871
simplify
drahnr Dec 9, 2025
f78103e
better docs
drahnr Dec 9, 2025
ea05b01
split long function in State
drahnr Dec 9, 2025
3cd457a
better
drahnr Dec 9, 2025
c8f0eb1
clippy et al
drahnr Dec 9, 2025
ed7224e
review
drahnr Dec 10, 2025
6336f41
address review comments
drahnr Dec 10, 2025
a1173f7
Revert "address review comments"
drahnr Dec 11, 2025
36470a5
improve
drahnr Dec 11, 2025
928fdb4
yes
drahnr Dec 18, 2025
5de3936
tuple ticks
drahnr Dec 18, 2025
f5b4898
Merge remote-tracking branch 'origin' into bernhard-integrate-smtforest
drahnr Dec 18, 2025
ca5ef9a
docs
drahnr Dec 18, 2025
17fd95b
from_iter
drahnr Dec 18, 2025
22f3ca9
simplify
drahnr Dec 18, 2025
3ee1884
docs
drahnr Dec 18, 2025
eaf7242
undo
drahnr Dec 18, 2025
72126e1
one more enum
drahnr Dec 18, 2025
be9071b
docs
drahnr Dec 18, 2025
a0f8fc9
unneces
drahnr Dec 18, 2025
88c058b
simplify
drahnr Dec 18, 2025
b84f25f
misleading
drahnr Dec 18, 2025
25b5550
bound
drahnr Dec 18, 2025
31dacdd
fmt
drahnr Dec 18, 2025
55f4a46
changelog
drahnr Dec 18, 2025
bf67ce8
0 ->1; 1->0
drahnr Dec 19, 2025
0c0e32b
avoid full paths
drahnr Dec 19, 2025
ec4318e
fn
drahnr Dec 19, 2025
4bfee30
refactor, simplify
drahnr Dec 19, 2025
b8d2e66
yuk
drahnr Dec 19, 2025
3265406
add partial storage maps
drahnr Dec 4, 2025
e453faa
remoe useless comment
drahnr Dec 19, 2025
15af845
CI fixins
drahnr Dec 19, 2025
f6d1ce1
shorthandg pu
drahnr Dec 19, 2025
617c033
yay
drahnr Dec 19, 2025
b1f9cf6
delete unused
drahnr Dec 19, 2025
d2d9e8c
review
drahnr Dec 20, 2025
2781db8
simplify
drahnr Dec 22, 2025
b0e537c
Merge remote-tracking branch 'origin' into bernhard-integrate-smtforest
drahnr Dec 22, 2025
6fb80fe
yay
drahnr Dec 22, 2025
efaa685
feedback
drahnr Dec 22, 2025
d6b31ef
minor
drahnr Dec 22, 2025
9c859fc
fmt
drahnr Dec 23, 2025
1dba957
Merge branch 'bernhard-integrate-smtforest' into bernhard-partial-sto…
drahnr Dec 23, 2025
2982002
fff
drahnr Dec 23, 2025
b016495
Merge branch 'next' into bernhard-integrate-smtforest
bobbinth Dec 27, 2025
579b9dc
chore: fix merge conflicts
bobbinth Dec 27, 2025
3336edb
chore: fix test
bobbinth Dec 27, 2025
2aa8c8b
chore: minor formatting changes
bobbinth Dec 27, 2025
354d586
chore: move InnerForest module
bobbinth Dec 27, 2025
a96def0
chore: refactor SMT forest initialization
bobbinth Dec 27, 2025
e8cdad1
chore: re-organize account queries
bobbinth Dec 27, 2025
3009bf7
nope
drahnr Dec 29, 2025
3110962
fix inconsistency
drahnr Dec 29, 2025
53cb5e8
faster
drahnr Dec 29, 2025
0cc0c61
undue changes
drahnr Dec 29, 2025
ac7b8f9
move fn to innerforest
drahnr Dec 29, 2025
369db2f
y
drahnr Dec 29, 2025
6cd1033
another
drahnr Dec 29, 2025
7613624
test re-review
drahnr Dec 29, 2025
e04ff10
fuckup
drahnr Dec 29, 2025
9d8c220
update
drahnr Dec 29, 2025
5ed1a4f
sync docs
drahnr Dec 29, 2025
f702791
mixed bag
drahnr Dec 29, 2025
16f5785
Merge remote-tracking branch 'origin/bernhard-integrate-smtforest' in…
drahnr Dec 29, 2025
b2eaa55
unity
drahnr Dec 29, 2025
c43a5a2
splits
drahnr Dec 29, 2025
68ed4d7
y
drahnr Dec 29, 2025
bd2709c
behaviour
drahnr Dec 29, 2025
3346d9f
cleanup
drahnr Dec 29, 2025
dbbc1eb
fmt
drahnr Dec 29, 2025
b3c91df
remove dead code
drahnr Dec 29, 2025
77443c2
foo
drahnr Dec 29, 2025
1efa4f0
fixup
drahnr Dec 29, 2025
69ee5a5
change log
drahnr Dec 29, 2025
3bd5451
Merge branch 'bernhard-db-schema-queries' into bernhard-integrate-smt…
drahnr Dec 30, 2025
c5a199a
Merge branch 'bernhard-db-schema-queries' into bernhard-integrate-smt…
drahnr Dec 30, 2025
199a5cb
Merge branch 'bernhard-integrate-smtforest' into bernhard-partial-sto…
drahnr Dec 30, 2025
119ed10
Merge branch 'bernhard-integrate-smtforest' into bernhard-partial-sto…
drahnr Dec 30, 2025
c64392c
lint clippy fmt
drahnr Dec 30, 2025
8d33f66
fix storage_header comment
drahnr Dec 30, 2025
635cb78
select_account_code_at_block -> select_account_code_by_commitment
drahnr Dec 30, 2025
7ca6999
add minor test xtension
drahnr Dec 30, 2025
c712ba4
Merge branch 'bernhard-db-schema-queries' into bernhard-integrate-smt…
drahnr Jan 4, 2026
0874065
Merge branch 'bernhard-integrate-smtforest' into bernhard-partial-sto…
drahnr Jan 5, 2026
d9a666f
review
drahnr Jan 6, 2026
29b840c
remove dead code
drahnr Jan 6, 2026
1b22a34
chore: minor rename
bobbinth Jan 7, 2026
1cab5e2
review
drahnr Jan 9, 2026
c42d5f5
some more docs
drahnr Jan 9, 2026
f1655fe
Merge remote-tracking branch 'origin/next' into bernhard-integrate-sm…
drahnr Jan 9, 2026
9fe3979
add InnerForestError type, make asset addition non-panic
drahnr Jan 10, 2026
6f823e4
review
drahnr Jan 10, 2026
77eee02
remove dead code
drahnr Jan 10, 2026
5a8ea18
clippy
drahnr Jan 10, 2026
f6cd4b3
minor
drahnr Jan 10, 2026
38f3763
Merge remote-tracking branch 'origin/next' into bernhard-integrate-sm…
drahnr Jan 10, 2026
6e40652
Merge remote-tracking branch 'origin/bernhard-integrate-smtforest' in…
drahnr Jan 11, 2026
6e073f7
fixins
drahnr Jan 11, 2026
b9fdd4c
fixup
drahnr Jan 12, 2026
b72a2e9
Merge remote-tracking branch 'origin/next' into bernhard-partial-stor…
drahnr Jan 12, 2026
45b67f8
remove dead code
drahnr Jan 12, 2026
15a0b9a
better range patterns - composite keys are tricky
drahnr Jan 12, 2026
eb4a2d6
domain/ split of tests.rs from account.rs
drahnr Jan 14, 2026
a85ef99
review
drahnr Jan 14, 2026
6b8e1ce
fmt
drahnr Jan 14, 2026
19fb496
Merge origin/next into bernhard-partial-storage-map-queries
drahnr Jan 14, 2026
fb1a247
fmt
drahnr Jan 14, 2026
26313ee
delete, again
drahnr Jan 14, 2026
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 @@ -15,6 +15,7 @@
- Added pagination to `GetNetworkAccountIds` endpoint ([#1452](https://github.com/0xMiden/miden-node/pull/1452)).
- Improved tracing in `miden-network-monitor` binary ([#1366](https://github.com/0xMiden/miden-node/pull/1366)).
- Integrated RPC stack with Validator component for transaction validation ([#1457](https://github.com/0xMiden/miden-node/pull/1457)).
- Add partial storage map queries to RPC ([#1428](https://github.com/0xMiden/miden-node/pull/1428)).
- Added validated transactions check to block validation logc in Validator ([#1460](https://github.com/0xMiden/miden-node/pull/1460)).
- Added explorer status to the `miden-network-monitor` binary ([#1450](https://github.com/0xMiden/miden-node/pull/1450)).
- Added `GetLimits` endpoint to the RPC server ([#1410](https://github.com/0xMiden/miden-node/pull/1410)).
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion crates/proto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ tonic-prost = { workspace = true }
url = { workspace = true }

[dev-dependencies]
proptest = { version = "1.7" }
assert_matches = { workspace = true }
proptest = { version = "1.7" }

[build-dependencies]
fs-err = { workspace = true }
Expand Down
246 changes: 160 additions & 86 deletions crates/proto/src/domain/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use miden_protocol::asset::{Asset, AssetVault};
use miden_protocol::block::BlockNumber;
use miden_protocol::block::account_tree::AccountWitness;
use miden_protocol::crypto::merkle::SparseMerklePath;
use miden_protocol::crypto::merkle::smt::SmtProof;
use miden_protocol::note::{NoteExecutionMode, NoteTag};
use miden_protocol::utils::{Deserializable, DeserializationError, Serializable};
use thiserror::Error;
Expand All @@ -24,6 +25,9 @@ use super::try_convert;
use crate::errors::{ConversionError, MissingFieldHelper};
use crate::generated::{self as proto};

#[cfg(test)]
mod tests;

// ACCOUNT ID
// ================================================================================================

Expand Down Expand Up @@ -187,52 +191,6 @@ impl TryFrom<proto::rpc::account_proof_request::AccountDetailRequest> for Accoun
}
}

impl TryFrom<proto::rpc::account_storage_details::AccountStorageMapDetails>
for AccountStorageMapDetails
{
type Error = ConversionError;

fn try_from(
value: proto::rpc::account_storage_details::AccountStorageMapDetails,
) -> Result<Self, Self::Error> {
use proto::rpc::account_storage_details::account_storage_map_details::map_entries::StorageMapEntry;
let proto::rpc::account_storage_details::AccountStorageMapDetails {
slot_name,
too_many_entries,
entries,
} = value;

let slot_name = StorageSlotName::new(slot_name)?;

let entries = if too_many_entries {
StorageMapEntries::LimitExceeded
} else {
let map_entries = if let Some(entries) = entries {
entries
.entries
.into_iter()
.map(|entry| {
let key = entry
.key
.ok_or(StorageMapEntry::missing_field(stringify!(key)))?
.try_into()?;
let value = entry
.value
.ok_or(StorageMapEntry::missing_field(stringify!(value)))?
.try_into()?;
Ok((key, value))
})
.collect::<Result<Vec<_>, ConversionError>>()?
} else {
Vec::new()
};
StorageMapEntries::Entries(map_entries)
};

Ok(Self { slot_name, entries })
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StorageMapRequest {
pub slot_name: StorageSlotName,
Expand All @@ -259,6 +217,7 @@ impl TryFrom<proto::rpc::account_proof_request::account_detail_request::StorageM
}
}

/// Request of slot data values.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SlotData {
All,
Expand Down Expand Up @@ -457,92 +416,207 @@ pub enum StorageMapEntries {
/// Clients must use `SyncStorageMaps` endpoint instead.
LimitExceeded,

/// The storage map entries (key-value pairs), up to `MAX_RETURN_ENTRIES`.
/// TODO: For partial responses, also include Merkle proofs and inner SMT nodes.
Entries(Vec<(Word, Word)>),
/// All storage map entries (key-value pairs) without proofs.
/// Used when all entries are requested for small maps.
AllEntries(Vec<(Word, Word)>),

/// Specific entries with their SMT proofs for client-side verification.
/// Used when specific keys are requested from the storage map.
EntriesWithProofs(Vec<SmtProof>),
}

impl AccountStorageMapDetails {
/// Maximum number of storage map entries that can be returned in a single response.
pub const MAX_RETURN_ENTRIES: usize = 1000;

pub fn new(slot_name: StorageSlotName, slot_data: SlotData, storage_map: &StorageMap) -> Self {
match slot_data {
SlotData::All => Self::from_all_entries(slot_name, storage_map),
SlotData::MapKeys(keys) => Self::from_specific_keys(slot_name, &keys[..], storage_map),
/// Creates storage map details with all entries from the storage map.
///
/// If the storage map has too many entries (> `MAX_RETURN_ENTRIES`),
/// returns `LimitExceeded` variant.
pub fn from_all_entries(slot_name: StorageSlotName, storage_map: &StorageMap) -> Self {
if storage_map.num_entries() > Self::MAX_RETURN_ENTRIES {
Self {
slot_name,
entries: StorageMapEntries::LimitExceeded,
}
} else {
let entries = Vec::from_iter(storage_map.entries().map(|(k, v)| (*k, *v)));
Self {
slot_name,
entries: StorageMapEntries::AllEntries(entries),
}
}
}

fn from_all_entries(slot_name: StorageSlotName, storage_map: &StorageMap) -> Self {
if storage_map.num_entries() > Self::MAX_RETURN_ENTRIES {
/// Creates storage map details from forest-queried entries.
///
/// Returns `LimitExceeded` if too many entries.
pub fn from_forest_entries(slot_name: StorageSlotName, entries: Vec<(Word, Word)>) -> Self {
if entries.len() > Self::MAX_RETURN_ENTRIES {
Self {
slot_name,
entries: StorageMapEntries::LimitExceeded,
}
} else {
let map_entries = Vec::from_iter(storage_map.entries().map(|(k, v)| (*k, *v)));
Self {
slot_name,
entries: StorageMapEntries::Entries(map_entries),
entries: StorageMapEntries::AllEntries(entries),
}
}
}

fn from_specific_keys(
slot_name: StorageSlotName,
keys: &[Word],
storage_map: &StorageMap,
) -> Self {
if keys.len() > Self::MAX_RETURN_ENTRIES {
/// Creates storage map details from pre-computed SMT proofs.
///
/// Use this when the caller has already obtained the proofs from an `SmtForest`.
/// Returns `LimitExceeded` if too many proofs are provided.
pub fn from_proofs(slot_name: StorageSlotName, proofs: Vec<SmtProof>) -> Self {
if proofs.len() > Self::MAX_RETURN_ENTRIES {
Self {
slot_name,
entries: StorageMapEntries::LimitExceeded,
}
} else {
// TODO For now, we return all entries instead of specific keys with proofs
Self::from_all_entries(slot_name, storage_map)
Self {
slot_name,
entries: StorageMapEntries::EntriesWithProofs(proofs),
}
}
}
}

impl TryFrom<proto::rpc::account_storage_details::AccountStorageMapDetails>
for AccountStorageMapDetails
{
type Error = ConversionError;

fn try_from(
value: proto::rpc::account_storage_details::AccountStorageMapDetails,
) -> Result<Self, Self::Error> {
use proto::rpc::account_storage_details::account_storage_map_details::{
all_map_entries::StorageMapEntry,
map_entries_with_proofs::StorageMapEntryWithProof,
AllMapEntries,
Entries as ProtoEntries,
MapEntriesWithProofs,
};

let proto::rpc::account_storage_details::AccountStorageMapDetails {
slot_name,
too_many_entries,
entries,
} = value;

let slot_name = StorageSlotName::new(slot_name)?;

let entries = if too_many_entries {
StorageMapEntries::LimitExceeded
} else {
match entries {
None => {
return Err(
proto::rpc::account_storage_details::AccountStorageMapDetails::missing_field(
stringify!(entries),
),
);
},
Some(ProtoEntries::AllEntries(AllMapEntries { entries })) => {
let entries = entries
.into_iter()
.map(|entry| {
let key = entry
.key
.ok_or(StorageMapEntry::missing_field(stringify!(key)))?
.try_into()?;
let value = entry
.value
.ok_or(StorageMapEntry::missing_field(stringify!(value)))?
.try_into()?;
Ok((key, value))
})
.collect::<Result<Vec<_>, ConversionError>>()?;
StorageMapEntries::AllEntries(entries)
},
Some(ProtoEntries::EntriesWithProofs(MapEntriesWithProofs { entries })) => {
let proofs = entries
.into_iter()
.map(|entry| {
let smt_opening = entry.proof.ok_or(
StorageMapEntryWithProof::missing_field(stringify!(proof)),
)?;
SmtProof::try_from(smt_opening)
})
.collect::<Result<Vec<_>, ConversionError>>()?;
StorageMapEntries::EntriesWithProofs(proofs)
},
}
};

Ok(Self { slot_name, entries })
}
}

impl From<AccountStorageMapDetails>
for proto::rpc::account_storage_details::AccountStorageMapDetails
{
fn from(value: AccountStorageMapDetails) -> Self {
use proto::rpc::account_storage_details::account_storage_map_details;
use proto::rpc::account_storage_details::account_storage_map_details::{
AllMapEntries,
Entries as ProtoEntries,
MapEntriesWithProofs,
};

let AccountStorageMapDetails { slot_name, entries } = value;

match entries {
StorageMapEntries::LimitExceeded => Self {
slot_name: slot_name.to_string(),
too_many_entries: true,
entries: Some(account_storage_map_details::MapEntries { entries: Vec::new() }),
let (too_many_entries, proto_entries) = match entries {
StorageMapEntries::LimitExceeded => (true, None),
StorageMapEntries::AllEntries(entries) => {
let all = AllMapEntries {
entries: Vec::from_iter(entries.into_iter().map(|(key, value)| {
proto::rpc::account_storage_details::account_storage_map_details::all_map_entries::StorageMapEntry {
key: Some(key.into()),
value: Some(value.into()),
}
})),
};
(false, Some(ProtoEntries::AllEntries(all)))
},
StorageMapEntries::Entries(map_entries) => {
let entries = Some(account_storage_map_details::MapEntries {
entries: Vec::from_iter(map_entries.into_iter().map(|(key, value)| {
account_storage_map_details::map_entries::StorageMapEntry {
StorageMapEntries::EntriesWithProofs(proofs) => {
use miden_protocol::crypto::merkle::smt::SmtLeaf;

let with_proofs = MapEntriesWithProofs {
entries: Vec::from_iter(proofs.into_iter().map(|proof| {
// Get key/value from the leaf before consuming the proof
let (key, value) = match proof.leaf() {
SmtLeaf::Empty(_) => {
(miden_protocol::EMPTY_WORD, miden_protocol::EMPTY_WORD)
},
SmtLeaf::Single((k, v)) => (*k, *v),
SmtLeaf::Multiple(entries) => entries.iter().next().map_or(
(miden_protocol::EMPTY_WORD, miden_protocol::EMPTY_WORD),
|(k, v)| (*k, *v),
),
};
let smt_opening = proto::primitives::SmtOpening::from(proof);
proto::rpc::account_storage_details::account_storage_map_details::map_entries_with_proofs::StorageMapEntryWithProof {
key: Some(key.into()),
value: Some(value.into()),
proof: Some(smt_opening),
}
})),
});

Self {
slot_name: slot_name.to_string(),
too_many_entries: false,
entries,
}
};
(false, Some(ProtoEntries::EntriesWithProofs(with_proofs)))
},
};

Self {
slot_name: slot_name.to_string(),
too_many_entries,
entries: proto_entries,
}
}
}

// ACCOUNT STORAGE DETAILS DETAILS
//================================================================================================

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq)]
pub struct AccountStorageDetails {
pub header: AccountStorageHeader,
pub map_details: Vec<AccountStorageMapDetails>,
Expand Down
41 changes: 41 additions & 0 deletions crates/proto/src/domain/account/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use super::*;

fn word_from_u32(arr: [u32; 4]) -> Word {
Word::from(arr)
}

fn test_slot_name() -> StorageSlotName {
StorageSlotName::new("miden::test::storage::slot").unwrap()
}

#[test]
fn account_storage_map_details_from_forest_entries() {
let slot_name = test_slot_name();
let entries = vec![
(word_from_u32([1, 2, 3, 4]), word_from_u32([5, 6, 7, 8])),
(word_from_u32([9, 10, 11, 12]), word_from_u32([13, 14, 15, 16])),
];

let details = AccountStorageMapDetails::from_forest_entries(slot_name.clone(), entries.clone());

assert_eq!(details.slot_name, slot_name);
assert_eq!(details.entries, StorageMapEntries::AllEntries(entries));
}

#[test]
fn account_storage_map_details_from_forest_entries_limit_exceeded() {
let slot_name = test_slot_name();
// Create more entries than MAX_RETURN_ENTRIES
let entries: Vec<_> = (0..=AccountStorageMapDetails::MAX_RETURN_ENTRIES)
.map(|i| {
let key = word_from_u32([i as u32, 0, 0, 0]);
let value = word_from_u32([0, 0, 0, i as u32]);
(key, value)
})
.collect();

let details = AccountStorageMapDetails::from_forest_entries(slot_name.clone(), entries);

assert_eq!(details.slot_name, slot_name);
assert_eq!(details.entries, StorageMapEntries::LimitExceeded);
}
Loading