Skip to content

Commit e12004f

Browse files
committed
Merge branch 'main' into refactor/provider
2 parents 72c21eb + ec1224e commit e12004f

File tree

7 files changed

+91
-54
lines changed

7 files changed

+91
-54
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bin/katana/src/cli/rpc/starknet.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,9 @@ impl StarknetCommands {
484484
.collect::<Result<Vec<_>>>()?,
485485
)
486486
} else {
487-
None
487+
// temp: pathfinder expects an empty vector instead of an explicit null even
488+
// though the spec allows it
489+
Some(Vec::new())
488490
};
489491

490492
// Parse contract_addresses if provided
@@ -502,15 +504,19 @@ impl StarknetCommands {
502504
.collect::<Result<Vec<_>>>()?,
503505
)
504506
} else {
505-
None
507+
// temp: pathfinder expects an empty vector instead of an explicit null even
508+
// though the spec allows it
509+
Some(Vec::new())
506510
};
507511

508512
// Parse contracts_storage_keys if provided
509513
let contracts_storage_keys: Option<Vec<ContractStorageKeys>> =
510514
if !args.storages.is_empty() {
511515
Some(parse_contract_storage_keys(&args.storages)?)
512516
} else {
513-
None
517+
// temp: pathfinder expects an empty vector instead of an explicit null even
518+
// though the spec allows it
519+
Some(Vec::new())
514520
};
515521

516522
let result = client

crates/rpc/rpc-api/src/error/starknet.rs

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -285,38 +285,38 @@ mod impls {
285285
ProofLimitExceededData, TransactionExecutionErrorData, UnexpectedErrorData,
286286
};
287287

