use miden_protocol::block::BlockNumber;
use tonic::{Code, Status};
use super::*;
fn assert_client_error(status: &Status, detail: u8) {
assert_eq!(status.code(), Code::InvalidArgument, "{status}");
assert_eq!(status.details(), &[detail], "{status}");
assert!(!status.message().is_empty());
}
#[tokio::test]
async fn malformed_read_requests_return_method_specific_codes() {
let (mut client, _, _store, _server) = start_rpc().await;
let errors = [
(
client
.get_account(proto::miden::node::v1::GetAccountRequest::default())
.await
.unwrap_err(),
1,
),
(
client
.get_notes_by_id(proto::miden::node::v1::GetNotesByIdRequest {
note_ids: vec![proto::note::NoteId::default()],
})
.await
.unwrap_err(),
1,
),
(
client
.get_note_script_by_root(
proto::miden::node::v1::GetNoteScriptByRootRequest::default(),
)
.await
.unwrap_err(),
1,
),
(
client
.sync_notes(proto::miden::node::v1::SyncNotesRequest::default())
.await
.unwrap_err(),
3,
),
(
client
.sync_nullifiers(proto::miden::node::v1::SyncNullifiersRequest::default())
.await
.unwrap_err(),
3,
),
(
client
.sync_account_vault(proto::miden::node::v1::SyncAccountVaultRequest::default())
.await
.unwrap_err(),
2,
),
(
client
.sync_account_storage_maps(
proto::miden::node::v1::SyncAccountStorageMapsRequest::default(),
)
.await
.unwrap_err(),
2,
),
(
client
.sync_transactions(proto::miden::node::v1::SyncTransactionsRequest::default())
.await
.unwrap_err(),
2,
),
];
for (error, detail) in errors {
assert_client_error(&error, detail);
}
}
#[tokio::test]
async fn reversed_sync_ranges_return_invalid_range_code() {
let (mut client, _, _store, _server) = start_rpc().await;
let block_range = Some(proto::miden::node::v1::BlockRange { block_from: 1, block_to: 0 });
let account_id = Some(AccountId::try_from(ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET).unwrap().into());
let errors = [
client
.sync_notes(proto::miden::node::v1::SyncNotesRequest { block_range, note_tags: vec![] })
.await
.unwrap_err(),
client
.sync_nullifiers(proto::miden::node::v1::SyncNullifiersRequest {
block_range,
prefix_len: 16,
nullifiers: vec![],
})
.await
.unwrap_err(),
client
.sync_account_vault(proto::miden::node::v1::SyncAccountVaultRequest {
block_range,
account_id,
})
.await
.unwrap_err(),
client
.sync_account_storage_maps(proto::miden::node::v1::SyncAccountStorageMapsRequest {
block_range,
account_id,
})
.await
.unwrap_err(),
client
.sync_transactions(proto::miden::node::v1::SyncTransactionsRequest {
block_range,
account_ids: vec![],
})
.await
.unwrap_err(),
];
for error in errors {
assert_client_error(&error, 1);
}
}
#[tokio::test]
async fn private_account_sync_returns_method_specific_codes() {
let (mut client, _, _store, _server) = start_rpc().await;
let block_range = Some(proto::miden::node::v1::BlockRange { block_from: 0, block_to: 0 });
let account_id = Some(
AccountId::dummy(
[0; 15],
AccountIdVersion::Version1,
AccountType::Private,
AssetCallbackFlag::Disabled,
)
.into(),
);
let vault = client
.sync_account_vault(proto::miden::node::v1::SyncAccountVaultRequest {
block_range,
account_id,
})
.await
.unwrap_err();
assert_client_error(&vault, 3);
let storage = client
.sync_account_storage_maps(proto::miden::node::v1::SyncAccountStorageMapsRequest {
block_range,
account_id,
})
.await
.unwrap_err();
assert_client_error(&storage, 4);
}
#[tokio::test(flavor = "multi_thread")]
async fn account_lookup_returns_distinct_error_codes() {
let (mut client, _, _store, _server) = start_rpc().await;
let public_id = AccountId::dummy(
[42; 15],
AccountIdVersion::Version1,
AccountType::Public,
AssetCallbackFlag::Disabled,
);
let private_id = AccountId::dummy(
[42; 15],
AccountIdVersion::Version1,
AccountType::Private,
AssetCallbackFlag::Disabled,
);
for (account_id, block_num, detail) in [
(public_id, None, 2),
(private_id, None, 3),
(public_id, Some(BlockNumber::from(1).into()), 4),
] {
let error = client
.get_account(proto::miden::node::v1::GetAccountRequest {
account_id: Some(account_id.into()),
block_num,
details: Some(
proto::miden::node::v1::get_account_request::AccountDetailRequest::default(),
),
})
.await
.unwrap_err();
assert_client_error(&error, detail);
}
}
#[tokio::test]
async fn nullifier_prefix_errors_return_distinct_codes() {
let (mut client, _, _store, _server) = start_rpc().await;
for (prefix_len, nullifiers, detail) in [(15, vec![], 2), (16, vec![65536], 3)] {
let error = client
.sync_nullifiers(proto::miden::node::v1::SyncNullifiersRequest {
block_range: Some(proto::miden::node::v1::BlockRange {
block_from: 0,
block_to: 0,
}),
prefix_len,
nullifiers,
})
.await
.unwrap_err();
assert_client_error(&error, detail);
}
}
#[tokio::test]
async fn chain_mmr_sync_returns_future_block_code() {
let (mut client, _, _store, _server) = start_rpc().await;
let error = client
.sync_chain_mmr(proto::miden::node::v1::SyncChainMmrRequest {
current_client_block_height: 1,
..Default::default()
})
.await
.unwrap_err();
assert_client_error(&error, 2);
}