-
Notifications
You must be signed in to change notification settings - Fork 44
test(dapi): dapi-cli example in dapi-grpc #2801
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
base: v2.1-dev
Are you sure you want to change the base?
Conversation
WalkthroughAdds a new Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor U as User
participant CLI as dapi-cli
participant Core as CoreClient (gRPC)
participant Plat as PlatformClient (gRPC)
Note over CLI: parse args, init tracing
U->>CLI: run --url <addr> <Core|Platform> <subcommand>
alt Core subcommand
CLI->>Core: unary or streaming request (GetBlock/Transactions...)
Core-->>CLI: response / stream
CLI-->>U: formatted output / logs
else Platform subcommand
CLI->>Plat: unary or streaming request (GetStatus/Identity/StateTransition...)
Plat-->>CLI: response / stream
CLI-->>U: formatted output / proofs / logs
end
sequenceDiagram
autonumber
actor U as User
participant CLI as dapi-cli (workflow)
participant Plat as PlatformClient
rect rgba(230,245,255,0.6)
Note over CLI: Broadcast + Await Result (Workflow)
U->>CLI: workflow --state-transition <HEX> --prove --timeout <s>
CLI->>CLI: decode hex -> sha256(hash)
CLI->>Plat: broadcastStateTransition(data)
Plat-->>CLI: ack
CLI->>Plat: waitForStateTransitionResult(hash, prove)
alt Result::Proof
Plat-->>CLI: Result(V0.Proof)
CLI-->>U: print metadata + proof
else Result::Error
Plat-->>CLI: Result(V0.Error)
CLI-->>U: print metadata + error
else Result::None
Plat-->>CLI: Result(V0.None)
CLI-->>U: log no-result
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (10)
packages/dapi-grpc/Cargo.toml (2)
81-84: Gate the example on required featuresAdd required-features so dapi-cli only builds when these features are enabled (avoids breakage with --no-default-features).
[[example]] name = "dapi-cli" path = "examples/dapi-cli/main.rs" +required-features = ["core", "platform", "client"]
85-100: Align serde/serde_json versions across deps to reduce duplicatesDev-deps use newer serde/serde_json than main deps. Align to a single workspace version to cut compile units and avoid subtle mismatches.
Please verify with cargo tree -d to confirm no duplicate serde/serde_json versions are pulled in for the example.
packages/dapi-grpc/examples/dapi-cli/core/masternode_status.rs (1)
14-21: Add connect and RPC timeouts on the gRPC EndpointPrevents hangs on bad endpoints and improves UX for the CLI.
- let channel = Channel::from_shared(url.to_string()) - .map_err(|source| CliError::InvalidUrl { - url: url.to_string(), - source: Box::new(source), - })? - .connect() - .await?; + let channel = Channel::from_shared(url.to_string()) + .map_err(|source| CliError::InvalidUrl { + url: url.to_string(), + source: Box::new(source), + })? + .connect_timeout(std::time::Duration::from_secs(5)) + .timeout(std::time::Duration::from_secs(10)) + .connect() + .await?;packages/dapi-grpc/examples/dapi-cli/platform/state_transition/workflow.rs (1)
46-51: Harden connection with Endpoint timeoutsSet connect and overall RPC timeouts to avoid indefinite waits on misconfigured URLs.
- let channel = Channel::from_shared(url.to_string()).map_err(|source| CliError::InvalidUrl { - url: url.to_string(), - source: Box::new(source), - })?; - let mut client = PlatformClient::connect(channel).await?; + let endpoint = Channel::from_shared(url.to_string()).map_err(|source| CliError::InvalidUrl { + url: url.to_string(), + source: Box::new(source), + })? + .connect_timeout(Duration::from_secs(5)) + .timeout(Duration::from_secs(30)); + let mut client = PlatformClient::connect(endpoint).await?;packages/dapi-grpc/examples/dapi-cli/platform/mod.rs (1)
25-37: Optional: add tracing instrumentation on dispatcher.Helps correlate which subcommand ran and with what URL.
+#[tracing::instrument(name = "platform_cli", skip(url), fields(url))] pub async fn run(url: &str, command: PlatformCommand) -> CliResult<()> {packages/dapi-grpc/examples/dapi-cli/platform/protocol.rs (5)
36-41: DRY: factor client creation into a helper.Client/channel setup is duplicated in 3 places. Centralize to reduce copy/paste and keep connection logic consistent. Also aligns with tonic best practices to encapsulate transport setup.
Apply these diffs:
@@ - let channel = Channel::from_shared(url.to_string()).map_err(|source| CliError::InvalidUrl { - url: url.to_string(), - source: Box::new(source), - })?; - let mut client = PlatformClient::connect(channel).await?; + let mut client = platform_client(url).await?; @@ - let channel = Channel::from_shared(url.to_string()).map_err(|source| CliError::InvalidUrl { - url: url.to_string(), - source: Box::new(source), - })?; - let mut client = PlatformClient::connect(channel).await?; + let mut client = platform_client(url).await?; @@ - let channel = Channel::from_shared(url.to_string()).map_err(|source| CliError::InvalidUrl { - url: url.to_string(), - source: Box::new(source), - })?; - let mut client = PlatformClient::connect(channel).await?; + let mut client = platform_client(url).await?;Add this helper in this module:
async fn platform_client(url: &str) -> CliResult<PlatformClient<Channel>> { let channel = Channel::from_shared(url.to_string()).map_err(|source| CliError::InvalidUrl { url: url.to_string(), source: Box::new(source), })?; let client = PlatformClient::connect(channel).await?; Ok(client) }Based on learnings (tonic 0.14.x patterns).
Also applies to: 112-117, 168-174
103-111: Hex UX: support 0x prefix and trim whitespace.Makes input more forgiving without changing semantics.
- let start_pro_tx_hash = if let Some(ref hash) = cmd.start_pro_tx_hash { - hex::decode(hash).map_err(|source| CliError::InvalidHash { + let start_pro_tx_hash = if let Some(ref hash) = cmd.start_pro_tx_hash { + let raw = hash.trim(); + let hex_str = raw + .strip_prefix("0x") + .or_else(|| raw.strip_prefix("0X")) + .unwrap_or(raw); + hex::decode(hex_str).map_err(|source| CliError::InvalidHash { hash: hash.clone(), source, })? } else { Vec::new() };
26-27: Redundant default on boolean flags.Booleans default to false;
default_value_t = falsecan be dropped for brevity.- #[arg(long, default_value_t = false)] + #[arg(long)] pub prove: bool,Also applies to: 92-93
89-90: Optional: boundcountvia clap value_parser.Prevents excessively large requests; 0 still allowed for “server default.”
- #[arg(long, default_value_t = 0)] + #[arg(long, default_value_t = 0, value_parser = clap::value_parser!(u32).range(0..=1000))] pub count: u32,
192-205: Deduplicate printing helpers across modules.
print_metadataandprint_proofduplicate implementations in identity.rs. Extract to a shared helper (e.g., platform::pretty) and reuse.Example new module (packages/dapi-grpc/examples/dapi-cli/platform/pretty.rs):
pub fn print_metadata(metadata: Option<&dapi_grpc::platform::v0::ResponseMetadata>) { if let Some(meta) = metadata { println!("ℹ️ Metadata:"); println!(" height: {}", meta.height); println!(" core_chain_locked_height: {}", meta.core_chain_locked_height); println!(" epoch: {}", meta.epoch); println!(" protocol_version: {}", meta.protocol_version); println!(" chain_id: {}", meta.chain_id); println!(" time_ms: {}", meta.time_ms); } } pub fn print_proof(proof: &dapi_grpc::platform::v0::Proof) { println!("🔐 Proof received:"); println!(" quorum_hash: {}", hex::encode_upper(&proof.quorum_hash)); println!(" signature bytes: {}", proof.signature.len()); println!(" grovedb_proof bytes: {}", proof.grovedb_proof.len()); println!(" round: {}", proof.round); }Then:
use crate::platform::pretty::{print_metadata, print_proof};And remove local duplicates here and in identity.rs.
Also applies to: 307-313
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (15)
packages/dapi-grpc/Cargo.toml(1 hunks)packages/dapi-grpc/examples/dapi-cli/core/block_hash.rs(1 hunks)packages/dapi-grpc/examples/dapi-cli/core/chainlocks.rs(1 hunks)packages/dapi-grpc/examples/dapi-cli/core/masternode.rs(1 hunks)packages/dapi-grpc/examples/dapi-cli/core/masternode_status.rs(1 hunks)packages/dapi-grpc/examples/dapi-cli/core/mod.rs(1 hunks)packages/dapi-grpc/examples/dapi-cli/core/transactions.rs(1 hunks)packages/dapi-grpc/examples/dapi-cli/error.rs(1 hunks)packages/dapi-grpc/examples/dapi-cli/main.rs(1 hunks)packages/dapi-grpc/examples/dapi-cli/platform/identity.rs(1 hunks)packages/dapi-grpc/examples/dapi-cli/platform/mod.rs(1 hunks)packages/dapi-grpc/examples/dapi-cli/platform/protocol.rs(1 hunks)packages/dapi-grpc/examples/dapi-cli/platform/state_transition/mod.rs(1 hunks)packages/dapi-grpc/examples/dapi-cli/platform/state_transition/monitor.rs(1 hunks)packages/dapi-grpc/examples/dapi-cli/platform/state_transition/workflow.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.rs: Format Rust code with cargo fmt
Run Clippy linter for Rust code
Files:
packages/dapi-grpc/examples/dapi-cli/core/masternode.rspackages/dapi-grpc/examples/dapi-cli/core/mod.rspackages/dapi-grpc/examples/dapi-cli/core/chainlocks.rspackages/dapi-grpc/examples/dapi-cli/platform/state_transition/mod.rspackages/dapi-grpc/examples/dapi-cli/core/transactions.rspackages/dapi-grpc/examples/dapi-cli/core/block_hash.rspackages/dapi-grpc/examples/dapi-cli/platform/protocol.rspackages/dapi-grpc/examples/dapi-cli/platform/state_transition/workflow.rspackages/dapi-grpc/examples/dapi-cli/core/masternode_status.rspackages/dapi-grpc/examples/dapi-cli/platform/mod.rspackages/dapi-grpc/examples/dapi-cli/platform/state_transition/monitor.rspackages/dapi-grpc/examples/dapi-cli/platform/identity.rspackages/dapi-grpc/examples/dapi-cli/main.rspackages/dapi-grpc/examples/dapi-cli/error.rs
🧬 Code graph analysis (14)
packages/dapi-grpc/examples/dapi-cli/core/masternode.rs (5)
packages/wasm-drive-verify/src/voting/verify_contests_proof.rs (1)
ciborium(54-54)packages/dapi-grpc/clients/core/v0/web/core_pb_service.d.ts (1)
CoreClient(139-209)packages/dapi-grpc/examples/dapi-cli/core/block_hash.rs (1)
run(15-58)packages/dapi-grpc/examples/dapi-cli/core/chainlocks.rs (1)
run(18-83)packages/dapi-grpc/examples/dapi-cli/core/masternode_status.rs (1)
run(13-44)
packages/dapi-grpc/examples/dapi-cli/core/mod.rs (5)
packages/dapi-grpc/examples/dapi-cli/core/block_hash.rs (1)
run(15-58)packages/dapi-grpc/examples/dapi-cli/core/chainlocks.rs (1)
run(18-83)packages/dapi-grpc/examples/dapi-cli/core/masternode.rs (1)
run(15-56)packages/dapi-grpc/examples/dapi-cli/core/masternode_status.rs (1)
run(13-44)packages/dapi-grpc/examples/dapi-cli/core/transactions.rs (1)
run(22-115)
packages/dapi-grpc/examples/dapi-cli/core/chainlocks.rs (3)
packages/dapi-grpc/clients/core/v0/web/core_pb_service.d.ts (1)
CoreClient(139-209)packages/dapi-grpc/clients/core/v0/web/core_pb.d.ts (2)
BlockHeadersWithChainLocksRequest(511-536)BlockHeaders(589-605)packages/dapi-grpc/examples/dapi-cli/core/mod.rs (1)
run(25-33)
packages/dapi-grpc/examples/dapi-cli/platform/state_transition/mod.rs (3)
packages/dapi-grpc/examples/dapi-cli/platform/mod.rs (1)
run(25-37)packages/dapi-grpc/examples/dapi-cli/platform/state_transition/monitor.rs (1)
run(26-73)packages/dapi-grpc/examples/dapi-cli/platform/state_transition/workflow.rs (1)
run(34-108)
packages/dapi-grpc/examples/dapi-cli/core/transactions.rs (3)
packages/dapi-grpc/clients/core/v0/web/core_pb_service.d.ts (1)
CoreClient(139-209)packages/dapi-grpc/clients/core/v0/web/core_pb.d.ts (3)
TransactionsWithProofsRequest(653-686)RawTransactions(782-798)InstantSendLockMessages(806-822)packages/dapi-grpc/examples/dapi-cli/core/block_hash.rs (1)
run(15-58)
packages/dapi-grpc/examples/dapi-cli/core/block_hash.rs (3)
packages/dapi-grpc/examples/dapi-cli/core/chainlocks.rs (1)
run(18-83)packages/dapi-grpc/examples/dapi-cli/core/masternode_status.rs (1)
run(13-44)packages/dapi-grpc/examples/dapi-cli/core/mod.rs (1)
run(25-33)
packages/dapi-grpc/examples/dapi-cli/platform/protocol.rs (2)
packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts (10)
GetStatusResponseV0(5548-5587)GetStatusRequest(5482-5497)GetProtocolVersionUpgradeStateRequest(3034-3049)GetProtocolVersionUpgradeVoteStatusRequest(3197-3212)GetProtocolVersionUpgradeStateRequestV0(3056-3068)Versions(3138-3152)GetProtocolVersionUpgradeVoteStatusRequestV0(3219-3239)VersionSignals(3311-3325)GetStatusRequestV0(5504-5513)ResponseMetadata(57-84)packages/dapi-grpc/examples/dapi-cli/platform/identity.rs (2)
print_metadata(90-103)print_proof(105-111)
packages/dapi-grpc/examples/dapi-cli/platform/state_transition/workflow.rs (1)
packages/dapi-grpc/examples/dapi-cli/platform/state_transition/monitor.rs (4)
print_error_info(110-117)print_proof_info(92-108)print_response_metadata(75-90)run(26-73)
packages/dapi-grpc/examples/dapi-cli/core/masternode_status.rs (3)
packages/dapi-grpc/clients/core/v0/web/core_pb_service.d.ts (1)
CoreClient(139-209)packages/dapi-grpc/examples/dapi-cli/core/block_hash.rs (1)
run(15-58)packages/dapi-grpc/examples/dapi-cli/core/mod.rs (1)
run(25-33)
packages/dapi-grpc/examples/dapi-cli/platform/mod.rs (3)
packages/dapi-grpc/examples/dapi-cli/platform/identity.rs (1)
run(31-35)packages/dapi-grpc/examples/dapi-cli/platform/state_transition/mod.rs (1)
run(16-21)packages/dapi-grpc/examples/dapi-cli/platform/protocol.rs (3)
run_get_status(168-190)run_upgrade_state(30-81)run_upgrade_vote_status(96-166)
packages/dapi-grpc/examples/dapi-cli/platform/state_transition/monitor.rs (2)
packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts (4)
WaitForStateTransitionResultRequestV0(2769-2786)WaitForStateTransitionResultRequest(2747-2762)ResponseMetadata(57-84)StateTransitionBroadcastError(97-117)packages/dapi-grpc/examples/dapi-cli/platform/state_transition/workflow.rs (1)
run(34-108)
packages/dapi-grpc/examples/dapi-cli/platform/identity.rs (2)
packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts (3)
GetIdentityByPublicKeyHashRequestV0(2459-2476)GetIdentityByPublicKeyHashRequest(2437-2452)ResponseMetadata(57-84)packages/dapi-grpc/examples/dapi-cli/platform/protocol.rs (2)
print_metadata(192-205)print_proof(307-313)
packages/dapi-grpc/examples/dapi-cli/main.rs (4)
packages/dapi-grpc/examples/dapi-cli/core/mod.rs (1)
run(25-33)packages/dapi-grpc/examples/dapi-cli/platform/identity.rs (1)
run(31-35)packages/dapi-grpc/examples/dapi-cli/platform/mod.rs (1)
run(25-37)packages/dapi-grpc/examples/dapi-cli/platform/state_transition/mod.rs (1)
run(16-21)
packages/dapi-grpc/examples/dapi-cli/error.rs (1)
packages/wasm-drive-verify/src/voting/verify_contests_proof.rs (1)
ciborium(54-54)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: Rust packages (dapi-grpc) / Check each feature
- GitHub Check: Rust packages (dapi-grpc) / Tests
- GitHub Check: Rust packages (dapi-grpc) / Unused dependencies
- GitHub Check: Rust packages (dapi-grpc) / Linting
- GitHub Check: Rust packages (wasm-sdk) / Tests
- GitHub Check: Rust packages (rs-sdk-ffi) / Tests
- GitHub Check: Rust packages (rs-dapi-client) / Tests
- GitHub Check: Rust packages (dash-sdk) / Tests
- GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
- GitHub Check: Rust crates security audit
- GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
- GitHub Check: Build Docker images (DAPI, dapi, dapi) / Build DAPI image
- GitHub Check: Build JS packages / Build JS
🔇 Additional comments (11)
packages/dapi-grpc/examples/dapi-cli/platform/state_transition/mod.rs (1)
8-21: State transition routing looks solidEnum + dispatcher are clear; matches other modules. No issues.
packages/dapi-grpc/examples/dapi-cli/main.rs (1)
37-48: Tracing init is pragmaticEnv filter + verbosity mapping is fine for a CLI. No issues.
packages/dapi-grpc/examples/dapi-cli/core/block_hash.rs (1)
1-58: LGTM!The block hash command implementation is well-structured with proper error handling, logging, and output formatting. The height validation, channel creation, and gRPC interaction patterns are consistent with other core commands in the CLI.
packages/dapi-grpc/examples/dapi-cli/core/chainlocks.rs (1)
1-83: LGTM!The chain locks streaming command is well-implemented with clear user feedback, proper stream handling, and consistent error management. The use of
count: 0for unlimited streaming is appropriate, and the response variant handling is comprehensive.packages/dapi-grpc/examples/dapi-cli/core/transactions.rs (1)
1-126: LGTM!The transactions streaming command handles both full payloads and hash-only modes effectively. The stream processing logic is comprehensive, covering all response variants, and the hash_preview helper provides useful output for debugging.
packages/dapi-grpc/examples/dapi-cli/platform/identity.rs (1)
1-88: LGTM!The identity command implementation properly handles hex decoding, channel creation, and response processing. The error handling and output formatting are appropriate for the CLI use case.
packages/dapi-grpc/examples/dapi-cli/core/masternode.rs (1)
1-158: LGTM!The masternode streaming command is well-structured with proper CBOR deserialization, error handling that allows the stream to continue on decode failures, and comprehensive data structures that capture all relevant diff information. The summary output provides useful insights into masternode list changes.
packages/dapi-grpc/examples/dapi-cli/error.rs (1)
1-43: LGTM!The CLI error surface is comprehensive and well-structured using thiserror. The error variants cover all necessary failure modes (URL validation, transport, CBOR decoding, state transitions, etc.) with appropriate context fields. The type alias
CliResult<T>provides a convenient shorthand for consistency across the CLI.packages/dapi-grpc/examples/dapi-cli/core/mod.rs (1)
1-33: LGTM!The core module organization is clean and follows standard Rust CLI patterns. The
CoreCommandenum provides a clear command structure, and the dispatch function properly routes to the appropriate submodule handlers.packages/dapi-grpc/examples/dapi-cli/platform/state_transition/monitor.rs (1)
1-117: LGTM!The state transition monitoring command is well-implemented with proper error handling and comprehensive output for both success and error cases. The helper functions are appropriately scoped with
pub(super)for module-level sharing. The use of structured logging (info!,warn!) instead ofprintln!provides better observability compared to other commands.packages/dapi-grpc/examples/dapi-cli/platform/mod.rs (1)
9-23: Clap subcommand wiring looks correct.Enum variants map cleanly: subcommand enums for Identity/StateTransition and Args structs for Protocol*.
| let status = GrpcStatus::try_from(response.status).unwrap_or(GrpcStatus::Unknown); | ||
| let pro_tx_hash = if response.pro_tx_hash.is_empty() { | ||
| "<unset>".to_string() | ||
| } else { | ||
| hex::encode(response.pro_tx_hash) | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Fix enum conversion: use from_i32, not try_from
Prost enums expose from_i32; TryFrom isn’t implemented by default and will not compile.
- let status = GrpcStatus::try_from(response.status).unwrap_or(GrpcStatus::Unknown);
+ let status = GrpcStatus::from_i32(response.status).unwrap_or(GrpcStatus::Unknown);🏁 Script executed:
#!/bin/bash
# Scan for similar enum conversions that may not compile
rg -nP --type=rust -C2 '\b::try_from\s*\(\s*response\.\w+\s*\)' examplesLength of output: 48
#!/bin/bash
# Rescan for enum conversions in Rust .rs files across the repo
rg -nP --type=rust -C2 'try_from\s*\(\s*response\.' --glob '*.rs' .-->
🏁 Script executed:
#!/bin/bash
# Locate and preview imports in masternode_status.rs
echo "File path(s):"
fd -t f masternode_status.rs .
echo "---- File preview ----"
sed -n '1,50p' $(fd -t f masternode_status.rs .)Length of output: 1716
Replace enum conversion: use from_i32, not try_from
Prost-generated enums provide from_i32; TryFrom<i32> isn’t implemented by default and will not compile.
- let status = GrpcStatus::try_from(response.status).unwrap_or(GrpcStatus::Unknown);
+ let status = GrpcStatus::from_i32(response.status).unwrap_or(GrpcStatus::Unknown);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let status = GrpcStatus::try_from(response.status).unwrap_or(GrpcStatus::Unknown); | |
| let pro_tx_hash = if response.pro_tx_hash.is_empty() { | |
| "<unset>".to_string() | |
| } else { | |
| hex::encode(response.pro_tx_hash) | |
| }; | |
| let status = GrpcStatus::from_i32(response.status).unwrap_or(GrpcStatus::Unknown); | |
| let pro_tx_hash = if response.pro_tx_hash.is_empty() { | |
| "<unset>".to_string() | |
| } else { | |
| hex::encode(response.pro_tx_hash) | |
| }; |
🤖 Prompt for AI Agents
In packages/dapi-grpc/examples/dapi-cli/core/masternode_status.rs around lines
29 to 34, the code uses GrpcStatus::try_from(response.status) which won't
compile because prost enums expose from_i32 rather than TryFrom; replace the
conversion with
GrpcStatus::from_i32(response.status).unwrap_or(GrpcStatus::Unknown) (or
equivalent handling of the Option) so the integer status is converted via
from_i32 and defaults to Unknown when unrecognized.
| fn print_metadata(metadata: Option<&dapi_grpc::platform::v0::ResponseMetadata>) { | ||
| if let Some(meta) = metadata { | ||
| println!("ℹ️ Metadata:"); | ||
| println!(" height: {}", meta.height); | ||
| println!( | ||
| " core_chain_locked_height: {}", | ||
| meta.core_chain_locked_height | ||
| ); | ||
| println!(" epoch: {}", meta.epoch); | ||
| println!(" protocol_version: {}", meta.protocol_version); | ||
| println!(" chain_id: {}", meta.chain_id); | ||
| println!(" time_ms: {}", meta.time_ms); | ||
| } | ||
| } | ||
|
|
||
| fn print_proof(proof: &dapi_grpc::platform::v0::Proof) { | ||
| println!("🔐 Proof received:"); | ||
| println!(" quorum_hash: {}", hex::encode_upper(&proof.quorum_hash)); | ||
| println!(" signature bytes: {}", proof.signature.len()); | ||
| println!(" grovedb_proof bytes: {}", proof.grovedb_proof.len()); | ||
| println!(" round: {}", proof.round); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Extract duplicated helper functions to a shared module.
The print_metadata and print_proof functions are duplicated from packages/dapi-grpc/examples/dapi-cli/platform/protocol.rs (lines 191-204 and 306-312). To maintain DRY principles and ensure consistency, extract these helpers into a shared module within the platform directory.
Consider creating a shared helpers.rs or display.rs module in the platform directory:
Create packages/dapi-grpc/examples/dapi-cli/platform/helpers.rs:
use dapi_grpc::platform::v0::{Proof, ResponseMetadata};
pub fn print_metadata(metadata: Option<&ResponseMetadata>) {
if let Some(meta) = metadata {
println!("ℹ️ Metadata:");
println!(" height: {}", meta.height);
println!(
" core_chain_locked_height: {}",
meta.core_chain_locked_height
);
println!(" epoch: {}", meta.epoch);
println!(" protocol_version: {}", meta.protocol_version);
println!(" chain_id: {}", meta.chain_id);
println!(" time_ms: {}", meta.time_ms);
}
}
pub fn print_proof(proof: &Proof) {
println!("🔐 Proof received:");
println!(" quorum_hash: {}", hex::encode_upper(&proof.quorum_hash));
println!(" signature bytes: {}", proof.signature.len());
println!(" grovedb_proof bytes: {}", proof.grovedb_proof.len());
println!(" round: {}", proof.round);
}Then update both identity.rs and protocol.rs to use:
use super::helpers::{print_metadata, print_proof};🤖 Prompt for AI Agents
In packages/dapi-grpc/examples/dapi-cli/platform/identity.rs around lines 90-111
the print_metadata and print_proof helpers are duplicated from protocol.rs;
extract these two functions into a new shared module file
packages/dapi-grpc/examples/dapi-cli/platform/helpers.rs (exporting pub fn
print_metadata and pub fn print_proof with the same signatures and required
uses), remove the duplicate functions from identity.rs and protocol.rs, add a
mod declaration so the new helpers module is visible (e.g., mod helpers; or
adjust existing module layout), and import the functions where needed with use
super::helpers::{print_metadata, print_proof}; ensure any required imports
(dapi_grpc::platform::v0::{Proof, ResponseMetadata} and hex) are in the helpers
module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/dapi-grpc/Cargo.toml (1)
85-99: Verify serde version discrepancy between main and dev dependencies.The
dev-dependenciessection specifies serde1.0.228, while the main dependencies (line 46) use1.0.219. Both are patch versions and shouldn't introduce breaking changes, but consider aligning them for consistency and simpler version management.Additionally,
dashcoreis pinned to a specific git revision. This is acceptable for dev-only dependencies, but ensure the revision remains available in the upstream repository.Consider updating the serde dev-dependency to match the main dependency version:
-serde = { version = "1.0.228", features = ["derive"] } +serde = { version = "1.0.219", features = ["derive"] }Alternatively, if
1.0.228is intentional (e.g., to test forward compatibility), add a comment explaining the version choice.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (1)
packages/dapi-grpc/Cargo.toml(1 hunks)
🔇 Additional comments (2)
packages/dapi-grpc/Cargo.toml (2)
81-83: Example configuration looks good.The new
dapi-cliexample block follows standard conventions with a clear path reference to the entry point.
101-102: Cargo-machete ignored list updated appropriately.The changes to the ignored list reflect the new build structure: adding
getrandom(indirect tokio dependency) andtonic-prost-build(build-dependency), while removingserde_bytesanddapi-grpc-macros(no longer required by the example). This keeps cargo-machete checks aligned with actual dependency usage.
Issue being fixed or feature implemented
For testing of DAPI, we need some tool
What was done?
Created dapi-grpc/examples/dap-cli
How Has This Been Tested?
On local devnet
Breaking Changes
None
Checklist:
For repository code-owners and collaborators only
Summary by CodeRabbit
New Features
Chores