288-
impl From<ErrorObjectOwned> for StarknetApiError {
289-
fn from(err: ErrorObjectOwned) -> Self {
288+
impl StarknetApiError {
289+
pub fn from_error_object(err: &ErrorObjectOwned) -> Option<Self> {
290290
match err.code() {
291-
1 => Self::FailedToReceiveTxn,
292-
20 => Self::ContractNotFound,
293-
21 => Self::EntrypointNotFound,
294-
22 => Self::InvalidCallData,
295-
24 => Self::BlockNotFound,
296-
27 => Self::InvalidTxnIndex,
297-
28 => Self::ClassHashNotFound,
298-
29 => Self::TxnHashNotFound,
291+
1 => Some(Self::FailedToReceiveTxn),
292+
20 => Some(Self::ContractNotFound),
293+
21 => Some(Self::EntrypointNotFound),
294+
22 => Some(Self::InvalidCallData),
295+
24 => Some(Self::BlockNotFound),
296+
27 => Some(Self::InvalidTxnIndex),
297+
28 => Some(Self::ClassHashNotFound),
298+
29 => Some(Self::TxnHashNotFound),
299299
31 => {
300300
if let Some(data) = err.data() {
301301
if let Ok(data) = serde_json::from_str::<PageSizeTooBigData>(data.get()) {
302-
return Self::PageSizeTooBig(data);
302+
return Some(Self::PageSizeTooBig(data));
303303
}
304304
}
305305

306-
Self::PageSizeTooBig(Default::default())
306+
Some(Self::PageSizeTooBig(Default::default()))
307307
}
308-
32 => Self::NoBlocks,
309-
33 => Self::InvalidContinuationToken,
310-
34 => Self::TooManyKeysInFilter,
311-
38 => Self::FailedToFetchPendingTransactions,
308+
32 => Some(Self::NoBlocks),
309+
33 => Some(Self::InvalidContinuationToken),
310+
34 => Some(Self::TooManyKeysInFilter),
311+
38 => Some(Self::FailedToFetchPendingTransactions),
312312
40 => {
313313
let data = if let Some(data) = err.data() {
314314
serde_json::from_str::<ContractErrorData>(data.get()).unwrap_or_default()
315315
} else {
316316
ContractErrorData::default()
317317
};
318318

319-
Self::ContractError(data)
319+
Some(Self::ContractError(data))
320320
}
321321
41 => {
322322
let data = if let Some(data) = err.data() {
@@ -326,21 +326,21 @@ mod impls {
326326
TransactionExecutionErrorData::default()
327327
};
328328

329-
Self::TransactionExecutionError(data)
329+
Some(Self::TransactionExecutionError(data))
330330
}
331331
42 => {
332332
if let Some(data) = err.data() {
333333
if let Ok(data) =
334334
serde_json::from_str::<StorageProofNotSupportedData>(data.get())
335335
{
336-
return Self::StorageProofNotSupported(data);
336+
return Some(Self::StorageProofNotSupported(data));
337337
}
338338
}
339339

340-
Self::StorageProofNotSupported(StorageProofNotSupportedData::default())
340+
Some(Self::StorageProofNotSupported(StorageProofNotSupportedData::default()))
341341
}
342-
50 => Self::InvalidContractClass,
343-
51 => Self::ClassAlreadyDeclared,
342+
50 => Some(Self::InvalidContractClass),
343+
51 => Some(Self::ClassAlreadyDeclared),
344344
52 => {
345345
let data = if let Some(value) = err.data() {
346346
serde_json::from_str::<InvalidTransactionNonceData>(value.get())
@@ -349,10 +349,10 @@ mod impls {
349349
InvalidTransactionNonceData::default()
350350
};
351351

352-
Self::InvalidTransactionNonce(data)
352+
Some(Self::InvalidTransactionNonce(data))
353353
}
354-
53 => Self::InsufficientResourcesForValidate,
355-
54 => Self::InsufficientAccountBalance,
354+
53 => Some(Self::InsufficientResourcesForValidate),
355+
54 => Some(Self::InsufficientAccountBalance),
356356
55 => {
357357
let data = if let Some(data) = err.data() {
358358
serde_json::from_str::<ValidationFailureData>(data.get())
@@ -361,36 +361,36 @@ mod impls {
361361
ValidationFailureData::default()
362362
};
363363

364-
Self::ValidationFailure(data)
364+
Some(Self::ValidationFailure(data))
365365
}
366-
57 => Self::ContractClassSizeIsTooLarge,
367-
58 => Self::NonAccount,
368-
59 => Self::DuplicateTransaction,
369-
60 => Self::CompiledClassHashMismatch,
370-
61 => Self::UnsupportedTransactionVersion,
371-
62 => Self::UnsupportedContractClassVersion,
366+
57 => Some(Self::ContractClassSizeIsTooLarge),
367+
58 => Some(Self::NonAccount),
368+
59 => Some(Self::DuplicateTransaction),
369+
60 => Some(Self::CompiledClassHashMismatch),
370+
61 => Some(Self::UnsupportedTransactionVersion),
371+
62 => Some(Self::UnsupportedContractClassVersion),
372372
63 => {
373373
let data = if let Some(data) = err.data() {
374374
serde_json::from_str::<UnexpectedErrorData>(data.get()).unwrap_or_default()
375375
} else {
376376
UnexpectedErrorData::default()
377377
};
378378

379-
Self::UnexpectedError(data)
379+
Some(Self::UnexpectedError(data))
380380
}
381-
64 => Self::ReplacementTransactionUnderpriced,
382-
65 => Self::FeeBelowMinimum,
383-
66 => Self::InvalidSubscriptionId,
384-
67 => Self::TooManyAddressesInFilter,
385-
68 => Self::TooManyBlocksBack,
381+
64 => Some(Self::ReplacementTransactionUnderpriced),
382+
65 => Some(Self::FeeBelowMinimum),
383+
66 => Some(Self::InvalidSubscriptionId),
384+
67 => Some(Self::TooManyAddressesInFilter),
385+
68 => Some(Self::TooManyBlocksBack),
386386
100 => {
387387
let data = if let Some(data) = err.data() {
388388
serde_json::from_str::<CompilationErrorData>(data.get()).unwrap_or_default()
389389
} else {
390390
CompilationErrorData::default()
391391
};
392392

393-
Self::CompilationError(data)
393+
Some(Self::CompilationError(data))
394394
}
395395
1000 => {
396396
let data = if let Some(data) = err.data() {
@@ -400,10 +400,10 @@ mod impls {
400400
ProofLimitExceededData::default()
401401
};
402402

403-
Self::ProofLimitExceeded(data)
403+
Some(Self::ProofLimitExceeded(data))
404404
}
405405

406-
_ => Self::unexpected(err),
406+
_ => None,
407407
}
408408
}
409409
}

crates/rpc/rpc-client/src/starknet.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,15 @@ impl Client {
237237
contract_addresses: Option<Vec<ContractAddress>>,
238238
contracts_storage_keys: Option<Vec<ContractStorageKeys>>,
239239
) -> Result<GetStorageProofResponse> {
240+
// temp: pathfinder expects an empty vector instead of an explicit null even
241+
// though the spec allows it
240242
self.client
241-
.get_storage_proof(block_id, class_hashes, contract_addresses, contracts_storage_keys)
243+
.get_storage_proof(
244+
block_id,
245+
Some(class_hashes.unwrap_or_default()),
246+
Some(contract_addresses.unwrap_or_default()),
247+
Some(contracts_storage_keys.unwrap_or_default()),
248+
)
242249
.await
243250
.map_err(Into::into)
244251
}
@@ -319,7 +326,13 @@ pub enum Error {
319326
impl From<jsonrpsee::core::client::Error> for Error {
320327
fn from(err: jsonrpsee::core::client::Error) -> Self {
321328
match err {
322-
jsonrpsee::core::client::Error::Call(err_obj) => Error::Starknet(err_obj.into()),
329+
jsonrpsee::core::client::Error::Call(ref err_obj) => {
330+
if let Some(sn_err) = StarknetApiError::from_error_object(err_obj) {
331+
Error::Starknet(sn_err)
332+
} else {
333+
Error::Client(err)
334+
}
335+
}
323336
_ => Error::Client(err),
324337
}
325338
}

crates/storage/provider/provider/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ katana-chain-spec.workspace = true
4343
katana-contracts.workspace = true
4444
katana-runner.workspace = true
4545

46+
similar-asserts.workspace = true
4647
alloy-primitives.workspace = true
4748
lazy_static.workspace = true
4849
rand.workspace = true

crates/storage/provider/provider/src/providers/fork/state.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ impl<Tx1: DbTx, Tx2: DbTxMut> StateProofProvider for LatestStateProvider<Tx1, Tx
215215
let result = self.fork_provider.backend.get_contracts_proofs(addresses, fork_point)?;
216216
let proofs = result.expect("proofs should exist for block");
217217

218-
Ok(proofs.classes_proof.nodes.into())
218+
Ok(proofs.contracts_proof.nodes.into())
219219
} else {
220220
Err(ProviderError::StateProofNotSupported)
221221
}
@@ -476,7 +476,7 @@ impl<Tx1: DbTx, Tx2: DbTxMut> StateProofProvider for HistoricalStateProvider<Tx1
476476
.get_contracts_proofs(addresses, self.local_provider.block())?;
477477
let proofs = result.expect("block should exist");
478478

479-
Ok(proofs.classes_proof.nodes.into())
479+
Ok(proofs.contracts_proof.nodes.into())
480480
}
481481

482482
fn storage_multiproof(

crates/storage/provider/provider/tests/fork.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use katana_provider::api::transaction::{ReceiptProvider, TransactionProvider};
1313
use katana_provider::providers::fork::ForkedProvider;
1414
use katana_provider::ProviderError;
1515
use katana_rpc_client::starknet::Client as StarknetClient;
16-
use katana_rpc_types::Nodes;
16+
use katana_rpc_types::MerkleNode;
1717

1818
const SEPOLIA_RPC_URL: &str = "https://api.cartridge.gg/x/starknet/sepolia";
1919
const FORK_BLOCK_NUMBER: u64 = 2888618;
@@ -298,14 +298,16 @@ async fn historical_fork_state() {
298298
assert!(result2.is_some());
299299
}
300300

301-
#[ignore]
302301
#[tokio::test(flavor = "multi_thread")]
303302
async fn pre_fork_state_proof() {
304303
let starknet_client = StarknetClient::new(SEPOLIA_RPC_URL.try_into().unwrap());
305304

306305
// always use the latest block number of the forked chain because most nodes may not support
307306
// proofs for too old blocks
308-
let latest_block_number = starknet_client.block_number().await.unwrap().block_number;
307+
//
308+
// we take the previous block because there were some instances where the latest block was not
309+
// available or supported by the node.
310+
let latest_block_number = starknet_client.block_number().await.unwrap().block_number - 1;
309311
let provider = ForkedProvider::new_ephemeral(latest_block_number, starknet_client.clone());
310312

311313
let state = provider.latest().unwrap();
@@ -318,18 +320,32 @@ async fn pre_fork_state_proof() {
318320
.await
319321
.unwrap();
320322

321-
assert_eq!(Nodes::from(proofs), expected_proofs.classes_proof.nodes);
323+
// TODO: assert the nodes ordering - ensure they are in the same order. currently, pathfinder
324+
// doesn't return the nodes in the same order as katana.
325+
assert_eq!(proofs.0.len(), expected_proofs.classes_proof.nodes.len());
326+
for expected_node in expected_proofs.classes_proof.nodes.0.into_iter() {
327+
let node_hash = expected_node.node_hash;
328+
let actual_node = proofs.0.get(&node_hash).cloned().map(MerkleNode::from);
329+
assert_eq!(Some(expected_node.node), actual_node)
330+
}
322331

323332
let contracts =
324-
vec![address!("0x0164b86b8fC5C0c84d3c53Bc95760F290420Ea2a32ed49A44fd046683a1CaAc2")];
333+
vec![address!("0x04f4e29add19afa12c868ba1f4439099f225403ff9a71fe667eebb50e13518d3")];
325334
let proofs = state.contract_multiproof(contracts.clone()).unwrap();
326335

327336
let expected_proofs = starknet_client
328337
.get_storage_proof(latest_block_number.into(), None, Some(contracts), None)
329338
.await
330339
.unwrap();
331340

332-
assert_eq!(Nodes::from(proofs), expected_proofs.classes_proof.nodes);
341+
// TODO: assert the nodes ordering - ensure they are in the same order. currently, pathfinder
342+
// doesn't return the nodes in the same order as katana.
343+
assert_eq!(proofs.0.len(), expected_proofs.contracts_proof.nodes.len());
344+
for expected_node in expected_proofs.contracts_proof.nodes.0.into_iter() {
345+
let node_hash = expected_node.node_hash;
346+
let actual_node = proofs.0.get(&node_hash).cloned().map(MerkleNode::from);
347+
assert_eq!(Some(expected_node.node), actual_node)
348+
}
333349
}
334350

335351
#[tokio::test]

0 commit comments

Comments
 (0)