Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
scarb 2.8.2
scarb 2.15.0
katana 1.7.0
32 changes: 32 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ katana-gateway-server = { path = "crates/gateway/gateway-server" }
katana-fork = { path = "crates/storage/fork" }
katana-gas-price-oracle = { path = "crates/oracle/gas" }
katana-genesis = { path = "crates/genesis" }
katana-grpc = { path = "crates/grpc" }
katana-messaging = { path = "crates/messaging" }
katana-metrics = { path = "crates/metrics" }
katana-node = { path = "crates/node" }
Expand Down Expand Up @@ -194,6 +195,7 @@ tower-service = "0.3"
prost = "0.12"
tonic = { version = "0.11", features = [ "gzip", "tls", "tls-roots", "tls-webpki-roots" ] }
tonic-build = "0.11"
tonic-reflection = "0.11"

# benchmark
criterion = "0.5.1"
Expand Down
3 changes: 2 additions & 1 deletion crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ cartridge = [
"katana-node/cartridge",
"katana-rpc-server/cartridge",
]
default = ["cartridge", "server", "tee"]
grpc = [ "katana-node/grpc" ]
default = ["cartridge", "server", "tee", "grpc"]
explorer = ["katana-node/explorer", "katana-utils/explorer"]
native = ["katana-node/native"]
server = []
Expand Down
58 changes: 44 additions & 14 deletions crates/cli/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use katana_node::config::execution::ExecutionConfig;
use katana_node::config::fork::ForkingConfig;
#[cfg(feature = "server")]
use katana_node::config::gateway::GatewayConfig;
#[cfg(all(feature = "server", feature = "grpc"))]
use katana_node::config::grpc::GrpcConfig;
use katana_node::config::metrics::MetricsConfig;
#[cfg(feature = "cartridge")]
use katana_node::config::paymaster::PaymasterConfig;
Expand Down Expand Up @@ -135,6 +137,10 @@ pub struct SequencerNodeArgs {
#[cfg(feature = "tee")]
#[command(flatten)]
pub tee: TeeOptions,

#[cfg(all(feature = "server", feature = "grpc"))]
#[command(flatten)]
pub grpc: GrpcOptions,
}

