Skip to content

Commit 89e7a56

Browse files
committed
feat: grpc transaction, read, and write services
1 parent 9ff49c6 commit 89e7a56

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2356
-271
lines changed

Cargo.lock

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

crates/iota-config/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ tracing.workspace = true
3030
# internal dependencies
3131
consensus-config.workspace = true
3232
iota-genesis-common.workspace = true
33-
iota-grpc-api.workspace = true
3433
iota-keys.workspace = true
3534
iota-names.workspace = true
3635
iota-rest-api.workspace = true

crates/iota-config/src/node.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,47 @@ pub struct NodeConfig {
266266
default = "default_grpc_api_config",
267267
skip_serializing_if = "Option::is_none"
268268
)]
269-
pub grpc_api_config: Option<iota_grpc_api::Config>,
269+
pub grpc_api_config: Option<GrpcApiConfig>,
270+
}
271+
272+
/// Configuration for the gRPC API service
273+
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
274+
#[serde(rename_all = "kebab-case")]
275+
pub struct GrpcApiConfig {
276+
/// The address to bind the gRPC server to
277+
#[serde(default = "default_grpc_api_address")]
278+
pub address: std::net::SocketAddr,
279+
280+
/// Buffer size for broadcast channels used for checkpoint streaming
281+
#[serde(default = "default_checkpoint_broadcast_buffer_size")]
282+
pub checkpoint_broadcast_buffer_size: usize,
283+
284+
/// Buffer size for broadcast channels used for event streaming
285+
#[serde(default = "default_event_broadcast_buffer_size")]
286+
pub event_broadcast_buffer_size: usize,
287+
}
288+
289+
impl Default for GrpcApiConfig {
290+
fn default() -> Self {
291+
Self {
292+
address: default_grpc_api_address(),
293+
checkpoint_broadcast_buffer_size: default_checkpoint_broadcast_buffer_size(),
294+
event_broadcast_buffer_size: default_event_broadcast_buffer_size(),
295+
}
296+
}
297+
}
298+
299+
fn default_grpc_api_address() -> std::net::SocketAddr {
300+
use std::net::{IpAddr, Ipv4Addr};
301+
std::net::SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 50051)
302+
}
303+
304+
fn default_checkpoint_broadcast_buffer_size() -> usize {
305+
100
306+
}
307+
308+
fn default_event_broadcast_buffer_size() -> usize {
309+
1000
270310
}
271311

272312
#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize)]
@@ -576,7 +616,7 @@ pub fn default_json_rpc_address() -> SocketAddr {
576616
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 9000)
577617
}
578618

