Skip to content

Commit 63c1a13

Browse files
committed
apollo_gateway: dependency inject transaction converter
1 parent 4f9614e commit 63c1a13

File tree

12 files changed

+202
-158
lines changed

12 files changed

+202
-158
lines changed

Cargo.lock

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

crates/apollo_class_manager_types/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ starknet_api.workspace = true
2323
strum = { workspace = true, features = ["derive"] }
2424
strum_macros.workspace = true
2525
thiserror.workspace = true
26+
tokio.workspace = true
2627

2728
[dev-dependencies]
29+
assert_matches.workspace = true
30+
blockifier = { workspace = true, features = ["testing"] }
31+
mempool_test_utils.workspace = true
2832
mockall.workspace = true
33+
rstest.workspace = true
34+
starknet-types-core.workspace = true
2935
starknet_api = { workspace = true, features = ["testing"] }

crates/apollo_class_manager_types/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use apollo_infra::component_definitions::{
1414
use apollo_infra::{impl_debug_for_infra_requests_and_responses, impl_labeled_request};
1515
use apollo_proc_macros::handle_all_response_variants;
1616
use async_trait::async_trait;
17-
#[cfg(feature = "testing")]
17+
#[cfg(any(feature = "testing", test))]
1818
use mockall::automock;
1919
use serde::{Deserialize, Serialize};
2020
use starknet_api::contract_class::ContractClass;
@@ -50,7 +50,7 @@ pub struct ClassHashes {
5050
/// Serves as the class manager's shared interface.
5151
/// Requires `Send + Sync` to allow transferring and sharing resources (inputs, futures) across
5252
/// threads.
53-
#[cfg_attr(feature = "testing", automock)]
53+
#[cfg_attr(any(test, feature = "testing"), automock)]
5454
#[async_trait]
5555
pub trait ClassManagerClient: Send + Sync {
5656
async fn add_class(&self, class: Class) -> ClassManagerClientResult<ClassHashes>;
@@ -130,7 +130,7 @@ impl From<serde_json::Error> for ClassManagerError {
130130
}
131131
}
132132

133-
#[derive(Clone, Debug, Error)]
133+
#[derive(Clone, Debug, Error, PartialEq)]
134134
pub enum ClassManagerClientError {
135135
#[error(transparent)]
136136
ClientError(#[from] ClientError),

crates/apollo_class_manager_types/src/transaction_converter.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ use thiserror::Error;
2727

2828
use crate::{ClassHashes, ClassManagerClientError, SharedClassManagerClient};
2929

30-
#[derive(Error, Debug, Clone)]
30+
#[cfg(test)]
31+
#[path = "transaction_converter_test.rs"]
32+
pub mod transaction_converter_test;
33+
34+
#[derive(Error, Debug, Clone, PartialEq)]
3135
pub enum TransactionConverterError {
3236
#[error(transparent)]
3337
ClassManagerClientError(#[from] ClassManagerClientError),
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use std::sync::Arc;
2+
3+
use assert_matches::assert_matches;
4+
use blockifier::context::ChainInfo;
5+
use mempool_test_utils::starknet_api_test_utils::declare_tx;
6+
use mockall::predicate::eq;
7+
use rstest::rstest;
8+
use starknet_api::compiled_class_hash;
9+
use starknet_api::executable_transaction::ValidateCompiledClassHashError;
10+
use starknet_api::rpc_transaction::{RpcDeclareTransaction, RpcTransaction};
11+
12+
use crate::transaction_converter::{
13+
TransactionConverter,
14+
TransactionConverterError,
15+
TransactionConverterTrait,
16+
};
17+
use crate::{ClassHashes, MockClassManagerClient};
18+
19+
#[rstest]
20+
#[tokio::test]
21+
async fn test_compiled_class_hash_mismatch() {
22+
let declare_tx = declare_tx();
23+
let declare_tx_inner = assert_matches!(declare_tx.clone(), RpcTransaction::Declare(RpcDeclareTransaction::V3(tx)) => tx);
24+
25+
let other_compiled_class_hash = compiled_class_hash!(2_u8);
26+
assert_ne!(declare_tx_inner.compiled_class_hash, other_compiled_class_hash);
27+
28+
let mut mock_class_manager_client = MockClassManagerClient::new();
29+
30+
mock_class_manager_client
31+
.expect_add_class()
32+
.once()
33+
.with(eq(declare_tx_inner.contract_class.clone()))
34+
.return_once(move |_| {
35+
Ok(ClassHashes {
36+
class_hash: declare_tx_inner.contract_class.calculate_class_hash(),
37+
executable_class_hash_v2: other_compiled_class_hash,
38+
})
39+
});
40+
41+
let transaction_converter = TransactionConverter::new(
42+
Arc::new(mock_class_manager_client),
43+
ChainInfo::create_for_testing().chain_id,
44+
);
45+
46+
let err =
47+
transaction_converter.convert_rpc_tx_to_internal_rpc_tx(declare_tx).await.unwrap_err();
48+
let expected_code = TransactionConverterError::ValidateCompiledClassHashError(
49+
ValidateCompiledClassHashError::CompiledClassHashMismatch {
50+
computed_class_hash: other_compiled_class_hash,
51+
supplied_class_hash: declare_tx_inner.compiled_class_hash,
52+
},
53+
);
54+
assert_eq!(err, expected_code);
55+
}

crates/apollo_gateway/benches/utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ impl BenchTestSetup {
9494
config.gateway_config,
9595
Arc::new(state_reader_factory),
9696
Arc::new(mempool_client),
97-
transaction_converter,
97+
Arc::new(transaction_converter),
9898
);
9999

100100
Self { gateway: gateway_business_logic, txs }

crates/apollo_gateway/src/gateway.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@ pub struct Gateway {
6262
pub stateful_tx_validator_factory: Arc<dyn StatefulTransactionValidatorFactoryTrait>,
6363
pub state_reader_factory: Arc<dyn StateReaderFactory>,
6464
pub mempool_client: SharedMempoolClient,
65-
pub transaction_converter: Arc<TransactionConverter>,
65+
pub transaction_converter: Arc<dyn TransactionConverterTrait>,
6666
}
6767

6868
impl Gateway {
6969
pub fn new(
7070
config: GatewayConfig,
7171
state_reader_factory: Arc<dyn StateReaderFactory>,
7272
mempool_client: SharedMempoolClient,
73-
transaction_converter: TransactionConverter,
73+
transaction_converter: Arc<dyn TransactionConverterTrait>,
7474
) -> Self {
7575
Self {
7676
config: Arc::new(config.clone()),
@@ -83,7 +83,7 @@ impl Gateway {
8383
}),
8484
state_reader_factory,
8585
mempool_client,
86-
transaction_converter: Arc::new(transaction_converter),
86+
transaction_converter,
8787
}
8888
}
8989

@@ -292,8 +292,10 @@ pub fn create_gateway(
292292
class_manager_client: class_manager_client.clone(),
293293
runtime,
294294
});
295-
let transaction_converter =
296-
TransactionConverter::new(class_manager_client, config.chain_info.chain_id.clone());
295+
let transaction_converter = Arc::new(TransactionConverter::new(
296+
class_manager_client,
297+
config.chain_info.chain_id.clone(),
298+
));
297299

298300
Gateway::new(config, state_reader_factory, mempool_client, transaction_converter)
299301
}

0 commit comments

Comments
 (0)