impl SequencerNodeArgs {
Expand Down Expand Up @@ -209,6 +215,8 @@ impl SequencerNodeArgs {
let (chain, cs_messaging) = self.chain_spec()?;
let metrics = self.metrics_config();
let gateway = self.gateway_config();
#[cfg(all(feature = "server", feature = "grpc"))]
let grpc = self.grpc_config();
let forking = self.forking_config()?;
let execution = self.execution_config();
let sequencing = self.sequencer_config();
Expand All @@ -222,6 +230,8 @@ impl SequencerNodeArgs {
db,
dev,
rpc,
#[cfg(feature = "grpc")]
grpc,
chain,
metrics,
gateway,
Expand Down Expand Up @@ -448,6 +458,21 @@ impl SequencerNodeArgs {
None
}

#[cfg(all(feature = "server", feature = "grpc"))]
fn grpc_config(&self) -> Option<GrpcConfig> {
if self.grpc.grpc_enable {
use std::time::Duration;

Some(GrpcConfig {
addr: self.grpc.grpc_addr,
port: self.grpc.grpc_port,
timeout: self.grpc.grpc_timeout.map(Duration::from_secs),
})
} else {
None
}
}

#[cfg(feature = "cartridge")]
fn cartridge_config(&self) -> Option<PaymasterConfig> {
if self.cartridge.paymaster {
Expand Down Expand Up @@ -508,6 +533,11 @@ impl SequencerNodeArgs {
}
}

#[cfg(all(feature = "server", feature = "grpc"))]
{
self.grpc.merge(config.grpc.as_ref());
}

self.starknet.merge(config.starknet.as_ref());
self.development.merge(config.development.as_ref());

Expand Down Expand Up @@ -881,13 +911,13 @@ explorer = true
ControllerV108, ControllerV109,
};

assert!(config.chain.genesis().classes.get(&ControllerV104::HASH).is_some());
assert!(config.chain.genesis().classes.get(&ControllerV105::HASH).is_some());
assert!(config.chain.genesis().classes.get(&ControllerV106::HASH).is_some());
assert!(config.chain.genesis().classes.get(&ControllerV107::HASH).is_some());
assert!(config.chain.genesis().classes.get(&ControllerV108::HASH).is_some());
assert!(config.chain.genesis().classes.get(&ControllerV109::HASH).is_some());
assert!(config.chain.genesis().classes.get(&ControllerLatest::HASH).is_some());
assert!(config.chain.genesis().classes.contains_key(&ControllerV104::HASH));
assert!(config.chain.genesis().classes.contains_key(&ControllerV105::HASH));
assert!(config.chain.genesis().classes.contains_key(&ControllerV106::HASH));
assert!(config.chain.genesis().classes.contains_key(&ControllerV107::HASH));
assert!(config.chain.genesis().classes.contains_key(&ControllerV108::HASH));
assert!(config.chain.genesis().classes.contains_key(&ControllerV109::HASH));
assert!(config.chain.genesis().classes.contains_key(&ControllerLatest::HASH));

// Test without paymaster enabled
let args = SequencerNodeArgs::parse_from(["katana"]);
Expand All @@ -896,12 +926,12 @@ explorer = true
// Verify cartridge module is not enabled by default
assert!(!config.rpc.apis.contains(&RpcModuleKind::Cartridge));

assert!(config.chain.genesis().classes.get(&ControllerV104::HASH).is_none());
assert!(config.chain.genesis().classes.get(&ControllerV105::HASH).is_none());
assert!(config.chain.genesis().classes.get(&ControllerV106::HASH).is_none());
assert!(config.chain.genesis().classes.get(&ControllerV107::HASH).is_none());
assert!(config.chain.genesis().classes.get(&ControllerV108::HASH).is_none());
assert!(config.chain.genesis().classes.get(&ControllerV109::HASH).is_none());
assert!(config.chain.genesis().classes.get(&ControllerLatest::HASH).is_none());
assert!(!config.chain.genesis().classes.contains_key(&ControllerV104::HASH));
assert!(!config.chain.genesis().classes.contains_key(&ControllerV105::HASH));
assert!(!config.chain.genesis().classes.contains_key(&ControllerV106::HASH));
assert!(!config.chain.genesis().classes.contains_key(&ControllerV107::HASH));
assert!(!config.chain.genesis().classes.contains_key(&ControllerV108::HASH));
assert!(!config.chain.genesis().classes.contains_key(&ControllerV109::HASH));
assert!(!config.chain.genesis().classes.contains_key(&ControllerLatest::HASH));
}
}
8 changes: 8 additions & 0 deletions crates/cli/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub struct NodeArgsConfig {
pub server: Option<ServerOptions>,
#[cfg(feature = "server")]
pub metrics: Option<MetricsOptions>,
#[cfg(all(feature = "server", feature = "grpc"))]
pub grpc: Option<GrpcOptions>,
#[cfg(feature = "cartridge")]
pub cartridge: Option<CartridgeOptions>,
#[cfg(feature = "explorer")]
Expand Down Expand Up @@ -76,6 +78,12 @@ impl TryFrom<SequencerNodeArgs> for NodeArgsConfig {
if args.metrics == MetricsOptions::default() { None } else { Some(args.metrics) };
}

#[cfg(all(feature = "server", feature = "grpc"))]
{
node_config.grpc =
if args.grpc == GrpcOptions::default() { None } else { Some(args.grpc) };
}

#[cfg(feature = "cartridge")]
{
node_config.cartridge = if args.cartridge == CartridgeOptions::default() {
Expand Down
74 changes: 74 additions & 0 deletions crates/cli/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -835,3 +835,77 @@ impl TeeOptions {
}
}
}

#[cfg(all(feature = "server", feature = "grpc"))]
#[derive(Debug, Args, Clone, Serialize, Deserialize, PartialEq)]
#[command(next_help_heading = "gRPC server options")]
pub struct GrpcOptions {
/// Enable the gRPC server.
///
/// When enabled, the gRPC server will start alongside the JSON-RPC server,
/// providing high-performance endpoints for Starknet operations.
#[arg(long = "grpc")]
#[serde(default)]
pub grpc_enable: bool,

/// gRPC server listening interface.
#[arg(requires = "grpc_enable")]
#[arg(long = "grpc.addr", value_name = "ADDRESS")]
#[arg(default_value_t = default_grpc_addr())]
#[serde(default = "default_grpc_addr")]
pub grpc_addr: IpAddr,

/// gRPC server listening port.
#[arg(requires = "grpc_enable")]
#[arg(long = "grpc.port", value_name = "PORT")]
#[arg(default_value_t = default_grpc_port())]
#[serde(default = "default_grpc_port")]
pub grpc_port: u16,

/// gRPC request timeout in seconds.
#[arg(requires = "grpc_enable")]
#[arg(long = "grpc.timeout", value_name = "TIMEOUT")]
pub grpc_timeout: Option<u64>,
}

#[cfg(all(feature = "server", feature = "grpc"))]
impl Default for GrpcOptions {
fn default() -> Self {
GrpcOptions {
grpc_enable: false,
grpc_addr: default_grpc_addr(),
grpc_port: default_grpc_port(),
grpc_timeout: None,
}
}
}

#[cfg(all(feature = "server", feature = "grpc"))]
impl GrpcOptions {
pub fn merge(&mut self, other: Option<&Self>) {
if let Some(other) = other {
if !self.grpc_enable {
self.grpc_enable = other.grpc_enable;
}
if self.grpc_addr == default_grpc_addr() {
self.grpc_addr = other.grpc_addr;
}
if self.grpc_port == default_grpc_port() {
self.grpc_port = other.grpc_port;
}
if self.grpc_timeout.is_none() {
self.grpc_timeout = other.grpc_timeout;
}
}
}
}

#[cfg(all(feature = "server", feature = "grpc"))]
fn default_grpc_addr() -> IpAddr {
katana_node::config::grpc::DEFAULT_GRPC_ADDR
}

#[cfg(all(feature = "server", feature = "grpc"))]
fn default_grpc_port() -> u16 {
katana_node::config::grpc::DEFAULT_GRPC_PORT
}
35 changes: 35 additions & 0 deletions crates/grpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,44 @@ repository.workspace = true
version.workspace = true

[dependencies]
# Internal dependencies
katana-primitives.workspace = true
katana-provider.workspace = true
katana-pool.workspace = true
katana-rpc-types.workspace = true
katana-rpc-server.workspace = true
katana-rpc-api.workspace = true

# gRPC dependencies
tonic.workspace = true
tonic-reflection = "0.11"
prost.workspace = true
http = "0.2"

# Async runtime
tokio.workspace = true

# Logging
tracing.workspace = true

# Error handling
thiserror.workspace = true

# Serialization
serde_json.workspace = true

# Starknet types
starknet.workspace = true

# Cairo types
cairo-lang-starknet-classes.workspace = true
num-bigint.workspace = true

tower-service.workspace = true

[dev-dependencies]
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
hex = "0.4"

[build-dependencies]
tonic-build.workspace = true
8 changes: 4 additions & 4 deletions crates/grpc/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use std::path::PathBuf;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let out_dir =
PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR environment variable not set"));
let feature_client = std::env::var("CARGO_FEATURE_CLIENT");
let feature_server = std::env::var("CARGO_FEATURE_SERVER");

tonic_build::configure()
.build_server(feature_server.is_ok())
.build_client(feature_client.is_ok())
.build_server(true)
.build_client(true)
.file_descriptor_set_path(out_dir.join("starknet_descriptor.bin"))
// Allow clippy lints on generated code for enum variant naming and size patterns
.type_attribute(".", "#[allow(clippy::enum_variant_names, clippy::large_enum_variant)]")
.compile(&["proto/starknet.proto"], &["proto"])?;

println!("cargo:rerun-if-changed=proto");
Expand Down
7 changes: 7 additions & 0 deletions crates/grpc/proto/common.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
syntax = "proto3";

package common;

message Felt {
bytes value = 1;
}
Loading
Loading