579-
pub fn default_grpc_api_config() -> Option<iota_grpc_api::Config> {
619+
pub fn default_grpc_api_config() -> Option<GrpcApiConfig> {
580620
None
581621
}
582622

crates/iota-core/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ iota-config.workspace = true
6868
iota-execution.workspace = true
6969
iota-framework.workspace = true
7070
iota-genesis-builder.workspace = true
71-
iota-grpc-api.workspace = true
72-
iota-grpc-types.workspace = true
7371
iota-json-rpc-types.workspace = true
7472
iota-macros.workspace = true
7573
iota-metrics.workspace = true

crates/iota-core/src/subscription_handler.rs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use std::sync::Arc;
66

7-
use iota_grpc_api::EventSubscriber;
87
use iota_json_rpc_types::{
98
EffectsWithInput, EventFilter, IotaEvent, IotaTransactionBlockEffects,
109
IotaTransactionBlockEffectsAPI, IotaTransactionBlockEvents, TransactionFilter,
@@ -14,7 +13,6 @@ use prometheus::{
1413
IntCounterVec, IntGaugeVec, Registry, register_int_counter_vec_with_registry,
1514
register_int_gauge_vec_with_registry,
1615
};
17-
use tokio_stream::Stream;
1816
use tracing::{error, instrument, trace};
1917

2018
use crate::streamer::Streamer;
@@ -114,24 +112,17 @@ impl SubscriptionHandler {
114112
Ok(())
115113
}
116114

117-
pub fn subscribe_events(&self, filter: EventFilter) -> impl Stream<Item = IotaEvent> {
118-
self.event_streamer.subscribe(filter)
115+
pub fn subscribe_events(
116+
&self,
117+
filter: EventFilter,
118+
) -> Box<dyn futures::Stream<Item = IotaEvent> + Send + Unpin> {
119+
Box::new(Box::pin(self.event_streamer.subscribe(filter)))
119120
}
120121

121122
pub fn subscribe_transactions(
122123
&self,
123124
filter: TransactionFilter,
124-
) -> impl Stream<Item = IotaTransactionBlockEffects> {
125-
self.transaction_streamer.subscribe(filter)
126-
}
127-
}
128-
129-
// Implement EventSubscriber trait for gRPC integration
130-
impl EventSubscriber for SubscriptionHandler {
131-
fn subscribe_events(
132-
&self,
133-
filter: EventFilter,
134-
) -> Box<dyn futures::Stream<Item = IotaEvent> + Send + Unpin> {
135-
Box::new(Box::pin(self.event_streamer.subscribe(filter)))
125+
) -> Box<dyn futures::Stream<Item = IotaTransactionBlockEffects> + Send + Unpin> {
126+
Box::new(Box::pin(self.transaction_streamer.subscribe(filter)))
136127
}
137128
}

crates/iota-grpc-api/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,14 @@ tonic.workspace = true
2525
tracing.workspace = true
2626

2727
# internal dependencies
28+
fastcrypto.workspace = true
29+
iota-config.workspace = true
30+
iota-core.workspace = true
2831
iota-grpc-types.workspace = true
32+
iota-json-rpc.workspace = true
2933
iota-json-rpc-types.workspace = true
34+
iota-metrics.workspace = true
35+
iota-storage.workspace = true
3036
iota-types.workspace = true
3137
move-core-types.workspace = true
3238

@@ -35,4 +41,5 @@ tonic-build.workspace = true
3541

3642
[dev-dependencies]
3743
iota-config.workspace = true
44+
prometheus.workspace = true
3845
test-cluster.workspace = true

crates/iota-grpc-api/build.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ fn main() {
88
"proto/common.proto",
99
"proto/checkpoint.proto",
1010
"proto/event.proto",
11+
"proto/transaction.proto",
12+
"proto/read.proto",
13+
"proto/write.proto",
1114
],
1215
&["proto/"],
1316
)

crates/iota-grpc-api/proto/checkpoint.proto

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ service CheckpointService {
1111
// Checkpoint operations
1212
rpc StreamCheckpoints (CheckpointStreamRequest) returns (stream Checkpoint);
1313
rpc GetEpochFirstCheckpointSequenceNumber (EpochRequest) returns (CheckpointSequenceNumberResponse);
14+
rpc GetLatestCheckpoint (GetLatestCheckpointRequest) returns (Checkpoint);
1415
}
1516

1617
message CheckpointStreamRequest {
@@ -28,6 +29,12 @@ message CheckpointSequenceNumberResponse {
2829
uint64 sequence_number = 1;
2930
}
3031

32+
// Get the latest checkpoint information
33+
message GetLatestCheckpointRequest {
34+
// If true, get the full CheckpointData (not just the summary).
35+
bool full = 1;
36+
}
37+
3138
message Checkpoint {
3239
uint64 sequence_number = 1;
3340
// Indicates whether bcs_data contains full CheckpointData (true) or just CertifiedCheckpointSummary (false)

crates/iota-grpc-api/proto/common.proto

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,64 @@ message BcsData {
1010
bytes data = 1;
1111
}
1212

13+
// JSON-serialized data container
14+
message JsonData {
15+
bytes data = 1;
16+
}
17+
1318
// 32-byte address type for IOTA addresses, object IDs, package IDs, etc.
1419
message Address {
1520
bytes address = 1;
1621
}
1722

18-
// 32-byte Transaction digest
19-
message TransactionDigest {
23+
// Generic 32-byte digest (used for transactions, objects, etc.)
24+
message Digest {
2025
bytes digest = 1;
2126
}
27+
28+
// Match all events (catch-all filter)
29+
message AllFilter {
30+
}
31+
32+
// Filter by address (sender, package, etc.)
33+
message AddressFilter {
34+
Address address = 1;
35+
}
36+
37+
// Filter by transaction digest
38+
message TransactionDigestFilter {
39+
Digest tx_digest = 1;
40+
}
41+
42+
// Filter by Move module (package + module)
43+
message MoveModuleFilter {
44+
Address package_id = 1; // Package ID
45+
string module = 2; // Module name
46+
}
47+
48+
// Filter by Move event type (package + module + event name)
49+
message MoveEventTypeFilter {
50+
Address package_id = 1; // Package ID
51+
string module = 2; // Module name
52+
string name = 3; // Event name
53+
}
54+
55+
// Filter by Move event module (package + module)
56+
message MoveEventModuleFilter {
57+
Address package_id = 1; // Package ID
58+
string module = 2; // Module name
59+
}
60+
61+
// Filter by Move function (package + module + function)
62+
message MoveFunctionFilter {
63+
Address package_id = 1; // Package ID
64+
optional string module = 2; // Module name (optional)
65+
optional string function = 3; // Function name (optional)
66+
}
67+
68+
// Object reference (ID + version + digest)
69+
message ObjectRef {
70+
Address object_id = 1;
71+
uint64 version = 2;
72+
Digest digest = 3;
73+
}

crates/iota-grpc-api/proto/event.proto

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -28,58 +28,24 @@ message Event {
2828

2929
message EventID {
3030
uint64 event_seq = 1;
31-
iota.grpc.common.TransactionDigest tx_digest = 2;
31+
iota.grpc.common.Digest tx_digest = 2;
3232
}
3333

3434
// Rich event filter that supports gRPC event filtering
3535
message EventFilter {
3636
oneof filter {
37-
AllFilter all = 1;
38-
SenderFilter sender = 2;
39-
TransactionFilter transaction = 3;
40-
MoveModuleFilter move_module = 4;
41-
MoveEventTypeFilter move_event_type = 5;
42-
MoveEventModuleFilter move_event_module = 6;
37+
iota.grpc.common.AllFilter all = 1;
38+
iota.grpc.common.AddressFilter sender = 2;
39+
iota.grpc.common.TransactionDigestFilter transaction = 3;
40+
iota.grpc.common.MoveModuleFilter move_module = 4;
41+
iota.grpc.common.MoveEventTypeFilter move_event_type = 5;
42+
iota.grpc.common.MoveEventModuleFilter move_event_module = 6;
4343
TimeRangeFilter time_range = 7;
4444
}
4545
}
4646

47-
// Match all events (catch-all filter)
48-
message AllFilter {
49-
// Empty - matches all events
50-
}
51-
52-
// Filter by sender address
53-
message SenderFilter {
54-
iota.grpc.common.Address sender = 1; // Sender address
55-
}
56-
57-
// Filter by transaction digest
58-
message TransactionFilter {
59-
iota.grpc.common.TransactionDigest tx_digest = 1; // Transaction digest
60-
}
61-
62-
// Filter by transaction execution module (different from event definition module)
63-
message MoveModuleFilter {
64-
iota.grpc.common.Address package_id = 1; // Package ID
65-
string module = 2; // Module name
66-
}
67-
68-
// Filter by Move event type (package::module::event_name)
69-
message MoveEventTypeFilter {
70-
iota.grpc.common.Address package_id = 1; // Package ID
71-
string module = 2; // Module name (e.g., "request")
72-
string name = 3; // Event name (e.g., "RequestEvent")
73-
}
74-
75-
// Filter by package and module
76-
message MoveEventModuleFilter {
77-
iota.grpc.common.Address package_id = 1; // Package ID
78-
string module = 2; // Module name
79-
}
80-
8147
// Filter by timestamp range
8248
message TimeRangeFilter {
8349
uint64 start_time = 1; // Start time in milliseconds since epoch (inclusive)
8450
uint64 end_time = 2; // End time in milliseconds since epoch (exclusive)
85-
}
51+
}

0 commit comments

Comments
 (0)