Skip to content

Commit 5eb101a

Browse files
committed
fix: return 404 on NotFound for accounts endpoints
Signed-off-by: William Hankins <william@sundae.fi>
1 parent f39c6d4 commit 5eb101a

File tree

4 files changed

+98
-86
lines changed

4 files changed

+98
-86
lines changed

modules/historical_accounts_state/src/historical_accounts_state.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -321,25 +321,28 @@ impl HistoricalAccountsState {
321321
let response = match query {
322322
AccountsStateQuery::GetAccountRegistrationHistory { account } => {
323323
match state.lock().await.get_registration_history(&account).await {
324-
Ok(registrations) => {
324+
Ok(Some(registrations)) => {
325325
AccountsStateQueryResponse::AccountRegistrationHistory(
326326
registrations,
327327
)
328328
}
329+
Ok(None) => AccountsStateQueryResponse::NotFound,
329330
Err(e) => AccountsStateQueryResponse::Error(e.to_string()),
330331
}
331332
}
332333
AccountsStateQuery::GetAccountDelegationHistory { account } => {
333334
match state.lock().await.get_delegation_history(&account).await {
334-
Ok(delegations) => {
335+
Ok(Some(delegations)) => {
335336
AccountsStateQueryResponse::AccountDelegationHistory(delegations)
336337
}
338+
Ok(None) => AccountsStateQueryResponse::NotFound,
337339
Err(e) => AccountsStateQueryResponse::Error(e.to_string()),
338340
}
339341
}
340342
AccountsStateQuery::GetAccountMIRHistory { account } => {
341343
match state.lock().await.get_mir_history(&account).await {
342-
Ok(mirs) => AccountsStateQueryResponse::AccountMIRHistory(mirs),
344+
Ok(Some(mirs)) => AccountsStateQueryResponse::AccountMIRHistory(mirs),
345+
Ok(None) => AccountsStateQueryResponse::NotFound,
343346
Err(e) => AccountsStateQueryResponse::Error(e.to_string()),
344347
}
345348
}

modules/historical_accounts_state/src/immutable_historical_account_store.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,16 @@ impl ImmutableHistoricalAccountStore {
6666
epoch: u32,
6767
config: &HistoricalAccountsConfig,
6868
) -> Result<u64> {
69-
if !config.any_enabled() {
70-
debug!("no persistence needed for epoch {epoch} (disabled)",);
71-
return Ok(0);
72-
}
73-
7469
let drained_blocks = {
7570
let mut pending = self.pending.lock().await;
7671
std::mem::take(&mut *pending)
7772
};
7873

74+
if !config.any_enabled() {
75+
debug!("no persistence needed for epoch {epoch} (disabled)",);
76+
return Ok(0);
77+
}
78+
7979
let mut batch = self.keyspace.batch();
8080
let mut change_count = 0;
8181

modules/historical_accounts_state/src/state.rs

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -249,41 +249,58 @@ impl State {
249249
pub async fn get_registration_history(
250250
&self,
251251
account: &StakeAddress,
252-
) -> Result<Vec<RegistrationUpdate>> {
253-
let mut registrations =
254-
self.immutable.get_registration_history(&account).await?.unwrap_or_default();
252+
) -> Result<Option<Vec<RegistrationUpdate>>> {
253+
let immutable = self.immutable.get_registration_history(&account).await?;
255254

256-
self.merge_volatile_history(
257-
&account,
258-
|e| e.registration_history.as_ref(),
259-
&mut registrations,
260-
);
255+
let mut volatile = Vec::new();
256+
self.merge_volatile_history(&account, |e| e.registration_history.as_ref(), &mut volatile);
261257

262-
Ok(registrations)
258+
match immutable {
259+
Some(mut registrations) => {
260+
registrations.extend(volatile);
261+
Ok(Some(registrations))
262+
}
263+
None if volatile.is_empty() => Ok(None),
264+
None => Ok(Some(volatile)),
265+
}
263266
}
264267

265268
pub async fn get_delegation_history(
266269
&self,
267270
account: &StakeAddress,
268-
) -> Result<Vec<DelegationUpdate>> {
269-
let mut delegations =
270-
self.immutable.get_delegation_history(&account).await?.unwrap_or_default();
271+
) -> Result<Option<Vec<DelegationUpdate>>> {
272+
let immutable = self.immutable.get_delegation_history(&account).await?;
271273

272-
self.merge_volatile_history(
273-
&account,
274-
|e| e.delegation_history.as_ref(),
275-
&mut delegations,
276-
);
274+
let mut volatile = Vec::new();
275+
self.merge_volatile_history(&account, |e| e.delegation_history.as_ref(), &mut volatile);
277276

278-
Ok(delegations)
277+
match immutable {
278+
Some(mut delegations) => {
279+
delegations.extend(volatile);
280+
Ok(Some(delegations))
281+
}
282+
None if volatile.is_empty() => Ok(None),
283+
None => Ok(Some(volatile)),
284+
}
279285
}
280286

281-
pub async fn get_mir_history(&self, account: &StakeAddress) -> Result<Vec<AccountWithdrawal>> {
282-
let mut mirs = self.immutable.get_mir_history(&account).await?.unwrap_or_default();
287+
pub async fn get_mir_history(
288+
&self,
289+
account: &StakeAddress,
290+
) -> Result<Option<Vec<AccountWithdrawal>>> {
291+
let immutable = self.immutable.get_mir_history(&account).await?;
283292

284-
self.merge_volatile_history(&account, |e| e.mir_history.as_ref(), &mut mirs);
293+
let mut volatile = Vec::new();
294+
self.merge_volatile_history(&account, |e| e.mir_history.as_ref(), &mut volatile);
285295

286-
Ok(mirs)
296+
match immutable {
297+
Some(mut mirs) => {
298+
mirs.extend(volatile);
299+
Ok(Some(mirs))
300+
}
301+
None if volatile.is_empty() => Ok(None),
302+
None => Ok(Some(volatile)),
303+
}
287304
}
288305

289306
pub async fn _get_withdrawal_history(

modules/rest_blockfrost/src/handlers/accounts.rs

Lines changed: 48 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -50,28 +50,26 @@ pub async fn handle_single_account_blockfrost(
5050
|message| match message {
5151
Message::StateQueryResponse(StateQueryResponse::Accounts(
5252
AccountsStateQueryResponse::AccountInfo(account),
53-
)) => Ok(account),
53+
)) => Ok(Some(account)),
5454
Message::StateQueryResponse(StateQueryResponse::Accounts(
5555
AccountsStateQueryResponse::NotFound,
56-
)) => {
57-
return Err(anyhow::anyhow!("Account not found"));
58-
}
56+
)) => Ok(None),
5957
Message::StateQueryResponse(StateQueryResponse::Accounts(
6058
AccountsStateQueryResponse::Error(e),
61-
)) => {
62-
return Err(anyhow::anyhow!(
63-
"Internal server error while retrieving account info: {e}"
64-
));
65-
}
66-
_ => {
67-
return Err(anyhow::anyhow!(
68-
"Unexpected message type while retrieving account info"
69-
))
70-
}
59+
)) => Err(anyhow::anyhow!(
60+
"Internal server error while retrieving account info: {e}"
61+
)),
62+
_ => Err(anyhow::anyhow!(
63+
"Unexpected message type while retrieving account info"
64+
)),
7165
},
7266
)
7367
.await?;
7468

69+
let Some(account) = account else {
70+
return Ok(RESTResponse::with_text(404, "Account not found"));
71+
};
72+
7573
let delegated_spo = match &account.delegated_spo {
7674
Some(spo) => match spo.to_bech32_with_hrp("pool") {
7775
Ok(val) => Some(val),
@@ -140,28 +138,26 @@ pub async fn handle_account_registrations_blockfrost(
140138
|message| match message {
141139
Message::StateQueryResponse(StateQueryResponse::Accounts(
142140
AccountsStateQueryResponse::AccountRegistrationHistory(registrations),
143-
)) => Ok(registrations),
141+
)) => Ok(Some(registrations)),
144142
Message::StateQueryResponse(StateQueryResponse::Accounts(
145143
AccountsStateQueryResponse::NotFound,
146-
)) => {
147-
return Err(anyhow::anyhow!("Account not found"));
148-
}
144+
)) => Ok(None),
149145
Message::StateQueryResponse(StateQueryResponse::Accounts(
150146
AccountsStateQueryResponse::Error(e),
151-
)) => {
152-
return Err(anyhow::anyhow!(
153-
"Internal server error while retrieving account info: {e}"
154-
));
155-
}
156-
_ => {
157-
return Err(anyhow::anyhow!(
158-
"Unexpected message type while retrieving account info"
159-
))
160-
}
147+
)) => Err(anyhow::anyhow!(
148+
"Internal server error while retrieving account info: {e}"
149+
)),
150+
_ => Err(anyhow::anyhow!(
151+
"Unexpected message type while retrieving account info"
152+
)),
161153
},
162154
)
163155
.await?;
164156

