Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(katana-grpc): implement starknet grpc server #2717

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
23 changes: 23 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 @@ -97,6 +97,7 @@ katana-codecs-derive = { path = "crates/katana/storage/codecs/derive" }
katana-core = { path = "crates/katana/core", default-features = false }
katana-db = { path = "crates/katana/storage/db" }
katana-executor = { path = "crates/katana/executor" }
katana-grpc = { path = "crates/katana/grpc" }
katana-node = { path = "crates/katana/node", default-features = false }
katana-node-bindings = { path = "crates/katana/node-bindings" }
katana-pipeline = { path = "crates/katana/pipeline" }
Expand Down Expand Up @@ -243,6 +244,7 @@ warp = "0.3"
prost = "0.12"
tonic = { version = "0.11", features = [ "gzip", "tls", "tls-roots" ] }
tonic-build = "0.11"
tonic-health = "0.11"
tonic-reflection = "0.11"
tonic-web = "0.11"

Expand Down
11 changes: 9 additions & 2 deletions crates/katana/grpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@ repository.workspace = true
version.workspace = true

[dependencies]
tonic.workspace = true
katana-primitives.workspace = true

[dev-dependencies]
prost.workspace = true
thiserror.workspace = true
tonic.workspace = true

[build-dependencies]
tonic-build.workspace = true
wasm-tonic-build.workspace = true

[features]
client = [ ]
default = [ "server" ]
server = [ ]
5 changes: 3 additions & 2 deletions crates/katana/grpc/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
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(feature_server.is_ok())
// .build_client(feature_client.is_ok())
.build_transport(true)
.file_descriptor_set_path(out_dir.join("starknet_descriptor.bin"))
.compile(&["proto/starknet.proto"], &["proto"])?;

Expand Down
2 changes: 1 addition & 1 deletion crates/katana/grpc/proto/starknet.proto
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ message BlockHashAndNumberResponse {
message ChainIdRequest {}

message ChainIdResponse {
string chain_id = 1;
types.Felt chain_id = 1;
}

message SyncingRequest {}
Expand Down
7 changes: 6 additions & 1 deletion crates/katana/grpc/proto/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ message BlockID {
oneof identifier {
uint64 number = 1 [json_name = "block_number"];
Felt hash = 2 [json_name = "block_hash"];
string tag = 3 [json_name = "block_tag"];
BlockTag tag = 3 [json_name = "block_tag"];
}
}

enum BlockTag {
PENDING = 0;
LATEST = 1;
}

enum SimulationFlag {
SKIP_FEE_CHARGE = 0;
SKIP_EXECUTE = 1;
Expand Down
78 changes: 77 additions & 1 deletion crates/katana/grpc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,77 @@
//! gRPC implementations.
use katana_primitives::{
block::{BlockIdOrTag, BlockTag},
ContractAddress, Felt,
};

pub mod api {
tonic::include_proto!("starknet");
}

pub mod types {
tonic::include_proto!("types");
}

pub use api::starknet_server::Starknet as StarknetApi;

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
Decode(#[from] ::prost::DecodeError),
}

impl TryFrom<types::Felt> for Felt {
type Error = Error;

fn try_from(value: types::Felt) -> Result<Self, Self::Error> {
if value.value.len() > 32 {
panic!("doesn't fit")
}

Ok(Self::from_bytes_be_slice(&value.value))
}
}

impl From<Felt> for types::Felt {
fn from(value: Felt) -> Self {
Self { value: value.to_bytes_be().to_vec() }
}
}

impl TryFrom<types::Felt> for ContractAddress {
type Error = Error;

fn try_from(value: types::Felt) -> Result<Self, Self::Error> {
Ok(Self::new(Felt::try_from(value)?))
}
}

impl From<types::BlockTag> for BlockTag {
fn from(value: types::BlockTag) -> Self {
match value {
types::BlockTag::Latest => Self::Latest,
types::BlockTag::Pending => Self::Pending,
}
}
}

impl TryFrom<types::BlockId> for BlockIdOrTag {
type Error = Error;

fn try_from(value: types::BlockId) -> Result<Self, Self::Error> {
use types::block_id::Identifier;

let Some(id) = value.identifier else { panic!("missing id") };

match id {
Identifier::Number(num) => Ok(Self::Number(num)),
Identifier::Hash(hash) => {
let felt = Felt::try_from(hash)?;
Ok(Self::Hash(felt))
}
Identifier::Tag(tag) => {
let tag = types::BlockTag::try_from(tag)?;
Ok(Self::Tag(BlockTag::from(tag)))
}
}
}
}
6 changes: 5 additions & 1 deletion crates/katana/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ version.workspace = true
katana-core.workspace = true
katana-db.workspace = true
katana-executor.workspace = true
katana-grpc.workspace = true
katana-pipeline.workspace = true
katana-pool.workspace = true
katana-primitives.workspace = true
Expand All @@ -27,9 +28,12 @@ tower = { workspace = true, features = [ "full" ] }
tower-http = { workspace = true, features = [ "full" ] }
tracing.workspace = true

const_format = "0.2.33"
strum.workspace = true
strum_macros.workspace = true
const_format = "0.2.33"
tonic.workspace = true
tonic-health.workspace = true
tokio.workspace = true

[build-dependencies]
vergen = { version = "9.0.0", features = [ "build", "cargo", "emit_and_set" ] }
Expand Down
15 changes: 15 additions & 0 deletions crates/katana/node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ pub async fn spawn<EF: ExecutorFactory>(
),
config: RpcConfig,
) -> Result<RpcServer> {
use katana_grpc::api::starknet_server::StarknetServer;
use tonic_health::server::HealthReporter;

let (pool, backend, block_producer, validator, forked_client) = node_components;

let mut methods = RpcModule::new(());
Expand All @@ -292,6 +295,18 @@ pub async fn spawn<EF: ExecutorFactory>(
StarknetApi::new(backend.clone(), pool.clone(), block_producer.clone(), validator, cfg)
};

let (mut health_reporter, health_service) = tonic_health::server::health_reporter();
health_reporter.set_serving::<StarknetServer<StarknetApi<EF>>>().await;

tokio::spawn(
tonic::transport::Server::builder()
.add_service(health_service)
.add_service(StarknetServer::new(server.clone()))
.serve(SocketAddr::new(config.addr, 6969)),
);

info!("grpc server listening on port 6969");

methods.merge(StarknetApiServer::into_rpc(server.clone()))?;
methods.merge(StarknetWriteApiServer::into_rpc(server.clone()))?;
methods.merge(StarknetTraceApiServer::into_rpc(server))?;
Expand Down
3 changes: 3 additions & 0 deletions crates/katana/rpc/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ version.workspace = true

[dependencies]
anyhow.workspace = true
async-trait.workspace = true
dojo-metrics.workspace = true
futures.workspace = true
jsonrpsee = { workspace = true, features = [ "server" ] }
katana-core.workspace = true
katana-executor.workspace = true
katana-grpc.workspace = true
katana-pool.workspace = true
katana-primitives.workspace = true
katana-provider.workspace = true
Expand All @@ -24,6 +26,7 @@ metrics.workspace = true
starknet.workspace = true
thiserror.workspace = true
tokio.workspace = true
tonic.workspace = true
tracing.workspace = true
url.workspace = true

Expand Down
Loading
Loading