diff --git a/Cargo.lock b/Cargo.lock
index 740834f0f..b39102595 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6029,6 +6029,7 @@ dependencies = [
"serde",
"serde_json",
"serde_with 3.9.0",
+ "starknet-core",
"starknet-types-core",
]
diff --git a/crates/client/gateway/src/client/methods.rs b/crates/client/gateway/src/client/methods.rs
index 91b93cf92..9de714b86 100644
--- a/crates/client/gateway/src/client/methods.rs
+++ b/crates/client/gateway/src/client/methods.rs
@@ -77,14 +77,14 @@ mod tests {
async fn test_get_state_update() {
let client = FeederClient::starknet_alpha_mainnet();
- let block = client.get_state_update(BlockId::Number(0)).await.unwrap();
- let block = client
+ let _block = client.get_state_update(BlockId::Number(0)).await.unwrap();
+ let _block = client
.get_state_update(BlockId::Hash(Felt::from_hex_unchecked(
"0x47c3637b57c2b079b93c61539950c17e868a28f46cdef28f88521067f21e943",
)))
.await
.unwrap();
- let block = client.get_state_update(BlockId::Tag(BlockTag::Latest)).await.unwrap();
- let block = client.get_state_update(BlockId::Tag(BlockTag::Pending)).await.unwrap();
+ let _block = client.get_state_update(BlockId::Tag(BlockTag::Latest)).await.unwrap();
+ let _block = client.get_state_update(BlockId::Tag(BlockTag::Pending)).await.unwrap();
}
}
diff --git a/crates/client/gateway/src/server/handler.rs b/crates/client/gateway/src/server/handler.rs
index 92405a358..fd9c97e2a 100644
--- a/crates/client/gateway/src/server/handler.rs
+++ b/crates/client/gateway/src/server/handler.rs
@@ -1,6 +1,6 @@
use std::sync::Arc;
-use hyper::{Body, Request, Response};
+use hyper::{body, Body, Request, Response};
use mc_db::MadaraBackend;
use mc_rpc::providers::AddTransactionProvider;
use mp_block::{BlockId, BlockTag, MadaraBlock, MadaraPendingBlock};
@@ -10,7 +10,10 @@ use mp_gateway::{
state_update::{PendingStateUpdateProvider, StateUpdateProvider},
};
use serde_json::json;
-use starknet_core::types::BroadcastedTransaction;
+use starknet_core::types::{
+ BroadcastedDeclareTransaction, BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction,
+ BroadcastedTransaction,
+};
use starknet_types_core::felt::Felt;
use crate::error::{StarknetError, StarknetErrorCode};
@@ -19,7 +22,7 @@ use super::{
error::{GatewayError, ResultExt},
helpers::{
block_id_from_params, create_json_response, create_response_with_json_body, get_params_from_request,
- include_block_params, not_implemented_response,
+ include_block_params,
},
};
@@ -245,18 +248,60 @@ pub async fn handle_get_class_by_hash(req: Request
, backend: Arc,
- backend: Arc,
add_transaction_provider: Arc,
) -> Response {
- // let transaction = match serde_json::from_slice::(req.body())) {
- // Ok(transaction) => transaction,
- // Err(e) => {
- // return GatewayError::StarknetError(StarknetError {
- // code: StarknetErrorCode::MalformedRequest,
- // message: format!("Failed to parse transaction: {}", e),
- // })
- // .into()
- // }
- // };
- not_implemented_response()
+ let whole_body = match body::to_bytes(req.into_body()).await {
+ Ok(body) => body,
+ Err(e) => {
+ log::error!("Failed to read request body: {}", e);
+ return GatewayError::InternalServerError.into();
+ }
+ };
+
+ let transaction = match serde_json::from_slice::(whole_body.as_ref()) {
+ Ok(transaction) => transaction,
+ Err(e) => {
+ return GatewayError::StarknetError(StarknetError {
+ code: StarknetErrorCode::MalformedRequest,
+ message: format!("Failed to parse transaction: {}", e),
+ })
+ .into()
+ }
+ };
+
+ match transaction {
+ BroadcastedTransaction::Declare(tx) => declare_transaction(tx, add_transaction_provider).await,
+ BroadcastedTransaction::DeployAccount(tx) => deploy_account_transaction(tx, add_transaction_provider).await,
+ BroadcastedTransaction::Invoke(tx) => invoke_transaction(tx, add_transaction_provider).await,
+ }
+}
+
+async fn declare_transaction(
+ tx: BroadcastedDeclareTransaction,
+ add_transaction_provider: Arc,
+) -> Response {
+ match add_transaction_provider.add_declare_transaction(tx).await {
+ Ok(result) => create_json_response(hyper::StatusCode::OK, &result),
+ Err(e) => create_json_response(hyper::StatusCode::OK, &e),
+ }
+}
+
+async fn deploy_account_transaction(
+ tx: BroadcastedDeployAccountTransaction,
+ add_transaction_provider: Arc,
+) -> Response {
+ match add_transaction_provider.add_deploy_account_transaction(tx).await {
+ Ok(result) => create_json_response(hyper::StatusCode::OK, &result),
+ Err(e) => create_json_response(hyper::StatusCode::OK, &e),
+ }
+}
+
+async fn invoke_transaction(
+ tx: BroadcastedInvokeTransaction,
+ add_transaction_provider: Arc,
+) -> Response {
+ match add_transaction_provider.add_invoke_transaction(tx).await {
+ Ok(result) => create_json_response(hyper::StatusCode::OK, &result),
+ Err(e) => create_json_response(hyper::StatusCode::OK, &e),
+ }
}
diff --git a/crates/client/gateway/src/server/router.rs b/crates/client/gateway/src/server/router.rs
index 4af0aa99d..baba97260 100644
--- a/crates/client/gateway/src/server/router.rs
+++ b/crates/client/gateway/src/server/router.rs
@@ -18,7 +18,7 @@ pub(crate) async fn main_router(
match (req.uri().path(), feeder_gateway_enable, gateway_enable) {
("/health", _, _) => Ok(Response::new(Body::from("OK"))),
(path, true, _) if path.starts_with("/feeder_gateway/") => feeder_gateway_router(req, backend).await,
- (path, _, true) if path.starts_with("/feeder/") => gateway_router(req, backend, add_transaction_provider).await,
+ (path, _, true) if path.starts_with("/feeder/") => gateway_router(req, add_transaction_provider).await,
(path, false, _) if path.starts_with("/feeder_gateway/") => Ok(service_unavailable_response("Feeder Gateway")),
(path, _, false) if path.starts_with("/feeder/") => Ok(service_unavailable_response("Feeder")),
_ => Ok(not_found_response()),
@@ -38,13 +38,10 @@ async fn feeder_gateway_router(req: Request, backend: Arc)
// Router for requests related to feeder
async fn gateway_router(
req: Request,
- backend: Arc,
add_transaction_provider: Arc,
) -> Result, Infallible> {
match (req.method(), req.uri().path()) {
- (&Method::POST, "/feeder/add_transaction") => {
- Ok(handle_add_transaction(req, backend, add_transaction_provider).await)
- }
+ (&Method::POST, "/feeder/add_transaction") => Ok(handle_add_transaction(req, add_transaction_provider).await),
_ => Ok(not_found_response()),
}
}
diff --git a/crates/node/src/main.rs b/crates/node/src/main.rs
index 3cd5946ad..f87ccb5eb 100644
--- a/crates/node/src/main.rs
+++ b/crates/node/src/main.rs
@@ -10,8 +10,8 @@ use std::sync::Arc;
use anyhow::Context;
use clap::Parser;
+use cli::{NetworkType, RunCmd};
use mc_block_import::BlockImporter;
-
use mc_db::DatabaseService;
use mc_mempool::{GasPriceProvider, L1DataProvider, Mempool};
use mc_metrics::MetricsService;
@@ -19,13 +19,9 @@ use mc_rpc::providers::{AddTransactionProvider, ForwardToProvider, MempoolAddTxP
use mc_telemetry::{SysInfo, TelemetryService};
use mp_convert::ToFelt;
use mp_utils::service::{Service, ServiceGroup};
-use service::{BlockProductionService, GatewayService, RpcService, SyncService};
+use service::{BlockProductionService, GatewayService, L1SyncService, RpcService, SyncService};
use starknet_providers::SequencerGatewayProvider;
-use cli::{NetworkType, RunCmd};
-use service::L1SyncService;
-use service::{BlockProductionService, RpcService, SyncService};
-
const GREET_IMPL_NAME: &str = "Madara";
const GREET_SUPPORT_URL: &str = "https://github.com/madara-alliance/madara/issues";
diff --git a/crates/primitives/gateway/Cargo.toml b/crates/primitives/gateway/Cargo.toml
index 2d4723405..7bac4798c 100644
--- a/crates/primitives/gateway/Cargo.toml
+++ b/crates/primitives/gateway/Cargo.toml
@@ -16,13 +16,14 @@ targets = ["x86_64-unknown-linux-gnu"]
# Deoxys
mp-block = { workspace = true }
mp-chain-config = { workspace = true }
-mp-convert = { workspace = true }
mp-class = { workspace = true }
+mp-convert = { workspace = true }
mp-receipt = { workspace = true }
mp-state-update = { workspace = true }
mp-transactions = { workspace = true }
# Starknet
+starknet-core = { workspace = true }
starknet-types-core = { workspace = true }
# Other
diff --git a/crates/primitives/gateway/src/user_transaction.rs b/crates/primitives/gateway/src/user_transaction.rs
index cb7d6f9ee..621b8f382 100644
--- a/crates/primitives/gateway/src/user_transaction.rs
+++ b/crates/primitives/gateway/src/user_transaction.rs
@@ -1,30 +1,58 @@
+use std::sync::Arc;
+
use mp_class::{CompressedLegacyContractClass, FlattenedSierraClass};
use mp_transactions::{DataAvailabilityMode, ResourceBoundsMapping};
use serde::{Deserialize, Serialize};
+use starknet_core::types::{
+ BroadcastedDeclareTransaction, BroadcastedDeclareTransactionV1, BroadcastedDeclareTransactionV2,
+ BroadcastedDeclareTransactionV3, BroadcastedDeployAccountTransaction, BroadcastedDeployAccountTransactionV1,
+ BroadcastedDeployAccountTransactionV3, BroadcastedInvokeTransaction, BroadcastedInvokeTransactionV1,
+ BroadcastedInvokeTransactionV3, BroadcastedTransaction,
+};
use starknet_types_core::felt::Felt;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "SCREAMING_SNAKE_CASE")]
#[serde(deny_unknown_fields)]
pub enum UserTransaction {
- DeclareV1(DeclareTransaction),
- InvokeFunction(InvokeFunctionTransaction),
- DeployAccount(DeployAccountTransaction),
+ DeclareV1(UserDeclareTransaction),
+ InvokeFunction(UserInvokeFunctionTransaction),
+ DeployAccount(UserDeployAccountTransaction),
+}
+
+impl From for BroadcastedTransaction {
+ fn from(transaction: UserTransaction) -> Self {
+ match transaction {
+ UserTransaction::DeclareV1(v1) => BroadcastedTransaction::Declare(v1.into()),
+ UserTransaction::InvokeFunction(v1) => BroadcastedTransaction::Invoke(v1.into()),
+ UserTransaction::DeployAccount(v1) => BroadcastedTransaction::DeployAccount(v1.into()),
+ }
+ }
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "version")]
-pub enum DeclareTransaction {
+pub enum UserDeclareTransaction {
#[serde(rename = "0x1")]
- V1(DeclareV1Transaction),
+ V1(UserDeclareV1Transaction),
#[serde(rename = "0x2")]
- V2(DeclareV2Transaction),
+ V2(UserDeclareV2Transaction),
#[serde(rename = "0x3")]
- V3(DeclareV3Transaction),
+ V3(UserDeclareV3Transaction),
+}
+
+impl From for BroadcastedDeclareTransaction {
+ fn from(transaction: UserDeclareTransaction) -> Self {
+ match transaction {
+ UserDeclareTransaction::V1(v1) => BroadcastedDeclareTransaction::V1(v1.into()),
+ UserDeclareTransaction::V2(v2) => BroadcastedDeclareTransaction::V2(v2.into()),
+ UserDeclareTransaction::V3(v3) => BroadcastedDeclareTransaction::V3(v3.into()),
+ }
+ }
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-pub struct DeclareV1Transaction {
+pub struct UserDeclareV1Transaction {
pub contract_class: CompressedLegacyContractClass,
pub sender_address: Felt,
pub max_fee: Felt,
@@ -33,8 +61,21 @@ pub struct DeclareV1Transaction {
pub is_query: bool,
}
+impl From for BroadcastedDeclareTransactionV1 {
+ fn from(transaction: UserDeclareV1Transaction) -> Self {
+ Self {
+ sender_address: transaction.sender_address,
+ max_fee: transaction.max_fee,
+ signature: transaction.signature,
+ nonce: transaction.nonce,
+ contract_class: Arc::new(transaction.contract_class.into()),
+ is_query: transaction.is_query,
+ }
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-pub struct DeclareV2Transaction {
+pub struct UserDeclareV2Transaction {
pub contract_class: FlattenedSierraClass,
pub compiled_class_hash: Felt,
pub sender_address: Felt,
@@ -44,8 +85,22 @@ pub struct DeclareV2Transaction {
pub is_query: bool,
}
+impl From for BroadcastedDeclareTransactionV2 {
+ fn from(transaction: UserDeclareV2Transaction) -> Self {
+ Self {
+ sender_address: transaction.sender_address,
+ compiled_class_hash: transaction.compiled_class_hash,
+ max_fee: transaction.max_fee,
+ signature: transaction.signature,
+ nonce: transaction.nonce,
+ contract_class: Arc::new(transaction.contract_class.into()),
+ is_query: transaction.is_query,
+ }
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-pub struct DeclareV3Transaction {
+pub struct UserDeclareV3Transaction {
pub contract_class: FlattenedSierraClass,
pub compiled_class_hash: Felt,
pub sender_address: Felt,
@@ -60,17 +115,45 @@ pub struct DeclareV3Transaction {
pub is_query: bool,
}
+impl From for BroadcastedDeclareTransactionV3 {
+ fn from(transaction: UserDeclareV3Transaction) -> Self {
+ Self {
+ sender_address: transaction.sender_address,
+ compiled_class_hash: transaction.compiled_class_hash,
+ signature: transaction.signature,
+ nonce: transaction.nonce,
+ nonce_data_availability_mode: transaction.nonce_data_availability_mode.into(),
+ fee_data_availability_mode: transaction.fee_data_availability_mode.into(),
+ resource_bounds: transaction.resource_bounds.into(),
+ tip: transaction.tip,
+ contract_class: Arc::new(transaction.contract_class.into()),
+ paymaster_data: transaction.paymaster_data,
+ account_deployment_data: transaction.account_deployment_data,
+ is_query: transaction.is_query,
+ }
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "version")]
-pub enum InvokeFunctionTransaction {
+pub enum UserInvokeFunctionTransaction {
#[serde(rename = "0x1")]
- V1(InvokeFunctionV1Transaction),
+ V1(UserInvokeFunctionV1Transaction),
#[serde(rename = "0x3")]
- V3(InvokeFunctionV3Transaction),
+ V3(UserInvokeFunctionV3Transaction),
+}
+
+impl From for BroadcastedInvokeTransaction {
+ fn from(transaction: UserInvokeFunctionTransaction) -> Self {
+ match transaction {
+ UserInvokeFunctionTransaction::V1(v1) => BroadcastedInvokeTransaction::V1(v1.into()),
+ UserInvokeFunctionTransaction::V3(v3) => BroadcastedInvokeTransaction::V3(v3.into()),
+ }
+ }
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-pub struct InvokeFunctionV1Transaction {
+pub struct UserInvokeFunctionV1Transaction {
pub sender_address: Felt,
pub calldata: Vec,
pub signature: Vec,
@@ -79,8 +162,21 @@ pub struct InvokeFunctionV1Transaction {
pub is_query: bool,
}
+impl From for BroadcastedInvokeTransactionV1 {
+ fn from(transaction: UserInvokeFunctionV1Transaction) -> Self {
+ Self {
+ sender_address: transaction.sender_address,
+ calldata: transaction.calldata,
+ signature: transaction.signature,
+ max_fee: transaction.max_fee,
+ nonce: transaction.nonce,
+ is_query: transaction.is_query,
+ }
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-pub struct InvokeFunctionV3Transaction {
+pub struct UserInvokeFunctionV3Transaction {
pub sender_address: Felt,
pub calldata: Vec,
pub signature: Vec,
@@ -94,17 +190,44 @@ pub struct InvokeFunctionV3Transaction {
pub is_query: bool,
}
+impl From for BroadcastedInvokeTransactionV3 {
+ fn from(transaction: UserInvokeFunctionV3Transaction) -> Self {
+ Self {
+ sender_address: transaction.sender_address,
+ calldata: transaction.calldata,
+ signature: transaction.signature,
+ nonce: transaction.nonce,
+ nonce_data_availability_mode: transaction.nonce_data_availability_mode.into(),
+ fee_data_availability_mode: transaction.fee_data_availability_mode.into(),
+ resource_bounds: transaction.resource_bounds.into(),
+ tip: transaction.tip,
+ paymaster_data: transaction.paymaster_data,
+ account_deployment_data: transaction.account_deployment_data,
+ is_query: transaction.is_query,
+ }
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "version")]
-pub enum DeployAccountTransaction {
+pub enum UserDeployAccountTransaction {
#[serde(rename = "0x1")]
- V1(DeployAccountV1Transaction),
+ V1(UserDeployAccountV1Transaction),
#[serde(rename = "0x3")]
- V3(DeployAccountV3Transaction),
+ V3(UserDeployAccountV3Transaction),
+}
+
+impl From for BroadcastedDeployAccountTransaction {
+ fn from(transaction: UserDeployAccountTransaction) -> Self {
+ match transaction {
+ UserDeployAccountTransaction::V1(v1) => BroadcastedDeployAccountTransaction::V1(v1.into()),
+ UserDeployAccountTransaction::V3(v3) => BroadcastedDeployAccountTransaction::V3(v3.into()),
+ }
+ }
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-pub struct DeployAccountV1Transaction {
+pub struct UserDeployAccountV1Transaction {
pub class_hash: Felt,
pub contract_address_salt: Felt,
pub constructor_calldata: Vec,
@@ -114,8 +237,22 @@ pub struct DeployAccountV1Transaction {
pub is_query: bool,
}
+impl From for BroadcastedDeployAccountTransactionV1 {
+ fn from(transaction: UserDeployAccountV1Transaction) -> Self {
+ Self {
+ class_hash: transaction.class_hash,
+ contract_address_salt: transaction.contract_address_salt,
+ constructor_calldata: transaction.constructor_calldata,
+ max_fee: transaction.max_fee,
+ signature: transaction.signature,
+ nonce: transaction.nonce,
+ is_query: transaction.is_query,
+ }
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-pub struct DeployAccountV3Transaction {
+pub struct UserDeployAccountV3Transaction {
pub class_hash: Felt,
pub contract_address_salt: Felt,
pub constructor_calldata: Vec,
@@ -128,3 +265,21 @@ pub struct DeployAccountV3Transaction {
pub paymaster_data: Vec,
pub is_query: bool,
}
+
+impl From for BroadcastedDeployAccountTransactionV3 {
+ fn from(transaction: UserDeployAccountV3Transaction) -> Self {
+ Self {
+ class_hash: transaction.class_hash,
+ contract_address_salt: transaction.contract_address_salt,
+ constructor_calldata: transaction.constructor_calldata,
+ signature: transaction.signature,
+ nonce: transaction.nonce,
+ nonce_data_availability_mode: transaction.nonce_data_availability_mode.into(),
+ fee_data_availability_mode: transaction.fee_data_availability_mode.into(),
+ resource_bounds: transaction.resource_bounds.into(),
+ tip: transaction.tip,
+ paymaster_data: transaction.paymaster_data,
+ is_query: transaction.is_query,
+ }
+ }
+}