157+
let Some(registrations) = registrations else {
158+
return Ok(RESTResponse::with_text(404, "Account not found"));
159+
};
160+
165161
// Get TxHashes from TxIdentifiers
166162
let tx_ids: Vec<_> = registrations.iter().map(|r| r.tx_identifier.clone()).collect();
167163
let msg = Arc::new(Message::StateQuery(StateQuery::Blocks(
@@ -238,28 +234,26 @@ pub async fn handle_account_delegations_blockfrost(
238234
|message| match message {
239235
Message::StateQueryResponse(StateQueryResponse::Accounts(
240236
AccountsStateQueryResponse::AccountDelegationHistory(delegations),
241-
)) => Ok(delegations),
237+
)) => Ok(Some(delegations)),
242238
Message::StateQueryResponse(StateQueryResponse::Accounts(
243239
AccountsStateQueryResponse::NotFound,
244-
)) => {
245-
return Err(anyhow::anyhow!("Account not found"));
246-
}
240+
)) => Ok(None),
247241
Message::StateQueryResponse(StateQueryResponse::Accounts(
248242
AccountsStateQueryResponse::Error(e),
249-
)) => {
250-
return Err(anyhow::anyhow!(
251-
"Internal server error while retrieving account info: {e}"
252-
));
253-
}
254-
_ => {
255-
return Err(anyhow::anyhow!(
256-
"Unexpected message type while retrieving account info"
257-
))
258-
}
243+
)) => Err(anyhow::anyhow!(
244+
"Internal server error while retrieving account info: {e}"
245+
)),
246+
_ => Err(anyhow::anyhow!(
247+
"Unexpected message type while retrieving account info"
248+
)),
259249
},
260250
)
261251
.await?;
262252

