diff --git a/Cargo.lock b/Cargo.lock index 342e3c962ae88..14f39a0c89df2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13582,6 +13582,7 @@ dependencies = [ "passkey-types", "prometheus", "prost 0.13.3", + "prost-types 0.13.3", "rand 0.8.5", "reqwest 0.12.9", "serde", diff --git a/crates/sui-e2e-tests/Cargo.toml b/crates/sui-e2e-tests/Cargo.toml index 7ba2f8e7f4f9a..86319d8a85e3d 100644 --- a/crates/sui-e2e-tests/Cargo.toml +++ b/crates/sui-e2e-tests/Cargo.toml @@ -69,6 +69,7 @@ shared-crypto.workspace = true sui-sdk-types.workspace = true sui-sdk-transaction-builder.workspace = true tonic.workspace = true +prost-types.workspace = true passkey-types.workspace = true passkey-client.workspace = true diff --git a/crates/sui-e2e-tests/tests/rpc/checkpoints.rs b/crates/sui-e2e-tests/tests/rpc/checkpoints.rs index 6620d0ff39f12..3a69cc54bced0 100644 --- a/crates/sui-e2e-tests/tests/rpc/checkpoints.rs +++ b/crates/sui-e2e-tests/tests/rpc/checkpoints.rs @@ -137,6 +137,7 @@ async fn get_checkpoint() { sequence_number: Some(sequence_number.unwrap()), digest: Some(digest.clone().unwrap()), options: None, + read_mask: None, }) .await .unwrap_err(); @@ -401,6 +402,7 @@ async fn get_full_checkpoint() { sequence_number: Some(sequence_number.unwrap()), digest: Some(digest.clone().unwrap()), options: None, + read_mask: None, }) .await .unwrap_err(); @@ -420,8 +422,14 @@ async fn subscribe_checkpoint() { .await .unwrap(); + let request = SubscribeCheckpointsRequest { + read_mask: Some(prost_types::FieldMask { + paths: vec!["sequence_number".to_owned()], + }), + }; + let mut stream = client - .subscribe_checkpoints(SubscribeCheckpointsRequest::default()) + .subscribe_checkpoints(request) .await .unwrap() .into_inner(); diff --git a/crates/sui-e2e-tests/tests/rpc/resolve.rs b/crates/sui-e2e-tests/tests/rpc/resolve.rs index 0787a08e3449a..74ed2c462b07b 100644 --- a/crates/sui-e2e-tests/tests/rpc/resolve.rs +++ b/crates/sui-e2e-tests/tests/rpc/resolve.rs @@ -1,6 +1,7 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 +use prost_types::FieldMask; use shared_crypto::intent::Intent; use sui_keys::keystore::AccountKeystore; use sui_macros::sim_test; @@ -20,10 +21,16 @@ fn build_resolve_request( transaction: &unresolved::Transaction, simulate: bool, ) -> ResolveTransactionRequest { + let read_mask = if simulate { + Some(FieldMask { + paths: vec!["simulation".to_string()], + }) + } else { + None + }; ResolveTransactionRequest { unresolved_transaction: Some(serde_json::to_string(transaction).unwrap()), - simulate: Some(simulate), - simulate_options: None, + read_mask, } } diff --git a/crates/sui-rpc-api/proto/sui/node/v2/node_service.proto b/crates/sui-rpc-api/proto/sui/node/v2/node_service.proto index f6e7e5232fdd9..8ab5e69f4ee38 100644 --- a/crates/sui-rpc-api/proto/sui/node/v2/node_service.proto +++ b/crates/sui-rpc-api/proto/sui/node/v2/node_service.proto @@ -1,10 +1,11 @@ // The sui.node.v2 package contains API definitions for services that are -// expected to run on Full nodes. +// expected to run on Fullnodes. syntax = "proto3"; package sui.node.v2; import "google/protobuf/empty.proto"; +import "google/protobuf/field_mask.proto"; import "google/protobuf/timestamp.proto"; import "sui/types/types.proto"; @@ -12,7 +13,7 @@ import "sui/types/types.proto"; // RPC Node interface // -// Service for reading data from a Sui Full node. +// Service for reading data from a Sui Fullnode. service NodeService { // Query a node for information about its current state. rpc GetNodeInfo(GetNodeInfoRequest) returns (GetNodeInfoResponse); @@ -138,12 +139,14 @@ message GetTransactionRequest { // Required. The digest of the requested transaction. optional sui.types.Digest digest = 1; - // Optional. Options for specifying which parts of the `GetTransactionResponse` - // should be returned. + // DEPRECATED To be removed in the next release optional GetTransactionOptions options = 3; + // Optional. Mask for specifying which parts of the `GetTransactionResponse` + // should be returned. + optional google.protobuf.FieldMask read_mask = 4; } -// Options for which parts of the `GetTransactionResponse` should be returned. +// DEPRECATED To be removed in the next release message GetTransactionOptions { // Include the `sui.types.Transaction` message in the response. // @@ -239,10 +242,14 @@ message GetObjectRequest { // the object is returned. optional uint64 version = 2; - // Optional. Options for specifying which parts of the `GetObjectResponse` should be returned. + // DEPRECATED To be removed in the next release optional GetObjectOptions options = 3; + // Optional. Mask for specifying which parts of the `GetObjectResponse` + // should be returned. + optional google.protobuf.FieldMask read_mask = 4; } +// DEPRECATED To be removed in the next release message GetObjectOptions { // Include the `sui.types.Object` message in the response. // @@ -287,12 +294,14 @@ message GetCheckpointRequest { // Optional. The digest of the requested checkpoint. optional sui.types.Digest digest = 2; - // Optional. Options for specifying which parts of the `GetCheckpointResponse` - // should be returned. + // DEPRECATED To be removed in the next release optional GetCheckpointOptions options = 3; + // Optional. Mask for specifying which parts of the `GetCheckpointResponse` + // should be returned. + optional google.protobuf.FieldMask read_mask = 4; } -// Options for which parts of the `GetCheckpointResponse` should be returned. +// DEPRECATED To be removed in the next release message GetCheckpointOptions { // Include the `sui.types.CheckpointSummary` in the response. // @@ -361,12 +370,14 @@ message GetFullCheckpointRequest { // Optional. The digest of the requested checkpoint. optional sui.types.Digest digest = 2; - // Optional. Options for specifying which parts of the - // `GetFullCheckpointResponse` should be returned. + // DEPRECATED To be removed in the next release optional GetFullCheckpointOptions options = 3; + // Optional. Mask for specifying which parts of the `GetFullCheckpointResponse` + // should be returned. + optional google.protobuf.FieldMask read_mask = 4; } -// Options for which parts of the `GetFullCheckpointResponse` should be returned. +// DEPRECATED To be removed in the next release message GetFullCheckpointOptions { // Include the `sui.types.CheckpointSummary` in the response. // @@ -566,11 +577,14 @@ message ExecuteTransactionRequest { // transaction, encoded as bytes. repeated bytes signatures_bytes = 4; - // Optional. Options for specifying which parts of the - // `ExecuteTransactionResponse` should be returned. + // DEPRECATED To be removed in the next release optional ExecuteTransactionOptions options = 5; + // Optional. Mask for specifying which parts of the + // `ExecuteTransactionResponse` should be returned. + optional google.protobuf.FieldMask read_mask = 6; } +// DEPRECATED To be removed in the next release message ExecuteTransactionOptions { // Include the `sui.types.TransactionEffects` message in the response. // diff --git a/crates/sui-rpc-api/proto/sui/node/v2alpha/node_service.proto b/crates/sui-rpc-api/proto/sui/node/v2alpha/node_service.proto index 2b1066399c8d9..daf310cb891fd 100644 --- a/crates/sui-rpc-api/proto/sui/node/v2alpha/node_service.proto +++ b/crates/sui-rpc-api/proto/sui/node/v2alpha/node_service.proto @@ -7,6 +7,7 @@ syntax = "proto3"; package sui.node.v2alpha; +import "google/protobuf/field_mask.proto"; import "sui/node/v2/node_service.proto"; import "sui/types/types.proto"; @@ -160,14 +161,7 @@ message GetGasInfoResponse { message SimulateTransactionRequest { optional sui.types.Bcs transaction_bcs = 2; - optional SimulateTransactionOptions options = 3; -} - -message SimulateTransactionOptions { - // Include the `BalanceChange`s in the response. - // - // Defaults to `false` if not included. - optional bool balance_changes = 8; + optional google.protobuf.FieldMask read_mask = 3; } message SimulateTransactionResponse { @@ -180,8 +174,7 @@ message ResolveTransactionRequest { // TODO FIX TYPE // Json unresolved transaction type optional string unresolved_transaction = 1; - optional bool simulate = 2; - optional SimulateTransactionOptions simulate_options = 3; + optional google.protobuf.FieldMask read_mask = 3; } message ResolveTransactionResponse { diff --git a/crates/sui-rpc-api/proto/sui/node/v2alpha/subscription_service.proto b/crates/sui-rpc-api/proto/sui/node/v2alpha/subscription_service.proto index d2da8c070a836..749e2ec8e4774 100644 --- a/crates/sui-rpc-api/proto/sui/node/v2alpha/subscription_service.proto +++ b/crates/sui-rpc-api/proto/sui/node/v2alpha/subscription_service.proto @@ -7,6 +7,7 @@ syntax = "proto3"; package sui.node.v2alpha; +import "google/protobuf/field_mask.proto"; import "sui/node/v2/node_service.proto"; // Service for subscribing to data from a Sui Fullnode @@ -21,16 +22,16 @@ service SubscriptionService { // event the subscription terminates (either by the client/server or by the // connection breaking), clients will be able to reinitailize a subscription // and then leverage other APIs (e.g. - // sui.node.v1.NodeService.GetFullCheckpoint) in order to request data for + // sui.node.v2.NodeService.GetFullCheckpoint) in order to request data for // the checkpoints they missed. rpc SubscribeCheckpoints(SubscribeCheckpointsRequest) returns (stream SubscribeCheckpointsResponse); } // Request message for SubscriptionService.SubscribeCheckpoints message SubscribeCheckpointsRequest { - // Optional. Options for specifiying which parts of the + // Optional. Mask for specifiying which parts of the // SubscribeCheckpointsResponse should be returned. - optional sui.node.v2.GetFullCheckpointOptions options = 1; + optional google.protobuf.FieldMask read_mask = 3; } // Response message for SubscriptionService.SubscribeCheckpoints diff --git a/crates/sui-rpc-api/src/client/mod.rs b/crates/sui-rpc-api/src/client/mod.rs index 75e9a89344dac..74e71166ee75f 100644 --- a/crates/sui-rpc-api/src/client/mod.rs +++ b/crates/sui-rpc-api/src/client/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 mod response_ext; +use prost_types::FieldMask; pub use response_ext::ResponseExt; use tap::Pipe; @@ -99,6 +100,12 @@ impl Client { contents: Some(false), contents_bcs: Some(false), }), + read_mask: Some(FieldMask { + paths: ["summary_bcs", "signature"] + .into_iter() + .map(ToOwned::to_owned) + .collect(), + }), }; let ( @@ -143,6 +150,21 @@ impl Client { object: Some(false), object_bcs: Some(true), }), + read_mask: Some(FieldMask { + paths: [ + "summary_bcs", + "signature", + "contents_bcs", + "transactions.transaction_bcs", + "transactions.effects_bcs", + "transactions.events_bcs", + "transactions.input_objects.object_bcs", + "transactions.output_objects.object_bcs", + ] + .into_iter() + .map(ToOwned::to_owned) + .collect(), + }), }; let (metadata, response, _extentions) = self @@ -181,6 +203,9 @@ impl Client { object: Some(false), object_bcs: Some(true), }), + read_mask: Some(FieldMask { + paths: ["object_bcs"].into_iter().map(ToOwned::to_owned).collect(), + }), }; let (metadata, GetObjectResponse { object_bcs, .. }, _extentions) = @@ -217,6 +242,12 @@ impl Client { events_bcs: Some(true), ..(parameters.to_owned().into()) }), + read_mask: Some(FieldMask { + paths: ["effects_bcs", "events_bcs", "balance_changes"] + .into_iter() + .map(ToOwned::to_owned) + .collect(), + }), }; let (metadata, response, _extentions) = self diff --git a/crates/sui-rpc-api/src/grpc.rs b/crates/sui-rpc-api/src/grpc.rs index 14d6af9d5edea..ec2d5493fc7ca 100644 --- a/crates/sui-rpc-api/src/grpc.rs +++ b/crates/sui-rpc-api/src/grpc.rs @@ -3,7 +3,7 @@ use crate::proto::types::Bcs; use http::{Request, Response}; -use std::{convert::Infallible, pin::Pin, sync::Arc}; +use std::{convert::Infallible, pin::Pin}; use tap::Pipe; use tonic::{ body::{boxed, BoxBody}, @@ -91,7 +91,13 @@ impl crate::proto::node::v2::node_service_server::NodeService for crate::RpcServ .try_into() .map_err(|_| tonic::Status::new(tonic::Code::InvalidArgument, "invalid object_id"))?; let version = request.version; - let options = request.options.unwrap_or_default().into(); + let options = if let Some(read_mask) = request.read_mask { + crate::types::GetObjectOptions::from_read_mask(read_mask) + } else if let Some(options) = request.options { + options.into() + } else { + Default::default() + }; self.get_object(object_id, version, options) .map(Into::into) @@ -118,7 +124,13 @@ impl crate::proto::node::v2::node_service_server::NodeService for crate::RpcServ tonic::Status::new(tonic::Code::InvalidArgument, "invalid transaction_digest") })?; - let options = request.options.unwrap_or_default().into(); + let options = if let Some(read_mask) = request.read_mask { + crate::types::GetTransactionOptions::from_read_mask(read_mask) + } else if let Some(options) = request.options { + options.into() + } else { + Default::default() + }; self.get_transaction(transaction_digest, &options) .map(Into::into) @@ -152,7 +164,13 @@ impl crate::proto::node::v2::node_service_server::NodeService for crate::RpcServ (None, None) => None, }; - let options = request.options.unwrap_or_default().into(); + let options = if let Some(read_mask) = request.read_mask { + crate::types::GetCheckpointOptions::from_read_mask(read_mask) + } else if let Some(options) = request.options { + options.into() + } else { + Default::default() + }; self.get_checkpoint(checkpoint, options) .map(Into::into) @@ -192,7 +210,13 @@ impl crate::proto::node::v2::node_service_server::NodeService for crate::RpcServ } }; - let options = request.options.unwrap_or_default().into(); + let options = if let Some(read_mask) = request.read_mask { + crate::types::GetFullCheckpointOptions::from_read_mask(read_mask) + } else if let Some(options) = request.options { + options.into() + } else { + Default::default() + }; self.get_full_checkpoint(checkpoint, &options) .map(Into::into) @@ -300,7 +324,7 @@ impl crate::proto::node::v2alpha::subscription_service_server::SubscriptionServi &self, request: tonic::Request, ) -> Result, tonic::Status> { - let options = request.into_inner().options.unwrap_or_default(); + let read_mask = request.into_inner().read_mask.unwrap_or_default(); let Some(mut receiver) = self.register_subscription().await else { return Err(tonic::Status::unavailable( @@ -315,7 +339,7 @@ impl crate::proto::node::v2alpha::subscription_service_server::SubscriptionServi break; }; - let checkpoint = apply_checkpont_options(&options, Arc::unwrap_or_clone(checkpoint)); + let checkpoint = apply_checkpoint_read_mask(&read_mask, &checkpoint); let response = SubscribeCheckpointsResponse { cursor: Some(cursor), checkpoint: Some(checkpoint), @@ -333,69 +357,101 @@ impl crate::proto::node::v2alpha::subscription_service_server::SubscriptionServi // // This function assumes that the provided checkpoint has all fields populated and that applying // the requested options is a matter of removing the data that the request didn't ask for. -fn apply_checkpont_options( - options: &crate::proto::node::v2::GetFullCheckpointOptions, - mut checkpoint: crate::proto::node::v2::GetFullCheckpointResponse, +fn apply_checkpoint_read_mask( + read_mask: &prost_types::FieldMask, + checkpoint: &crate::proto::node::v2::GetFullCheckpointResponse, ) -> crate::proto::node::v2::GetFullCheckpointResponse { - if !options.summary() { - checkpoint.summary = None; - } - if !options.summary_bcs() { - checkpoint.summary_bcs = None; - } - if !options.signature() { - checkpoint.signature = None; - } - if !options.contents() { - checkpoint.contents = None; - } - if !options.contents_bcs() { - checkpoint.contents_bcs = None; - } + let mut response = crate::proto::node::v2::GetFullCheckpointResponse::default(); - for transaction in checkpoint.transactions.iter_mut() { - if !options.transaction() { - transaction.transaction = None; - } - if !options.transaction_bcs() { - transaction.transaction_bcs = None; - } - if !options.effects() { - transaction.effects = None; - } - if !options.effects_bcs() { - transaction.effects_bcs = None; - } - if !options.events() { - transaction.events = None; - } - if !options.events_bcs() { - transaction.events_bcs = None; - } - if !options.input_objects() { - transaction.input_objects_old = None; - transaction.input_objects.clear(); - } - if !options.output_objects() { - transaction.output_objects_old = None; - transaction.output_objects.clear(); - } + for path in &read_mask.paths { + let mut components = path.split('.'); + let Some(component) = components.next() else { + continue; + }; - for object in transaction - .input_objects - .iter_mut() - .chain(transaction.output_objects.iter_mut()) - { - if !options.object() { - object.object = None; - } - if !options.object_bcs() { - object.object_bcs = None; + match component { + "sequence_number" => response.sequence_number = checkpoint.sequence_number, + "digest" => response.digest = checkpoint.digest.clone(), + "summary" => response.summary = checkpoint.summary.clone(), + "summary_bcs" => response.summary_bcs = checkpoint.summary_bcs.clone(), + "signature" => response.signature = checkpoint.signature.clone(), + "contents" => response.contents = checkpoint.contents.clone(), + "contents_bcs" => response.contents_bcs = checkpoint.contents_bcs.clone(), + "transactions" => { + let Some(component) = components.next() else { + response.transactions = checkpoint.transactions.clone(); + continue; + }; + if response.transactions.len() != checkpoint.transactions.len() { + response.transactions = vec![Default::default(); checkpoint.transactions.len()]; + } + + for (src, dst) in checkpoint + .transactions + .iter() + .zip(response.transactions.iter_mut()) + { + match component { + "digest" => dst.digest = src.digest.clone(), + "transaction" => dst.transaction = src.transaction.clone(), + "transaction_bcs" => dst.transaction_bcs = src.transaction_bcs.clone(), + "effects" => dst.effects = src.effects.clone(), + "effects_bcs" => dst.effects_bcs = src.effects_bcs.clone(), + "events" => dst.events = src.events.clone(), + "events_bcs" => dst.events_bcs = src.events_bcs.clone(), + "input_objects" => { + let Some(component) = components.clone().next() else { + dst.input_objects = src.input_objects.clone(); + continue; + }; + if dst.input_objects.len() != src.input_objects.len() { + dst.input_objects = + vec![Default::default(); src.input_objects.len()]; + } + + for (src, dst) in + src.input_objects.iter().zip(dst.input_objects.iter_mut()) + { + match component { + "object" => dst.object = src.object.clone(), + "object_bcs" => dst.object_bcs = src.object_bcs.clone(), + // Ignore unknown field + _ => {} + } + } + } + "output_objects" => { + let Some(component) = components.clone().next() else { + dst.output_objects = src.output_objects.clone(); + continue; + }; + if dst.output_objects.len() != src.output_objects.len() { + dst.output_objects = + vec![Default::default(); src.output_objects.len()]; + } + + for (src, dst) in + src.output_objects.iter().zip(dst.output_objects.iter_mut()) + { + match component { + "object" => dst.object = src.object.clone(), + "object_bcs" => dst.object_bcs = src.object_bcs.clone(), + // Ignore unknown field + _ => {} + } + } + } + // Ignore unknown field + _ => {} + } + } } + // Ignore unknown field + _ => {} } } - checkpoint + response } #[tonic::async_trait] @@ -466,11 +522,9 @@ impl crate::proto::node::v2alpha::node_service_server::NodeService for crate::Rp tonic::Status, > { let request = request.into_inner(); + //TODO use provided read_mask let parameters = crate::types::SimulateTransactionQueryParameters { - balance_changes: request - .options - .and_then(|options| options.balance_changes) - .unwrap_or(false), + balance_changes: false, input_objects: false, output_objects: false, }; @@ -511,25 +565,29 @@ impl crate::proto::node::v2alpha::node_service_server::NodeService for crate::Rp tonic::Status, > { let request = request.into_inner(); + let read_mask = request.read_mask.unwrap_or_default(); + //TODO use provided read_mask let simulate_parameters = crate::types::SimulateTransactionQueryParameters { - balance_changes: request - .simulate_options - .and_then(|options| options.balance_changes) - .unwrap_or(false), + balance_changes: false, input_objects: false, output_objects: false, }; let parameters = crate::types::ResolveTransactionQueryParameters { - simulate: request.simulate.unwrap_or(false), + simulate: read_mask + .paths + .iter() + .any(|path| path.starts_with("simulation")), simulate_transaction_parameters: simulate_parameters, }; - let unresolved_transaction = serde_json::from_str(request.unresolved_transaction()) - .map_err(|_| { - tonic::Status::new( - tonic::Code::InvalidArgument, - "invalid unresolved_transaction", - ) - })?; + let unresolved_transaction = serde_json::from_str( + &request.unresolved_transaction.unwrap_or_default(), + ) + .map_err(|_| { + tonic::Status::new( + tonic::Code::InvalidArgument, + "invalid unresolved_transaction", + ) + })?; let response = self.resolve_transaction(parameters, unresolved_transaction)?; diff --git a/crates/sui-rpc-api/src/proto/generated/sui.node.v2.fds.bin b/crates/sui-rpc-api/src/proto/generated/sui.node.v2.fds.bin index 1720704e62a74..5229d80b5c3b4 100644 Binary files a/crates/sui-rpc-api/src/proto/generated/sui.node.v2.fds.bin and b/crates/sui-rpc-api/src/proto/generated/sui.node.v2.fds.bin differ diff --git a/crates/sui-rpc-api/src/proto/generated/sui.node.v2.rs b/crates/sui-rpc-api/src/proto/generated/sui.node.v2.rs index efe989948f0d9..5a552bb2f53f1 100644 --- a/crates/sui-rpc-api/src/proto/generated/sui.node.v2.rs +++ b/crates/sui-rpc-api/src/proto/generated/sui.node.v2.rs @@ -57,12 +57,15 @@ pub struct GetTransactionRequest { /// Required. The digest of the requested transaction. #[prost(message, optional, tag = "1")] pub digest: ::core::option::Option, - /// Optional. Options for specifying which parts of the `GetTransactionResponse` - /// should be returned. + /// DEPRECATED To be removed in the next release #[prost(message, optional, tag = "3")] pub options: ::core::option::Option, + /// Optional. Mask for specifying which parts of the `GetTransactionResponse` + /// should be returned. + #[prost(message, optional, tag = "4")] + pub read_mask: ::core::option::Option<::prost_types::FieldMask>, } -/// Options for which parts of the `GetTransactionResponse` should be returned. +/// DEPRECATED To be removed in the next release #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetTransactionOptions { /// Include the `sui.types.Transaction` message in the response. @@ -168,10 +171,15 @@ pub struct GetObjectRequest { /// the object is returned. #[prost(uint64, optional, tag = "2")] pub version: ::core::option::Option, - /// Optional. Options for specifying which parts of the `GetObjectResponse` should be returned. + /// DEPRECATED To be removed in the next release #[prost(message, optional, tag = "3")] pub options: ::core::option::Option, + /// Optional. Mask for specifying which parts of the `GetObjectResponse` + /// should be returned. + #[prost(message, optional, tag = "4")] + pub read_mask: ::core::option::Option<::prost_types::FieldMask>, } +/// DEPRECATED To be removed in the next release #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetObjectOptions { /// Include the `sui.types.Object` message in the response. @@ -219,12 +227,15 @@ pub struct GetCheckpointRequest { /// Optional. The digest of the requested checkpoint. #[prost(message, optional, tag = "2")] pub digest: ::core::option::Option, - /// Optional. Options for specifying which parts of the `GetCheckpointResponse` - /// should be returned. + /// DEPRECATED To be removed in the next release #[prost(message, optional, tag = "3")] pub options: ::core::option::Option, + /// Optional. Mask for specifying which parts of the `GetCheckpointResponse` + /// should be returned. + #[prost(message, optional, tag = "4")] + pub read_mask: ::core::option::Option<::prost_types::FieldMask>, } -/// Options for which parts of the `GetCheckpointResponse` should be returned. +/// DEPRECATED To be removed in the next release #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetCheckpointOptions { /// Include the `sui.types.CheckpointSummary` in the response. @@ -298,12 +309,15 @@ pub struct GetFullCheckpointRequest { /// Optional. The digest of the requested checkpoint. #[prost(message, optional, tag = "2")] pub digest: ::core::option::Option, - /// Optional. Options for specifying which parts of the - /// `GetFullCheckpointResponse` should be returned. + /// DEPRECATED To be removed in the next release #[prost(message, optional, tag = "3")] pub options: ::core::option::Option, + /// Optional. Mask for specifying which parts of the `GetFullCheckpointResponse` + /// should be returned. + #[prost(message, optional, tag = "4")] + pub read_mask: ::core::option::Option<::prost_types::FieldMask>, } -/// Options for which parts of the `GetFullCheckpointResponse` should be returned. +/// DEPRECATED To be removed in the next release #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetFullCheckpointOptions { /// Include the `sui.types.CheckpointSummary` in the response. @@ -512,11 +526,15 @@ pub struct ExecuteTransactionRequest { /// transaction, encoded as bytes. #[prost(bytes = "bytes", repeated, tag = "4")] pub signatures_bytes: ::prost::alloc::vec::Vec<::prost::bytes::Bytes>, - /// Optional. Options for specifying which parts of the - /// `ExecuteTransactionResponse` should be returned. + /// DEPRECATED To be removed in the next release #[prost(message, optional, tag = "5")] pub options: ::core::option::Option, + /// Optional. Mask for specifying which parts of the + /// `ExecuteTransactionResponse` should be returned. + #[prost(message, optional, tag = "6")] + pub read_mask: ::core::option::Option<::prost_types::FieldMask>, } +/// DEPRECATED To be removed in the next release #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct ExecuteTransactionOptions { /// Include the `sui.types.TransactionEffects` message in the response. @@ -626,7 +644,7 @@ pub mod node_service_client { )] use tonic::codegen::*; use tonic::codegen::http::Uri; - /// Service for reading data from a Sui Full node. + /// Service for reading data from a Sui Fullnode. #[derive(Debug, Clone)] pub struct NodeServiceClient { inner: tonic::client::Grpc, @@ -1052,7 +1070,7 @@ pub mod node_service_server { tonic::Status, >; } - /// Service for reading data from a Sui Full node. + /// Service for reading data from a Sui Fullnode. #[derive(Debug)] pub struct NodeServiceServer { inner: Arc, diff --git a/crates/sui-rpc-api/src/proto/generated/sui.node.v2alpha.fds.bin b/crates/sui-rpc-api/src/proto/generated/sui.node.v2alpha.fds.bin index 4434a6cddf882..3981c320ab4ac 100644 Binary files a/crates/sui-rpc-api/src/proto/generated/sui.node.v2alpha.fds.bin and b/crates/sui-rpc-api/src/proto/generated/sui.node.v2alpha.fds.bin differ diff --git a/crates/sui-rpc-api/src/proto/generated/sui.node.v2alpha.rs b/crates/sui-rpc-api/src/proto/generated/sui.node.v2alpha.rs index 3e3d3160a26cb..266a928dbda70 100644 --- a/crates/sui-rpc-api/src/proto/generated/sui.node.v2alpha.rs +++ b/crates/sui-rpc-api/src/proto/generated/sui.node.v2alpha.rs @@ -155,15 +155,7 @@ pub struct SimulateTransactionRequest { #[prost(message, optional, tag = "2")] pub transaction_bcs: ::core::option::Option, #[prost(message, optional, tag = "3")] - pub options: ::core::option::Option, -} -#[derive(Clone, Copy, PartialEq, ::prost::Message)] -pub struct SimulateTransactionOptions { - /// Include the `BalanceChange`s in the response. - /// - /// Defaults to `false` if not included. - #[prost(bool, optional, tag = "8")] - pub balance_changes: ::core::option::Option, + pub read_mask: ::core::option::Option<::prost_types::FieldMask>, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct SimulateTransactionResponse { @@ -180,10 +172,8 @@ pub struct ResolveTransactionRequest { /// Json unresolved transaction type #[prost(string, optional, tag = "1")] pub unresolved_transaction: ::core::option::Option<::prost::alloc::string::String>, - #[prost(bool, optional, tag = "2")] - pub simulate: ::core::option::Option, #[prost(message, optional, tag = "3")] - pub simulate_options: ::core::option::Option, + pub read_mask: ::core::option::Option<::prost_types::FieldMask>, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct ResolveTransactionResponse { @@ -1011,12 +1001,12 @@ pub mod node_service_server { } } /// Request message for SubscriptionService.SubscribeCheckpoints -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SubscribeCheckpointsRequest { - /// Optional. Options for specifiying which parts of the + /// Optional. Mask for specifiying which parts of the /// SubscribeCheckpointsResponse should be returned. - #[prost(message, optional, tag = "1")] - pub options: ::core::option::Option, + #[prost(message, optional, tag = "3")] + pub read_mask: ::core::option::Option<::prost_types::FieldMask>, } /// Response message for SubscriptionService.SubscribeCheckpoints #[derive(Clone, PartialEq, ::prost::Message)] @@ -1131,7 +1121,7 @@ pub mod subscription_service_client { /// event the subscription terminates (either by the client/server or by the /// connection breaking), clients will be able to reinitailize a subscription /// and then leverage other APIs (e.g. - /// sui.node.v1.NodeService.GetFullCheckpoint) in order to request data for + /// sui.node.v2.NodeService.GetFullCheckpoint) in order to request data for /// the checkpoints they missed. pub async fn subscribe_checkpoints( &mut self, @@ -1198,7 +1188,7 @@ pub mod subscription_service_server { /// event the subscription terminates (either by the client/server or by the /// connection breaking), clients will be able to reinitailize a subscription /// and then leverage other APIs (e.g. - /// sui.node.v1.NodeService.GetFullCheckpoint) in order to request data for + /// sui.node.v2.NodeService.GetFullCheckpoint) in order to request data for /// the checkpoints they missed. async fn subscribe_checkpoints( &self, diff --git a/crates/sui-rpc-api/src/proto/node.rs b/crates/sui-rpc-api/src/proto/node.rs index 6b62d0c38482e..0a5d78f14fd16 100644 --- a/crates/sui-rpc-api/src/proto/node.rs +++ b/crates/sui-rpc-api/src/proto/node.rs @@ -231,6 +231,7 @@ impl GetObjectRequest { object_id: Some(object_id.into()), version: None, options: None, + read_mask: None, } } @@ -431,6 +432,7 @@ impl GetCheckpointRequest { sequence_number: None, digest: None, options: None, + read_mask: None, } } @@ -439,6 +441,7 @@ impl GetCheckpointRequest { sequence_number: None, digest: Some(digest.into()), options: None, + read_mask: None, } } @@ -447,6 +450,7 @@ impl GetCheckpointRequest { sequence_number: Some(sequence_number), digest: None, options: None, + read_mask: None, } } @@ -629,6 +633,7 @@ impl GetTransactionRequest { Self { digest: Some(digest.into()), options: None, + read_mask: None, } } @@ -968,6 +973,7 @@ impl GetFullCheckpointRequest { sequence_number: None, digest: None, options: None, + read_mask: None, } } @@ -976,6 +982,7 @@ impl GetFullCheckpointRequest { sequence_number: None, digest: Some(digest.into()), options: None, + read_mask: None, } } @@ -984,6 +991,7 @@ impl GetFullCheckpointRequest { sequence_number: Some(sequence_number), digest: None, options: None, + read_mask: None, } } diff --git a/crates/sui-rpc-api/src/types.rs b/crates/sui-rpc-api/src/types.rs index 0e0b1e6704a8d..2daae7b046ee6 100644 --- a/crates/sui-rpc-api/src/types.rs +++ b/crates/sui-rpc-api/src/types.rs @@ -1,6 +1,8 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 +use prost_types::FieldMask; + /// Chain ID of the current chain pub const X_SUI_CHAIN_ID: &str = "x-sui-chain-id"; @@ -107,6 +109,20 @@ impl GetObjectOptions { pub fn include_object_bcs(&self) -> bool { self.object_bcs.unwrap_or(false) } + + pub fn from_read_mask(read_mask: FieldMask) -> Self { + let mut options = Self::default(); + + for path in read_mask.paths { + match path.as_str() { + "object" => options.object = Some(true), + "object_bcs" => options.object_bcs = Some(true), + _ => {} + } + } + + options + } } #[serde_with::serde_as] @@ -188,6 +204,23 @@ impl GetCheckpointOptions { pub fn include_contents_bcs(&self) -> bool { self.contents_bcs.unwrap_or(false) } + + pub fn from_read_mask(read_mask: FieldMask) -> Self { + let mut options = Self::default(); + + for path in read_mask.paths { + match path.as_str() { + "summary" => options.summary = Some(true), + "summary_bcs" => options.summary_bcs = Some(true), + "signature" => options.signature = Some(true), + "contents" => options.contents = Some(true), + "contents_bcs" => options.contents_bcs = Some(true), + _ => {} + } + } + + options + } } #[serde_with::serde_as] @@ -319,6 +352,26 @@ impl GetTransactionOptions { pub fn include_events_bcs(&self) -> bool { self.events_bcs.unwrap_or(false) } + + pub fn from_read_mask(read_mask: FieldMask) -> Self { + let mut options = Self::default(); + + for path in read_mask.paths { + match path.as_str() { + "transaction" => options.transaction = Some(true), + "transaction_bcs" => options.transaction_bcs = Some(true), + "effects" => options.effects = Some(true), + "effects_bcs" => options.effects_bcs = Some(true), + "events" => options.events = Some(true), + "events_bcs" => options.events_bcs = Some(true), + "signatures" => options.signatures = Some(true), + "signatures_bytes" => options.signatures_bytes = Some(true), + _ => {} + } + } + + options + } } /// Options for the execute transaction endpoint @@ -383,6 +436,23 @@ impl ExecuteTransactionOptions { pub fn include_output_objects(&self) -> bool { false } + + pub fn from_read_mask(read_mask: FieldMask) -> Self { + let mut options = Self::default(); + + for path in read_mask.paths { + match path.as_str() { + "effects" => options.effects = Some(true), + "effects_bcs" => options.effects_bcs = Some(true), + "events" => options.events = Some(true), + "events_bcs" => options.events_bcs = Some(true), + "balance_changes" => options.balance_changes = Some(true), + _ => {} + } + } + + options + } } /// Response type for the execute transaction endpoint @@ -590,6 +660,45 @@ impl GetFullCheckpointOptions { || self.include_input_objects() || self.include_output_objects() } + + pub fn from_read_mask(read_mask: FieldMask) -> Self { + let mut options = Self::default(); + + for path in read_mask.paths { + match path.as_str() { + "summary" => options.summary = Some(true), + "summary_bcs" => options.summary_bcs = Some(true), + "signature" => options.signature = Some(true), + "contents" => options.contents = Some(true), + "contents_bcs" => options.contents_bcs = Some(true), + "transactions.transaction" => options.transaction = Some(true), + "transactions.transaction_bcs" => options.transaction_bcs = Some(true), + "transactions.effects" => options.effects = Some(true), + "transactions.effects_bcs" => options.effects_bcs = Some(true), + "transactions.events" => options.events = Some(true), + "transactions.events_bcs" => options.events_bcs = Some(true), + "transactions.input_objects.object" => { + options.input_objects = Some(true); + options.object = Some(true); + } + "transactions.input_objects.object_bcs" => { + options.input_objects = Some(true); + options.object_bcs = Some(true); + } + "transactions.output_objects.object" => { + options.output_objects = Some(true); + options.object = Some(true); + } + "transactions.output_objects.object_bcs" => { + options.output_objects = Some(true); + options.object_bcs = Some(true); + } + _ => {} + } + } + + options + } } #[derive(Clone, Debug, PartialEq)]