Skip to content

Commit 25da5ba

Browse files
authored
refactor(rpc): make BlockRange.block_to required (#2056)
1 parent 143cf7f commit 25da5ba

7 files changed

Lines changed: 45 additions & 34 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
- Added `StoreReplica` gRPC service with endpoints for streaming blocks and proofs ([#1987](https://github.com/0xMiden/node/pull/1987)).
1818
- Replaced the network monitor's JavaScript dashboard with a server-rendered Maud + HTMX frontend ([#2024](https://github.com/0xMiden/node/pull/2024)).
1919
- [BREAKING] Removed `CheckNullifiers` endpoint ([#2049](https://github.com/0xMiden/node/pull/2049)).
20+
- [BREAKING] `BlockRange.block_to` is now required for all RPC endpoints ([#2056](https://github.com/0xMiden/node/pull/2056)).
2021

2122
## v0.14.10 (2026-05-29)
2223

bin/stress-test/src/store/mod.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,17 @@ pub async fn bench_sync_notes(data_directory: PathBuf, iterations: usize, concur
5656

5757
wait_for_store(&store_client).await.unwrap();
5858

59+
// Get the latest block number to determine the range
60+
let status = store_client.clone().status(()).await.unwrap().into_inner();
61+
let chain_tip = status.chain_tip;
62+
5963
// each request will have `ACCOUNTS_PER_SYNC_NOTES` note tags and will be sent with block number
6064
// 0.
6165
let request = |_| {
6266
let mut client = store_client.clone();
6367
let account_batch: Vec<AccountId> =
6468
account_ids.by_ref().take(ACCOUNTS_PER_SYNC_NOTES).collect();
65-
tokio::spawn(async move { sync_notes(&mut client, account_batch).await })
69+
tokio::spawn(async move { sync_notes(&mut client, account_batch, chain_tip).await })
6670
};
6771

6872
// create a stream of tasks to send the requests
@@ -82,13 +86,14 @@ pub async fn bench_sync_notes(data_directory: PathBuf, iterations: usize, concur
8286
pub async fn sync_notes(
8387
api_client: &mut RpcClient<InterceptedService<Channel, OtelInterceptor>>,
8488
account_ids: Vec<AccountId>,
89+
chain_tip: u32,
8590
) -> Duration {
8691
let note_tags = account_ids
8792
.iter()
8893
.map(|id| u32::from(NoteTag::with_account_target(*id)))
8994
.collect::<Vec<_>>();
9095
let sync_request = proto::rpc::SyncNotesRequest {
91-
block_range: Some(proto::rpc::BlockRange { block_from: 0, block_to: None }),
96+
block_range: Some(proto::rpc::BlockRange { block_from: 0, block_to: chain_tip }),
9297
note_tags,
9398
};
9499

@@ -128,6 +133,10 @@ pub async fn bench_sync_nullifiers(
128133
.map(|a| AccountId::from_hex(a).unwrap())
129134
.collect();
130135

136+
// Get the latest block number to determine the range
137+
let status = store_client.clone().status(()).await.unwrap().into_inner();
138+
let chain_tip = status.chain_tip;
139+
131140
// Get all nullifier prefixes from the store using sync_notes
132141
let mut nullifier_prefixes: Vec<u32> = vec![];
133142
let mut current_block_num = 0;
@@ -140,7 +149,7 @@ pub async fn bench_sync_nullifiers(
140149
let sync_request = proto::rpc::SyncNotesRequest {
141150
block_range: Some(proto::rpc::BlockRange {
142151
block_from: current_block_num,
143-
block_to: None,
152+
block_to: chain_tip,
144153
}),
145154
note_tags,
146155
};
@@ -191,7 +200,7 @@ pub async fn bench_sync_nullifiers(
191200

192201
let nullifiers_batch: Vec<u32> = nullifiers.by_ref().take(prefixes_per_request).collect();
193202

194-
tokio::spawn(async move { sync_nullifiers(&mut client, nullifiers_batch).await })
203+
tokio::spawn(async move { sync_nullifiers(&mut client, nullifiers_batch, chain_tip).await })
195204
};
196205

197206
// Create a stream of tasks to send the requests
@@ -216,9 +225,10 @@ pub async fn bench_sync_nullifiers(
216225
async fn sync_nullifiers(
217226
api_client: &mut RpcClient<InterceptedService<Channel, OtelInterceptor>>,
218227
nullifiers_prefixes: Vec<u32>,
228+
chain_tip: u32,
219229
) -> (Duration, proto::rpc::SyncNullifiersResponse) {
220230
let sync_request = proto::rpc::SyncNullifiersRequest {
221-
block_range: Some(proto::rpc::BlockRange { block_from: 0, block_to: None }),
231+
block_range: Some(proto::rpc::BlockRange { block_from: 0, block_to: chain_tip }),
222232
nullifiers: nullifiers_prefixes,
223233
prefix_len: 16,
224234
};
@@ -345,7 +355,7 @@ pub async fn sync_transactions(
345355
.collect::<Vec<_>>();
346356

347357
let sync_request = proto::rpc::SyncTransactionsRequest {
348-
block_range: Some(proto::rpc::BlockRange { block_from, block_to: Some(block_to) }),
358+
block_range: Some(proto::rpc::BlockRange { block_from, block_to }),
349359
account_ids,
350360
};
351361

crates/proto/src/domain/block.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -380,16 +380,11 @@ pub enum InvalidBlockRange {
380380
}
381381

382382
impl proto::rpc::BlockRange {
383-
/// Converts the block range into an inclusive range, using the fallback block number if the
384-
/// block to is not specified.
383+
/// Converts the block range into an inclusive range.
385384
pub fn into_inclusive_range<T: From<InvalidBlockRange>>(
386385
self,
387-
fallback: &BlockNumber,
388386
) -> Result<RangeInclusive<BlockNumber>, T> {
389-
let block_range = RangeInclusive::new(
390-
self.block_from.into(),
391-
self.block_to.map_or(*fallback, BlockNumber::from),
392-
);
387+
let block_range = RangeInclusive::new(self.block_from.into(), self.block_to.into());
393388

394389
if block_range.start() > block_range.end() {
395390
return Err(InvalidBlockRange::StartGreaterThanEnd {
@@ -415,7 +410,7 @@ impl From<RangeInclusive<BlockNumber>> for proto::rpc::BlockRange {
415410
fn from(range: RangeInclusive<BlockNumber>) -> Self {
416411
Self {
417412
block_from: range.start().as_u32(),
418-
block_to: Some(range.end().as_u32()),
413+
block_to: range.end().as_u32(),
419414
}
420415
}
421416
}

crates/rpc/src/server/api.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ impl api_server::Api for RpcService {
255255

256256
let span = Span::current();
257257
span.set_attribute("block_range.from", range.block_from);
258-
span.set_attribute("block_range.to", range.block_to());
258+
span.set_attribute("block_range.to", range.block_to);
259259

260260
debug!(target: COMPONENT, request = ?request.get_ref());
261261

@@ -309,7 +309,7 @@ impl api_server::Api for RpcService {
309309

310310
let span = Span::current();
311311
span.set_attribute("block_range.from", range.block_from);
312-
span.set_attribute("block_range.to", range.block_to());
312+
span.set_attribute("block_range.to", range.block_to);
313313
debug!(target: COMPONENT, request = ?request.get_ref());
314314

315315
check::<QueryParamNoteTagLimit>(request.get_ref().note_tags.len())?;
@@ -364,7 +364,7 @@ impl api_server::Api for RpcService {
364364
let span = Span::current();
365365
span.set_attribute("account.id", account_id);
366366
span.set_attribute("block_range.from", range.block_from);
367-
span.set_attribute("block_range.to", range.block_to());
367+
span.set_attribute("block_range.to", range.block_to);
368368

369369
debug!(target: COMPONENT, request = ?request.get_ref());
370370

@@ -385,7 +385,7 @@ impl api_server::Api for RpcService {
385385
let span = Span::current();
386386
span.set_attribute("account.id", account_id);
387387
span.set_attribute("block_range.from", range.block_from);
388-
span.set_attribute("block_range.to", range.block_to());
388+
span.set_attribute("block_range.to", range.block_to);
389389

390390
debug!(target: COMPONENT, request = ?request.get_ref());
391391

@@ -618,7 +618,7 @@ impl api_server::Api for RpcService {
618618

619619
let span = Span::current();
620620
span.set_attribute("block_range.from", range.block_from);
621-
span.set_attribute("block_range.to", range.block_to());
621+
span.set_attribute("block_range.to", range.block_to);
622622
span.set_attribute("account.ids", format!("{account_ids:?}").as_str());
623623
span.set_attribute("account.ids.count", n_accounts);
624624

crates/store/src/server/ntx_builder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,16 @@ impl ntx_builder_server::NtxBuilder for StoreApi {
140140
) -> Result<Response<proto::store::NetworkAccountIdList>, Status> {
141141
let request = request.into_inner();
142142

143-
let mut chain_tip = self.state.chain_tip(Finality::Committed).await;
144143
let block_range =
145144
read_block_range::<GetNetworkAccountIdsError>(Some(request), "GetNetworkAccountIds")?
146-
.into_inclusive_range::<GetNetworkAccountIdsError>(&chain_tip)?;
145+
.into_inclusive_range::<GetNetworkAccountIdsError>()?;
147146

148147
let (account_ids, mut last_block_included) =
149148
self.state.get_all_network_accounts(block_range).await.map_err(internal_error)?;
150149

151150
let account_ids = Vec::from_iter(account_ids.into_iter().map(Into::into));
152151

152+
let mut chain_tip = self.state.chain_tip(Finality::Committed).await;
153153
if last_block_included > chain_tip {
154154
last_block_included = chain_tip;
155155
}

crates/store/src/server/rpc_api.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,9 @@ impl rpc_server::Rpc for StoreApi {
6969
// Validate nullifier prefix list size before querying state.
7070
check::<QueryParamNullifierPrefixLimit>(request.nullifiers.len())?;
7171

72-
let chain_tip = self.state.chain_tip(Finality::Committed).await;
7372
let block_range =
7473
read_block_range::<SyncNullifiersError>(request.block_range, "SyncNullifiersRequest")?
75-
.into_inclusive_range::<SyncNullifiersError>(&chain_tip)?;
74+
.into_inclusive_range::<SyncNullifiersError>()?;
7675

7776
let (nullifiers, block_num) = self
7877
.state
@@ -88,6 +87,8 @@ impl rpc_server::Rpc for StoreApi {
8887
})
8988
.collect();
9089

90+
let chain_tip = self.state.chain_tip(Finality::Committed).await;
91+
9192
Ok(Response::new(proto::rpc::SyncNullifiersResponse {
9293
pagination_info: Some(proto::rpc::PaginationInfo {
9394
chain_tip: chain_tip.as_u32(),
@@ -104,10 +105,11 @@ impl rpc_server::Rpc for StoreApi {
104105
) -> Result<Response<proto::rpc::SyncNotesResponse>, Status> {
105106
let request = request.into_inner();
106107

107-
let chain_tip = self.state.chain_tip(Finality::Committed).await;
108108
let block_range =
109109
read_block_range::<NoteSyncError>(request.block_range, "SyncNotesRequest")?
110-
.into_inclusive_range::<NoteSyncError>(&chain_tip)?;
110+
.into_inclusive_range::<NoteSyncError>()?;
111+
112+
let chain_tip = self.state.chain_tip(Finality::Committed).await;
111113
if *block_range.end() > chain_tip {
112114
Err(NoteSyncError::FutureBlock { chain_tip, block_to: *block_range.end() })?;
113115
}
@@ -171,7 +173,7 @@ impl rpc_server::Rpc for StoreApi {
171173
Ok(Response::new(proto::rpc::SyncChainMmrResponse {
172174
block_range: Some(proto::rpc::BlockRange {
173175
block_from: block_range.start().as_u32(),
174-
block_to: Some(block_range.end().as_u32()),
176+
block_to: block_range.end().as_u32(),
175177
}),
176178
mmr_delta: Some(mmr_delta.into()),
177179
block_header: Some(block_header.into()),
@@ -249,7 +251,6 @@ impl rpc_server::Rpc for StoreApi {
249251
request: Request<proto::rpc::SyncAccountVaultRequest>,
250252
) -> Result<Response<proto::rpc::SyncAccountVaultResponse>, Status> {
251253
let request = request.into_inner();
252-
let chain_tip = self.state.chain_tip(Finality::Committed).await;
253254

254255
let account_id: AccountId = read_account_id::<
255256
proto::rpc::SyncAccountVaultRequest,
@@ -264,7 +265,7 @@ impl rpc_server::Rpc for StoreApi {
264265
request.block_range,
265266
"SyncAccountVaultRequest",
266267
)?
267-
.into_inclusive_range::<SyncAccountVaultError>(&chain_tip)?;
268+
.into_inclusive_range::<SyncAccountVaultError>()?;
268269

269270
let (last_included_block, updates) = self
270271
.state
@@ -284,6 +285,8 @@ impl rpc_server::Rpc for StoreApi {
284285
})
285286
.collect();
286287

288+
let chain_tip = self.state.chain_tip(Finality::Committed).await;
289+
287290
Ok(Response::new(proto::rpc::SyncAccountVaultResponse {
288291
pagination_info: Some(proto::rpc::PaginationInfo {
289292
chain_tip: chain_tip.as_u32(),
@@ -311,12 +314,11 @@ impl rpc_server::Rpc for StoreApi {
311314
Err(SyncAccountStorageMapsError::AccountNotPublic(account_id))?;
312315
}
313316

314-
let chain_tip = self.state.chain_tip(Finality::Committed).await;
315317
let block_range = read_block_range::<SyncAccountStorageMapsError>(
316318
request.block_range,
317319
"SyncAccountStorageMapsRequest",
318320
)?
319-
.into_inclusive_range::<SyncAccountStorageMapsError>(&chain_tip)?;
321+
.into_inclusive_range::<SyncAccountStorageMapsError>()?;
320322

321323
let storage_maps_page = self
322324
.state
@@ -335,6 +337,8 @@ impl rpc_server::Rpc for StoreApi {
335337
})
336338
.collect();
337339

340+
let chain_tip = self.state.chain_tip(Finality::Committed).await;
341+
338342
Ok(Response::new(proto::rpc::SyncAccountStorageMapsResponse {
339343
pagination_info: Some(proto::rpc::PaginationInfo {
340344
chain_tip: chain_tip.as_u32(),
@@ -383,12 +387,11 @@ impl rpc_server::Rpc for StoreApi {
383387

384388
let request = request.into_inner();
385389

386-
let chain_tip = self.state.chain_tip(Finality::Committed).await;
387390
let block_range = read_block_range::<SyncTransactionsError>(
388391
request.block_range,
389392
"SyncTransactionsRequest",
390393
)?
391-
.into_inclusive_range::<SyncTransactionsError>(&chain_tip)?;
394+
.into_inclusive_range::<SyncTransactionsError>()?;
392395

393396
let account_ids: Vec<AccountId> =
394397
read_account_ids::<SyncTransactionsError, _>(request.account_ids)?;
@@ -409,6 +412,8 @@ impl rpc_server::Rpc for StoreApi {
409412
.map(crate::db::TransactionRecord::into_proto)
410413
.collect();
411414

415+
let chain_tip = self.state.chain_tip(Finality::Committed).await;
416+
412417
Ok(Response::new(proto::rpc::SyncTransactionsResponse {
413418
pagination_info: Some(proto::rpc::PaginationInfo {
414419
chain_tip: chain_tip.as_u32(),

proto/proto/rpc.proto

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,8 +558,8 @@ message BlockRange {
558558
// Block number from which to start (inclusive).
559559
fixed32 block_from = 1;
560560

561-
// Block number up to which to check (inclusive). If not specified, checks up to the latest block.
562-
optional fixed32 block_to = 2;
561+
// Block number up to which to check (inclusive).
562+
fixed32 block_to = 2;
563563
}
564564

565565
// PAGINATION INFO

0 commit comments

Comments
 (0)