253+
let Some(delegations) = delegations else {
254+
return Ok(RESTResponse::with_text(404, "Account not found"));
255+
};
256+
263257
// Get TxHashes from TxIdentifiers
264258
let tx_ids: Vec<_> = delegations.iter().map(|r| r.tx_identifier.clone()).collect();
265259
let msg = Arc::new(Message::StateQuery(StateQuery::Blocks(
@@ -346,28 +340,26 @@ pub async fn handle_account_mirs_blockfrost(
346340
|message| match message {
347341
Message::StateQueryResponse(StateQueryResponse::Accounts(
348342
AccountsStateQueryResponse::AccountMIRHistory(mirs),
349-
)) => Ok(mirs),
343+
)) => Ok(Some(mirs)),
350344
Message::StateQueryResponse(StateQueryResponse::Accounts(
351345
AccountsStateQueryResponse::NotFound,
352-
)) => {
353-
return Err(anyhow::anyhow!("Account not found"));
354-
}
346+
)) => Ok(None),
355347
Message::StateQueryResponse(StateQueryResponse::Accounts(
356348
AccountsStateQueryResponse::Error(e),
357-
)) => {
358-
return Err(anyhow::anyhow!(
359-
"Internal server error while retrieving account info: {e}"
360-
));
361-
}
362-
_ => {
363-
return Err(anyhow::anyhow!(
364-
"Unexpected message type while retrieving account info"
365-
))
366-
}
349+
)) => Err(anyhow::anyhow!(
350+
"Internal server error while retrieving account info: {e}"
351+
)),
352+
_ => Err(anyhow::anyhow!(
353+
"Unexpected message type while retrieving account info"
354+
)),
367355
},
368356
)
369357
.await?;
370358

359+
let Some(mirs) = mirs else {
360+
return Ok(RESTResponse::with_text(404, "Account not found"));
361+
};
362+
371363
// Get TxHashes from TxIdentifiers
372364
let tx_ids: Vec<_> = mirs.iter().map(|r| r.tx_identifier.clone()).collect();
373365
let msg = Arc::new(Message::StateQuery(StateQuery::Blocks(

0 commit comments

Comments
 (0)