From af724edbcb02aed9c789dc99fa012debac873ab4 Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Sun, 13 Apr 2025 13:36:35 -0700 Subject: [PATCH 01/13] Use prost for grpc generated types --- Cargo.lock | 130 +- admin-http-gateway/Cargo.toml | 2 +- admin-http-gateway/src/main.rs | 13 +- api/Cargo.toml | 3 +- api/proto/printable.proto | 1 + api/src/convert/account_key.rs | 31 +- api/src/convert/amount.rs | 91 +- api/src/convert/archive_block.rs | 113 +- api/src/convert/block.rs | 127 +- api/src/convert/block_contents.rs | 22 +- api/src/convert/block_contents_hash.rs | 19 +- api/src/convert/block_id.rs | 30 +- api/src/convert/block_metadata.rs | 68 +- api/src/convert/block_signature.rs | 63 +- api/src/convert/collateral.rs | 11 +- api/src/convert/compressed_ristretto.rs | 24 +- api/src/convert/curve_scalar.rs | 23 +- api/src/convert/dcap_evidence.rs | 10 +- api/src/convert/ed25519_multisig.rs | 40 +- api/src/convert/ed25519_signature.rs | 16 +- .../convert/enclave_report_data_contents.rs | 8 +- api/src/convert/input_ring.rs | 60 +- api/src/convert/input_secret.rs | 37 +- api/src/convert/key_image.rs | 22 +- api/src/convert/mint_config.rs | 75 +- api/src/convert/mint_tx.rs | 90 +- api/src/convert/node.rs | 14 +- api/src/convert/output_secret.rs | 19 +- api/src/convert/public_address.rs | 31 +- api/src/convert/quorum_set.rs | 28 +- api/src/convert/quote3.rs | 7 +- api/src/convert/reduced_tx_out.rs | 31 +- api/src/convert/ring_mlsag.rs | 39 +- api/src/convert/ristretto_private.rs | 10 +- api/src/convert/signature_rct_bulletproofs.rs | 57 +- api/src/convert/signed_contingent_input.rs | 54 +- api/src/convert/signing_data.rs | 28 +- api/src/convert/tx.rs | 41 +- api/src/convert/tx_hash.rs | 22 +- api/src/convert/tx_in.rs | 86 +- api/src/convert/tx_out.rs | 91 +- api/src/convert/tx_out_confirmation_number.rs | 19 +- api/src/convert/tx_out_gift_code.rs | 39 +- api/src/convert/tx_out_membership_element.rs | 28 +- api/src/convert/tx_out_membership_proof.rs | 65 +- api/src/convert/tx_prefix.rs | 50 +- api/src/convert/unsigned_tx.rs | 60 +- api/src/convert/validated_mint_config.rs | 31 +- api/src/convert/verification_report.rs | 17 +- api/src/convert/verification_signature.rs | 8 +- api/src/display.rs | 140 +- api/src/lib.rs | 10 - api/tests/tokens.rs | 21 +- attest/api/Cargo.toml | 4 +- attest/api/src/convert.rs | 57 +- attest/api/src/lib.rs | 11 - connection/Cargo.toml | 4 +- connection/src/thick.rs | 60 +- connection/src/traits.rs | 15 +- consensus/api/Cargo.toml | 4 +- consensus/api/src/conversions.rs | 72 +- consensus/api/src/lib.rs | 38 +- consensus/enclave/tests/enclave_api_tests.rs | 32 +- consensus/mint-client/Cargo.toml | 3 +- consensus/mint-client/src/bin/main.rs | 20 +- consensus/mint-client/src/config.rs | 15 +- consensus/mint-client/src/printers.rs | 9 +- consensus/service/Cargo.toml | 3 +- .../service/src/api/attested_api_service.rs | 10 +- .../service/src/api/blockchain_api_service.rs | 56 +- .../service/src/api/client_api_service.rs | 125 +- consensus/service/src/api/grpc_error.rs | 24 +- consensus/service/src/api/peer_api_service.rs | 138 +- consensus/service/src/consensus_service.rs | 39 +- consensus/tool/Cargo.toml | 2 +- consensus/tool/src/main.rs | 10 +- fog/api/Cargo.toml | 3 +- fog/api/src/conversions.rs | 69 +- fog/api/src/lib.rs | 48 +- fog/api/tests/fog_types.rs | 118 +- fog/block_provider/Cargo.toml | 2 +- fog/block_provider/src/lib.rs | 2 +- fog/block_provider/src/local.rs | 14 +- fog/block_provider/src/mobilecoind.rs | 49 +- fog/distribution/Cargo.toml | 2 +- fog/enclave_connection/Cargo.toml | 2 +- fog/enclave_connection/src/lib.rs | 15 +- fog/ingest/client/Cargo.toml | 3 +- fog/ingest/client/src/lib.rs | 61 +- fog/ingest/client/src/main.rs | 8 +- fog/ingest/server/Cargo.toml | 3 +- fog/ingest/server/src/attested_api_service.rs | 2 +- fog/ingest/server/src/connection.rs | 19 +- fog/ingest/server/src/controller.rs | 55 +- fog/ingest/server/src/controller_state.rs | 9 +- fog/ingest/server/src/ingest_peer_service.rs | 7 +- fog/ingest/server/src/ingest_service.rs | 84 +- fog/ingest/server/src/server.rs | 13 +- fog/ingest/server/src/state_file.rs | 12 +- fog/ingest/server/test-utils/src/lib.rs | 4 +- fog/ingest/server/tests/peer_key_sharing.rs | 18 +- fog/ingest/server/tests/three_node_cluster.rs | 6 +- fog/ledger/connection/Cargo.toml | 4 +- fog/ledger/connection/src/block.rs | 12 +- fog/ledger/connection/src/error.rs | 8 +- fog/ledger/connection/src/key_image.rs | 2 +- fog/ledger/connection/src/merkle_proof.rs | 9 +- fog/ledger/connection/src/router_client.rs | 49 +- fog/ledger/connection/src/untrusted.rs | 43 +- fog/ledger/server/Cargo.toml | 2 +- fog/ledger/server/src/block_service.rs | 48 +- fog/ledger/server/src/key_image_service.rs | 44 +- .../server/src/key_image_store_server.rs | 4 +- fog/ledger/server/src/merkle_proof_service.rs | 2 +- fog/ledger/server/src/router_admin_service.rs | 12 +- fog/ledger/server/src/router_handlers.rs | 50 +- fog/ledger/server/src/router_server.rs | 16 +- fog/ledger/server/src/router_service.rs | 30 +- .../server/src/untrusted_tx_out_service.rs | 17 +- fog/ledger/server/tests/router_connection.rs | 6 +- fog/load_testing/Cargo.toml | 2 +- fog/load_testing/src/bin/ingest.rs | 4 +- fog/overseer/server/Cargo.toml | 2 +- fog/overseer/server/src/metrics/mod.rs | 14 +- fog/overseer/server/src/worker.rs | 13 +- fog/report/api/Cargo.toml | 4 +- fog/report/api/src/lib.rs | 72 +- fog/report/api/test-utils/Cargo.toml | 1 - fog/report/api/test-utils/src/lib.rs | 45 +- fog/report/api/tests/fog_types.rs | 67 +- fog/report/cli/Cargo.toml | 2 +- fog/report/connection/Cargo.toml | 2 +- fog/report/connection/src/lib.rs | 8 +- fog/report/server/Cargo.toml | 2 +- fog/report/server/src/server.rs | 4 +- fog/report/server/src/service.rs | 5 +- fog/report/server/tests/grpc_apis.rs | 82 +- fog/sample-paykit/Cargo.toml | 4 +- .../src/bin/sample_paykit_remote_wallet.rs | 25 +- fog/sample-paykit/src/cached_tx_data/mod.rs | 80 +- fog/sample-paykit/src/client.rs | 10 +- fog/sample-paykit/src/lib.rs | 12 +- fog/test-client/Cargo.toml | 2 +- fog/types/src/ingest_common.rs | 3 - fog/view/connection/Cargo.toml | 2 +- .../connection/src/fog_view_router_client.rs | 55 +- fog/view/connection/src/lib.rs | 6 +- fog/view/load-test/Cargo.toml | 2 +- fog/view/server/Cargo.toml | 2 +- fog/view/server/src/bin/router.rs | 2 +- fog/view/server/src/fog_view_router_server.rs | 12 +- .../server/src/fog_view_router_service.rs | 17 +- fog/view/server/src/fog_view_service.rs | 46 +- fog/view/server/src/router_admin_service.rs | 12 +- fog/view/server/src/router_request_handler.rs | 58 +- fog/view/server/src/server.rs | 4 +- .../server/src/shard_responses_processor.rs | 48 +- fog/view/server/test-utils/Cargo.toml | 2 +- fog/view/server/test-utils/src/lib.rs | 2 +- go-grpc-gateway/testing/Cargo.toml | 2 +- go-grpc-gateway/testing/src/server.rs | 4 +- go-grpc-gateway/testing/src/service.rs | 5 +- ledger/distribution/Cargo.toml | 2 +- ledger/distribution/src/main.rs | 18 +- ledger/sync/Cargo.toml | 4 +- .../sync/src/reqwest_transactions_fetcher.rs | 6 +- light-client/cli/Cargo.toml | 3 +- light-client/cli/src/bin/main.rs | 14 +- mobilecoind-dev-faucet/Cargo.toml | 2 +- mobilecoind-dev-faucet/src/data_types.rs | 44 +- mobilecoind-dev-faucet/src/lib.rs | 83 +- mobilecoind-dev-faucet/src/slam/mod.rs | 31 +- .../src/slam/prepared_utxo.rs | 53 +- mobilecoind-dev-faucet/src/worker.rs | 142 +- mobilecoind-json/Cargo.toml | 3 +- mobilecoind-json/src/bin/main.rs | 317 +- mobilecoind-json/src/data_types.rs | 1098 +++--- mobilecoind/Cargo.toml | 3 +- mobilecoind/api/Cargo.toml | 4 +- mobilecoind/api/proto/mobilecoind_api.proto | 32 +- mobilecoind/api/src/lib.rs | 28 +- mobilecoind/src/conversions.rs | 261 +- mobilecoind/src/error.rs | 9 - mobilecoind/src/service.rs | 3160 +++++++++-------- mobilecoind/src/t3_store.rs | 17 +- mobilecoind/src/test_utils.rs | 2 +- mobilecoind/src/transaction_memo.rs | 113 +- peers/Cargo.toml | 3 +- peers/src/connection.rs | 102 +- peers/src/threaded_broadcaster.rs | 2 +- peers/test-utils/Cargo.toml | 2 +- peers/test-utils/src/lib.rs | 5 +- t3/api/Cargo.toml | 4 +- t3/api/proto/external/v1/external.proto | 14 +- t3/api/src/lib.rs | 20 +- t3/connection/Cargo.toml | 3 +- t3/connection/src/lib.rs | 28 +- test-vectors/b58-encodings/build.rs | 16 +- util/b58-decoder/src/bin/main.rs | 83 +- util/build/grpc/Cargo.toml | 4 +- util/build/grpc/src/lib.rs | 23 +- util/grpc-admin-tool/Cargo.toml | 2 +- util/grpc-admin-tool/src/bin/main.rs | 20 +- util/grpc/Cargo.toml | 4 +- util/grpc/src/admin_service.rs | 62 +- util/grpc/src/build_info_service.rs | 28 +- util/grpc/src/health_service.rs | 25 +- util/grpc/src/lib.rs | 11 +- util/grpc/src/server_cert_reloader.rs | 107 +- util/keyfile/src/lib.rs | 17 +- util/keyfile/tests/b58-length.rs | 7 +- util/metrics/Cargo.toml | 6 +- util/metrics/src/service_metrics.rs | 28 - util/serial/Cargo.toml | 3 +- util/serial/src/lib.rs | 17 +- watcher/Cargo.toml | 2 +- watcher/src/attestation_evidence_collector.rs | 2 +- watcher/src/bin/main.rs | 2 +- 218 files changed, 5778 insertions(+), 4981 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b5dfa14206..568dbc16f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1136,6 +1136,17 @@ dependencies = [ "syn 2.0.52", ] +[[package]] +name = "derive-new" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "devise" version = "0.4.1" @@ -1460,28 +1471,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "synstructure", -] - [[package]] name = "fastrand" version = "2.0.1" @@ -1791,22 +1780,27 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e398946b5721d72478eb647260a1b7c1d5f70f0de35399846c3913bd369a33e" dependencies = [ + "bytes 1.1.0", "futures-executor", "futures-util", "grpcio-sys", "libc", "log", "parking_lot 0.12.0", - "protobuf", + "prost", ] [[package]] name = "grpcio-compiler" -version = "0.7.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f1abac9f330ac9ee0950220c10eea84d66479cede4836f0b924407fecf093c" +checksum = "375292b9a9e3f5f9c6ef978d1f28070a6b56ab78f8be0cfbee16c62d5b0fa361" dependencies = [ - "protobuf", + "derive-new", + "prost", + "prost-build", + "prost-types", + "tempfile", ] [[package]] @@ -2541,7 +2535,6 @@ dependencies = [ "mc-watcher-api", "pem", "prost", - "protobuf", "rand", "rand_core", "rand_hc", @@ -2597,7 +2590,7 @@ dependencies = [ "mc-util-build-grpc", "mc-util-build-script", "mc-util-serial", - "protobuf", + "prost", ] [[package]] @@ -2884,6 +2877,7 @@ dependencies = [ "der", "displaydoc", "grpcio", + "mc-api", "mc-attest-ake", "mc-attest-api", "mc-attest-core", @@ -2899,6 +2893,7 @@ dependencies = [ "mc-util-grpc", "mc-util-serial", "mc-util-uri", + "prost", "rand", "rand_hc", "retry", @@ -2934,7 +2929,7 @@ dependencies = [ "mc-util-build-grpc", "mc-util-build-script", "mc-util-serial", - "protobuf", + "prost", "rand_core", "rand_hc", ] @@ -3112,7 +3107,6 @@ dependencies = [ "mc-util-parse", "mc-util-uri", "pem", - "protobuf", "rand", "serde", "serde_json", @@ -3236,7 +3230,6 @@ dependencies = [ "mc-util-uri", "mockall", "once_cell", - "protobuf", "rand", "rand_core", "rand_hc", @@ -3643,7 +3636,6 @@ dependencies = [ "mc-util-test-helper", "mc-watcher-api", "prost", - "protobuf", ] [[package]] @@ -3754,7 +3746,6 @@ dependencies = [ "mc-util-uri", "mc-watcher", "predicates", - "protobuf", "rand", "retry", "serde_json", @@ -3931,7 +3922,6 @@ dependencies = [ "mc-util-uri", "mc-watcher", "mc-watcher-api", - "protobuf", "rand_core", "rand_hc", "retry", @@ -4007,7 +3997,7 @@ dependencies = [ "mc-util-grpc", "mc-util-serial", "mc-util-uri", - "protobuf", + "prost", "retry", "sha2 0.10.8", ] @@ -4330,7 +4320,6 @@ dependencies = [ "mc-util-build-grpc", "mc-util-build-script", "prost", - "protobuf", ] [[package]] @@ -4339,7 +4328,6 @@ version = "7.0.0" dependencies = [ "mc-util-serial", "prost", - "protobuf", ] [[package]] @@ -4514,7 +4502,7 @@ dependencies = [ "mc-util-telemetry", "mc-util-test-helper", "mc-util-uri", - "protobuf", + "prost", "rand", "serde_json", ] @@ -5001,7 +4989,7 @@ dependencies = [ "mc-transaction-core", "mc-util-telemetry", "mc-util-test-helper", - "protobuf", + "prost", "retry", "rusoto_core", "rusoto_s3", @@ -5062,7 +5050,7 @@ dependencies = [ "mc-util-test-helper", "mc-util-uri", "mockall", - "protobuf", + "prost", "rand", "reqwest", "retry", @@ -5089,7 +5077,6 @@ dependencies = [ "mc-util-grpc", "mc-util-serial", "mc-util-uri", - "protobuf", "rayon", "serde_json", ] @@ -5204,7 +5191,6 @@ dependencies = [ "pem", "portpicker", "prost", - "protobuf", "rand", "rand_chacha", "rand_core", @@ -5232,7 +5218,7 @@ dependencies = [ "mc-util-build-grpc", "mc-util-build-script", "mc-util-uri", - "protobuf", + "prost", "rand", ] @@ -5286,7 +5272,6 @@ dependencies = [ "mc-util-from-random", "mc-util-grpc", "mc-util-serial", - "protobuf", "rand", "rocket", "serde", @@ -5371,7 +5356,6 @@ dependencies = [ "mc-util-serial", "mc-util-uri", "mockall", - "protobuf", "rand", "rand_hc", "retry", @@ -5727,7 +5711,7 @@ dependencies = [ "mc-util-build-grpc", "mc-util-build-script", "mc-util-uri", - "protobuf", + "prost", ] [[package]] @@ -5742,7 +5726,6 @@ dependencies = [ "mc-t3-api", "mc-util-grpc", "mc-util-uri", - "protobuf", ] [[package]] @@ -6041,8 +6024,9 @@ dependencies = [ name = "mc-util-build-grpc" version = "7.0.0" dependencies = [ + "grpcio-compiler", "mc-util-build-script", - "protoc-grpcio", + "prost-build", ] [[package]] @@ -6160,7 +6144,7 @@ dependencies = [ "mc-util-serial", "mc-util-uri", "prometheus", - "protobuf", + "prost", "rand", "retry", "serde", @@ -6262,7 +6246,7 @@ dependencies = [ "lazy_static", "mc-common", "prometheus", - "protobuf", + "prost", "serde_json", ] @@ -6304,7 +6288,6 @@ name = "mc-util-serial" version = "7.0.0" dependencies = [ "prost", - "protobuf", "serde", "serde_cbor", "serde_json", @@ -7297,39 +7280,6 @@ version = "2.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" -[[package]] -name = "protobuf-codegen" -version = "2.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "033460afb75cf755fcfc16dfaed20b86468082a2ea24e05ac35ab4a099a017d6" -dependencies = [ - "protobuf", -] - -[[package]] -name = "protoc" -version = "2.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ef1dc036942fac2470fdb8a911f125404ee9129e9e807f3d12d8589001a38f" -dependencies = [ - "log", - "which", -] - -[[package]] -name = "protoc-grpcio" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "980d0ed845138df84f72beb72faf6d726c70c99d0debb2b5e1e7dee61f853df7" -dependencies = [ - "failure", - "grpcio-compiler", - "protobuf", - "protobuf-codegen", - "protoc", - "tempfile", -] - [[package]] name = "quick-error" version = "1.2.3" @@ -8637,18 +8587,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -[[package]] -name = "synstructure" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", -] - [[package]] name = "system-configuration" version = "0.5.1" diff --git a/admin-http-gateway/Cargo.toml b/admin-http-gateway/Cargo.toml index 0d970f79d0..d490c88bc8 100644 --- a/admin-http-gateway/Cargo.toml +++ b/admin-http-gateway/Cargo.toml @@ -13,7 +13,7 @@ mc-util-grpc = { path = "../util/grpc" } mc-util-uri = { path = "../util/uri" } clap = { version = "4.5", features = ["derive", "env"] } -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } rocket = { version = "0.5.1", features = ["json"] } serde = "1.0" serde_derive = "1.0" diff --git a/admin-http-gateway/src/main.rs b/admin-http-gateway/src/main.rs index 21dd5b528b..cf03e13400 100644 --- a/admin-http-gateway/src/main.rs +++ b/admin-http-gateway/src/main.rs @@ -8,7 +8,7 @@ use clap::Parser; use grpcio::ChannelBuilder; use mc_common::logger::{create_app_logger, log, o}; -use mc_util_grpc::{admin, admin_grpc::AdminApiClient, ConnectionUriGrpcioChannel, Empty}; +use mc_util_grpc::{admin, admin::AdminApiClient, ConnectionUriGrpcioChannel}; use mc_util_uri::AdminUri; use rocket::{ form::Form, @@ -83,7 +83,7 @@ impl TryFrom<&admin::GetInfoResponse> for JsonInfoResponse { fn info(state: &rocket::State) -> Result, String> { let info = state .admin_api_client - .get_info(&Empty::new()) + .get_info(&()) .map_err(|err| format!("Failed getting info: {err}"))?; Ok(Json(JsonInfoResponse::try_from(&info)?)) @@ -99,10 +99,11 @@ fn set_rust_log( state: &rocket::State, form: Form, ) -> Result { - let mut req = admin::SetRustLogRequest::new(); - req.set_rust_log(form.rust_log.clone()); + let req = admin::SetRustLogRequest { + rust_log: form.rust_log.clone(), + }; - let _resp = state + state .admin_api_client .set_rust_log(&req) .map_err(|err| format!("failed setting rust_log: {err}"))?; @@ -114,7 +115,7 @@ fn set_rust_log( fn metrics(state: &rocket::State) -> Result { let resp = state .admin_api_client - .get_prometheus_metrics(&Empty::new()) + .get_prometheus_metrics(&()) .map_err(|err| format!("failed getting metrics: {err}"))?; Ok(resp.metrics) } diff --git a/api/Cargo.toml b/api/Cargo.toml index e4254bbe49..6eea6200f2 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -30,7 +30,7 @@ crc = "3.0.0" displaydoc = { version = "0.2", default-features = false } mc-sgx-core-types = "0.11.0" mc-sgx-dcap-types = "0.11.0" -protobuf = "2.27.1" +prost = { version = "0.11", default-features = false } curve25519-dalek = { version = "4.1.3", default-features = false } @@ -58,7 +58,6 @@ mc-util-zip-exact = { path = "../util/zip-exact" } generic-array = "0.14" pem = "3.0" -prost = { version = "0.11", default-features = false } rand = "0.8" rand_core = "0.6" rand_hc = "0.3" diff --git a/api/proto/printable.proto b/api/proto/printable.proto index e3ee162dbd..515f9ce154 100644 --- a/api/proto/printable.proto +++ b/api/proto/printable.proto @@ -49,6 +49,7 @@ message TransferPayload { } // Message encoding information required to locate a TxOut, +// // un-blind the amount, and spend the TxOut. This can be used to give // MobileCoin to both FOG & non-FOG users who may not yet have // a MobileCoin account enabled diff --git a/api/src/convert/account_key.rs b/api/src/convert/account_key.rs index db412e2986..c51c4eeaf8 100644 --- a/api/src/convert/account_key.rs +++ b/api/src/convert/account_key.rs @@ -7,24 +7,13 @@ use mc_account_keys::AccountKey; impl From<&AccountKey> for external::AccountKey { fn from(src: &AccountKey) -> Self { - let mut dst = external::AccountKey::new(); - - dst.set_view_private_key(external::RistrettoPrivate::from(src.view_private_key())); - dst.set_spend_private_key(external::RistrettoPrivate::from(src.spend_private_key())); - - if let Some(url) = src.fog_report_url() { - dst.set_fog_report_url(url.to_string()); - } - - if let Some(spki) = src.fog_authority_spki() { - dst.set_fog_authority_spki(spki.to_vec()); + Self { + view_private_key: Some(src.view_private_key().into()), + spend_private_key: Some(src.spend_private_key().into()), + fog_report_url: src.fog_report_url().unwrap_or_default().into(), + fog_authority_spki: src.fog_authority_spki().unwrap_or_default().to_vec(), + fog_report_id: src.fog_report_id().unwrap_or_default().into(), } - - if let Some(key) = src.fog_report_id() { - dst.set_fog_report_id(key.to_string()); - } - - dst } } @@ -74,11 +63,11 @@ mod tests { let account_key = AccountKey::random(&mut rng); let proto_credentials = external::AccountKey::from(&account_key); assert_eq!( - *proto_credentials.get_view_private_key(), + *proto_credentials.view_private_key.as_ref().unwrap(), external::RistrettoPrivate::from(account_key.view_private_key()) ); assert_eq!( - *proto_credentials.get_spend_private_key(), + *proto_credentials.spend_private_key.as_ref().unwrap(), external::RistrettoPrivate::from(account_key.spend_private_key()) ); assert_eq!(proto_credentials.fog_report_url, String::from("")); @@ -106,11 +95,11 @@ mod tests { let proto_credentials = external::AccountKey::from(&account_key); assert_eq!( - *proto_credentials.get_view_private_key(), + *proto_credentials.view_private_key.as_ref().unwrap(), external::RistrettoPrivate::from(account_key.view_private_key()) ); assert_eq!( - *proto_credentials.get_spend_private_key(), + *proto_credentials.spend_private_key.as_ref().unwrap(), external::RistrettoPrivate::from(account_key.spend_private_key()) ); assert_eq!( diff --git a/api/src/convert/amount.rs b/api/src/convert/amount.rs index 85cd4e2303..6655e16f79 100644 --- a/api/src/convert/amount.rs +++ b/api/src/convert/amount.rs @@ -2,12 +2,9 @@ //! Convert to/from external::Amount -use crate::{external, ConversionError}; -use mc_transaction_core::{ - Amount, CompressedCommitment, MaskedAmount, MaskedAmountV1, MaskedAmountV2, -}; +use crate::{external, external::CompressedRistretto, ConversionError}; +use mc_transaction_core::{Amount, MaskedAmount, MaskedAmountV1, MaskedAmountV2}; use mc_util_repr_bytes::ReprBytes; - // Note: // external::MaskedAmount is a proto message // external::TxOut_oneof_masked_amount is a proto oneof @@ -15,33 +12,37 @@ use mc_util_repr_bytes::ReprBytes; impl From<&MaskedAmountV1> for external::MaskedAmount { fn from(source: &MaskedAmountV1) -> Self { let commitment_bytes = source.commitment.to_bytes().to_vec(); - let mut amount = external::MaskedAmount::new(); - amount.mut_commitment().set_data(commitment_bytes); - amount.set_masked_value(source.masked_value); - amount.set_masked_token_id(source.masked_token_id.clone()); - amount + Self { + commitment: Some(CompressedRistretto { + data: commitment_bytes, + }), + masked_value: source.masked_value, + masked_token_id: source.masked_token_id.clone(), + } } } impl From<&MaskedAmountV2> for external::MaskedAmount { fn from(source: &MaskedAmountV2) -> Self { let commitment_bytes = source.commitment.to_bytes().to_vec(); - let mut amount = external::MaskedAmount::new(); - amount.mut_commitment().set_data(commitment_bytes); - amount.set_masked_value(source.masked_value); - amount.set_masked_token_id(source.masked_token_id.clone()); - amount + Self { + commitment: Some(CompressedRistretto { + data: commitment_bytes, + }), + masked_value: source.masked_value, + masked_token_id: source.masked_token_id.clone(), + } } } -impl From<&MaskedAmount> for external::TxOut_oneof_masked_amount { +impl From<&MaskedAmount> for external::tx_out::MaskedAmount { fn from(source: &MaskedAmount) -> Self { match source { MaskedAmount::V1(masked_amount) => { - external::TxOut_oneof_masked_amount::masked_amount_v1(masked_amount.into()) + external::tx_out::MaskedAmount::MaskedAmountV1(masked_amount.into()) } MaskedAmount::V2(masked_amount) => { - external::TxOut_oneof_masked_amount::masked_amount_v2(masked_amount.into()) + external::tx_out::MaskedAmount::MaskedAmountV2(masked_amount.into()) } } } @@ -51,13 +52,17 @@ impl TryFrom<&external::MaskedAmount> for MaskedAmountV1 { type Error = ConversionError; fn try_from(source: &external::MaskedAmount) -> Result { - let commitment = CompressedCommitment::try_from(source.get_commitment())?; - let masked_value = source.get_masked_value(); - let masked_token_id = source.get_masked_token_id(); + let commitment = source + .commitment + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let masked_value = source.masked_value; + let masked_token_id = source.masked_token_id.clone(); let amount = MaskedAmountV1 { commitment, masked_value, - masked_token_id: masked_token_id.to_vec(), + masked_token_id, }; Ok(amount) } @@ -67,9 +72,13 @@ impl TryFrom<&external::MaskedAmount> for MaskedAmountV2 { type Error = ConversionError; fn try_from(source: &external::MaskedAmount) -> Result { - let commitment = CompressedCommitment::try_from(source.get_commitment())?; - let masked_value = source.get_masked_value(); - let masked_token_id = source.get_masked_token_id().to_vec(); + let commitment = source + .commitment + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let masked_value = source.masked_value; + let masked_token_id = source.masked_token_id.clone(); let amount = MaskedAmountV2 { commitment, masked_value, @@ -79,43 +88,43 @@ impl TryFrom<&external::MaskedAmount> for MaskedAmountV2 { } } -impl TryFrom<&external::TxOut_oneof_masked_amount> for MaskedAmount { +impl TryFrom<&external::tx_out::MaskedAmount> for MaskedAmount { type Error = ConversionError; - fn try_from(source: &external::TxOut_oneof_masked_amount) -> Result { + fn try_from(source: &external::tx_out::MaskedAmount) -> Result { match source { - external::TxOut_oneof_masked_amount::masked_amount_v1(masked_amount) => { + external::tx_out::MaskedAmount::MaskedAmountV1(masked_amount) => { Ok(MaskedAmount::V1(masked_amount.try_into()?)) } - external::TxOut_oneof_masked_amount::masked_amount_v2(masked_amount) => { + external::tx_out::MaskedAmount::MaskedAmountV2(masked_amount) => { Ok(MaskedAmount::V2(masked_amount.try_into()?)) } } } } -impl From<&MaskedAmount> for external::Receipt_oneof_masked_amount { +impl From<&MaskedAmount> for external::receipt::MaskedAmount { fn from(source: &MaskedAmount) -> Self { match source { MaskedAmount::V1(masked_amount) => { - external::Receipt_oneof_masked_amount::masked_amount_v1(masked_amount.into()) + external::receipt::MaskedAmount::MaskedAmountV1(masked_amount.into()) } MaskedAmount::V2(masked_amount) => { - external::Receipt_oneof_masked_amount::masked_amount_v2(masked_amount.into()) + external::receipt::MaskedAmount::MaskedAmountV2(masked_amount.into()) } } } } -impl TryFrom<&external::Receipt_oneof_masked_amount> for MaskedAmount { +impl TryFrom<&external::receipt::MaskedAmount> for MaskedAmount { type Error = ConversionError; - fn try_from(source: &external::Receipt_oneof_masked_amount) -> Result { + fn try_from(source: &external::receipt::MaskedAmount) -> Result { match source { - external::Receipt_oneof_masked_amount::masked_amount_v1(masked_amount) => { + external::receipt::MaskedAmount::MaskedAmountV1(masked_amount) => { Ok(MaskedAmount::V1(masked_amount.try_into()?)) } - external::Receipt_oneof_masked_amount::masked_amount_v2(masked_amount) => { + external::receipt::MaskedAmount::MaskedAmountV2(masked_amount) => { Ok(MaskedAmount::V2(masked_amount.try_into()?)) } } @@ -124,16 +133,16 @@ impl TryFrom<&external::Receipt_oneof_masked_amount> for MaskedAmount { impl From<&Amount> for external::Amount { fn from(source: &Amount) -> Self { - let mut amount = external::Amount::new(); - amount.set_value(source.value); - amount.set_token_id(*source.token_id); - amount + Self { + value: source.value, + token_id: *source.token_id, + } } } impl From<&external::Amount> for Amount { fn from(source: &external::Amount) -> Self { - Amount::new(source.get_value(), source.get_token_id().into()) + Amount::new(source.value, source.token_id.into()) } } diff --git a/api/src/convert/archive_block.rs b/api/src/convert/archive_block.rs index f4d4742996..06103c4662 100644 --- a/api/src/convert/archive_block.rs +++ b/api/src/convert/archive_block.rs @@ -3,7 +3,7 @@ //! Convert between BlockData and ArchiveBlock. use crate::{ - blockchain::{ArchiveBlock, ArchiveBlocks}, + blockchain::{archive_block, ArchiveBlock, ArchiveBlockV1, ArchiveBlocks}, ConversionError, }; use mc_blockchain_types::{BlockContents, BlockData, BlockMetadata, BlockSignature}; @@ -11,20 +11,15 @@ use mc_blockchain_types::{BlockContents, BlockData, BlockMetadata, BlockSignatur /// Convert BlockData --> ArchiveBlock. impl From<&BlockData> for ArchiveBlock { fn from(src: &BlockData) -> Self { - let mut archive_block = ArchiveBlock::new(); - let archive_block_v1 = archive_block.mut_v1(); - archive_block_v1.set_block(src.block().into()); - archive_block_v1.set_block_contents(src.contents().into()); - - if let Some(signature) = src.signature() { - archive_block_v1.set_signature(signature.into()); - } - - if let Some(metadata) = src.metadata() { - archive_block_v1.set_metadata(metadata.into()); + Self { + block: archive_block::Block::V1(ArchiveBlockV1 { + block: Some(src.block().into()), + block_contents: Some(src.contents().into()), + signature: src.signature().map(|s| s.into()), + metadata: src.metadata().map(|m| m.into()), + }) + .into(), } - - archive_block } } @@ -33,13 +28,25 @@ impl TryFrom<&ArchiveBlock> for BlockData { type Error = ConversionError; fn try_from(src: &ArchiveBlock) -> Result { - if !src.has_v1() { + if src.block.is_none() { return Err(ConversionError::ObjectMissing); } - let archive_block_v1 = src.get_v1(); + let archive_block_v1 = match src.block.as_ref() { + Some(archive_block::Block::V1(archive_block_v1)) => archive_block_v1, + _ => return Err(ConversionError::ObjectMissing), + }; - let block = archive_block_v1.get_block().try_into()?; - let block_contents = BlockContents::try_from(archive_block_v1.get_block_contents())?; + let block = archive_block_v1 + .block + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let block_contents = BlockContents::try_from( + archive_block_v1 + .block_contents + .as_ref() + .unwrap_or(&Default::default()), + )?; let signature = archive_block_v1 .signature @@ -67,9 +74,9 @@ impl TryFrom<&ArchiveBlock> for BlockData { /// Convert &[BlockData] -> ArchiveBlocks impl From<&[BlockData]> for ArchiveBlocks { fn from(src: &[BlockData]) -> Self { - let mut archive_blocks = ArchiveBlocks::new(); - archive_blocks.set_blocks(src.iter().map(ArchiveBlock::from).collect()); - archive_blocks + Self { + blocks: src.iter().map(|block| block.into()).collect(), + } } } @@ -79,7 +86,7 @@ impl TryFrom<&ArchiveBlocks> for Vec { fn try_from(src: &ArchiveBlocks) -> Result { let blocks_data = src - .get_blocks() + .blocks .iter() .map(BlockData::try_from) .collect::, ConversionError>>()?; @@ -129,21 +136,22 @@ mod tests { // BlockData -> ArchiveBlock let archive_block = ArchiveBlock::from(&block_data); + let archive_block::Block::V1(archive_block_v1) = archive_block.block.as_ref().unwrap(); assert_eq!( block_data.block(), - &Block::try_from(archive_block.get_v1().get_block()).unwrap(), + &Block::try_from(archive_block_v1.block.as_ref().unwrap()).unwrap(), ); assert_eq!( block_data.contents(), - &BlockContents::try_from(archive_block.get_v1().get_block_contents()).unwrap() + &BlockContents::try_from(archive_block_v1.block_contents.as_ref().unwrap()).unwrap() ); assert_eq!( block_data.signature().cloned().unwrap(), - BlockSignature::try_from(archive_block.get_v1().get_signature()).unwrap() + BlockSignature::try_from(archive_block_v1.signature.as_ref().unwrap()).unwrap() ); assert_eq!( block_data.metadata().cloned().unwrap(), - BlockMetadata::try_from(archive_block.get_v1().get_metadata()).unwrap() + BlockMetadata::try_from(archive_block_v1.metadata.as_ref().unwrap()).unwrap() ); // ArchiveBlock -> BlockData @@ -160,11 +168,16 @@ mod tests { // ArchiveBlock with invalid signature cannot be converted back to BlockData { let mut archive_block = ArchiveBlock::from(&block_data); - archive_block - .mut_v1() - .mut_signature() - .mut_signature() - .mut_data()[0] += 1; + let archive_block::Block::V1(ref mut archive_block_v1) = + archive_block.block.as_mut().unwrap(); + archive_block_v1 + .signature + .as_mut() + .unwrap() + .signature + .as_mut() + .unwrap() + .data[0] += 1; assert_eq!( BlockData::try_from(&archive_block), Err(ConversionError::InvalidSignature) @@ -174,11 +187,18 @@ mod tests { // ArchiveBlock with invalid metadata cannot be converted back to BlockData { let mut archive_block = ArchiveBlock::from(&block_data); - archive_block - .mut_v1() - .mut_metadata() - .mut_contents() - .mut_quorum_set() + let archive_block::Block::V1(ref mut archive_block_v1) = + archive_block.block.as_mut().unwrap(); + archive_block_v1 + .metadata + .as_mut() + .unwrap() + .contents + .as_mut() + .unwrap() + .quorum_set + .as_mut() + .unwrap() .threshold += 1; assert_eq!( BlockData::try_from(&archive_block), @@ -189,10 +209,9 @@ mod tests { // ArchiveBlock with invalid contents cannot be converted back to BlockData { let mut archive_block = ArchiveBlock::from(&block_data); - archive_block - .mut_v1() - .mut_block_contents() - .clear_key_images(); + let archive_block::Block::V1(ref mut archive_block_v1) = + archive_block.block.as_mut().unwrap(); + archive_block_v1.block_contents.as_mut().unwrap().key_images = vec![]; assert_eq!( BlockData::try_from(&archive_block), Err(ConversionError::InvalidContents) @@ -208,23 +227,25 @@ mod tests { // Vec -> ArchiveBlocks let archive_blocks = ArchiveBlocks::from(blocks_data.as_slice()); for (block_data, archive_block) in - zip_exact(blocks_data.iter(), archive_blocks.get_blocks().iter()).unwrap() + zip_exact(blocks_data.iter(), archive_blocks.blocks.iter()).unwrap() { + let archive_block::Block::V1(archive_block_v1) = archive_block.block.as_ref().unwrap(); assert_eq!( block_data.block(), - &Block::try_from(archive_block.get_v1().get_block()).unwrap(), + &Block::try_from(archive_block_v1.block.as_ref().unwrap()).unwrap(), ); assert_eq!( block_data.contents(), - &BlockContents::try_from(archive_block.get_v1().get_block_contents()).unwrap() + &BlockContents::try_from(archive_block_v1.block_contents.as_ref().unwrap()) + .unwrap() ); assert_eq!( block_data.signature().cloned().unwrap(), - BlockSignature::try_from(archive_block.get_v1().get_signature()).unwrap() + BlockSignature::try_from(archive_block_v1.signature.as_ref().unwrap()).unwrap() ); assert_eq!( block_data.metadata().cloned().unwrap(), - BlockMetadata::try_from(archive_block.get_v1().get_metadata()).unwrap() + BlockMetadata::try_from(archive_block_v1.metadata.as_ref().unwrap()).unwrap() ); } @@ -239,7 +260,7 @@ mod tests { fn test_try_from_blockchain_archive_blocks_rejects_invalid() { let blocks_data = generate_test_blocks_data(10); let mut archive_blocks = ArchiveBlocks::from(blocks_data.as_slice()); - archive_blocks.mut_blocks().remove(5); + archive_blocks.blocks.remove(5); assert_eq!( Vec::::try_from(&archive_blocks), diff --git a/api/src/convert/block.rs b/api/src/convert/block.rs index 1194ee5f98..4fbbf3ffb5 100644 --- a/api/src/convert/block.rs +++ b/api/src/convert/block.rs @@ -9,15 +9,15 @@ use mc_transaction_core::tx::TxOutMembershipElement; /// Convert Block --> blockchain::Block. impl From<&Block> for blockchain::Block { fn from(other: &Block) -> Self { - let mut block = blockchain::Block::new(); - block.set_id(blockchain::BlockID::from(&other.id)); - block.set_version(other.version); - block.set_parent_id(blockchain::BlockID::from(&other.parent_id)); - block.set_index(other.index); - block.set_cumulative_txo_count(other.cumulative_txo_count); - block.set_root_element((&other.root_element).into()); - block.set_contents_hash(blockchain::BlockContentsHash::from(&other.contents_hash)); - block + Self { + id: Some((&other.id).into()), + version: other.version, + parent_id: Some((&other.parent_id).into()), + index: other.index, + cumulative_txo_count: other.cumulative_txo_count, + root_element: Some((&other.root_element).into()), + contents_hash: Some((&other.contents_hash).into()), + } } } @@ -26,10 +26,14 @@ impl TryFrom<&blockchain::Block> for Block { type Error = ConversionError; fn try_from(value: &blockchain::Block) -> Result { - let block_id = BlockID::try_from(value.get_id())?; - let parent_id = BlockID::try_from(value.get_parent_id())?; - let root_element = TxOutMembershipElement::try_from(value.get_root_element())?; - let contents_hash = BlockContentsHash::try_from(value.get_contents_hash())?; + let block_id = BlockID::try_from(value.id.as_ref().unwrap_or(&Default::default()))?; + let parent_id = BlockID::try_from(value.parent_id.as_ref().unwrap_or(&Default::default()))?; + let root_element = TxOutMembershipElement::try_from( + value.root_element.as_ref().unwrap_or(&Default::default()), + )?; + let contents_hash = BlockContentsHash::try_from( + value.contents_hash.as_ref().unwrap_or(&Default::default()), + )?; let block = Block { id: block_id, @@ -49,7 +53,7 @@ mod tests { use super::*; use crate::external; use mc_transaction_core::{membership_proofs::Range, tx::TxOutMembershipHash}; - use protobuf::Message; + use prost::Message; #[test] // Block --> blockchain::Block @@ -68,41 +72,76 @@ mod tests { }; let block = blockchain::Block::from(&source_block); - assert_eq!(block.get_id().get_data(), [2u8; 32]); - assert_eq!(block.get_version(), 1); - assert_eq!(block.get_parent_id().get_data(), [1u8; 32]); - assert_eq!(block.get_index(), 99); - assert_eq!(block.get_cumulative_txo_count(), 400); - assert_eq!(block.get_root_element().get_range().get_from(), 10); - assert_eq!(block.get_root_element().get_range().get_to(), 20); - assert_eq!(block.get_root_element().get_hash().get_data(), &[12u8; 32]); - assert_eq!(block.get_contents_hash().get_data(), [66u8; 32]); + assert_eq!(block.id.unwrap().data, [2u8; 32]); + assert_eq!(block.version, 1); + assert_eq!(block.parent_id.unwrap().data, [1u8; 32]); + assert_eq!(block.index, 99); + assert_eq!(block.cumulative_txo_count, 400); + assert_eq!( + block + .root_element + .as_ref() + .unwrap() + .range + .as_ref() + .unwrap() + .from, + 10 + ); + assert_eq!( + block + .root_element + .as_ref() + .unwrap() + .range + .as_ref() + .unwrap() + .to, + 20 + ); + assert_eq!( + block + .root_element + .as_ref() + .unwrap() + .hash + .as_ref() + .unwrap() + .data, + &[12u8; 32] + ); + assert_eq!(block.contents_hash.unwrap().data, [66u8; 32]); } #[test] // blockchain::Block -> Block fn test_block_try_from() { - let mut root_element = external::TxOutMembershipElement::new(); - root_element.mut_range().set_from(10); - root_element.mut_range().set_to(20); - root_element.mut_hash().set_data(vec![13u8; 32]); - - let mut block_id = blockchain::BlockID::new(); - block_id.set_data(vec![10u8; 32]); - - let mut parent_block_id = blockchain::BlockID::new(); - parent_block_id.set_data(vec![9u8; 32]); + let root_element = external::TxOutMembershipElement { + range: Some(external::Range { from: 10, to: 20 }), + hash: Some(external::TxOutMembershipHash { + data: vec![13u8; 32], + }), + }; - let mut contents_hash = blockchain::BlockContentsHash::new(); - contents_hash.set_data(vec![66u8; 32]); + let block_id = blockchain::BlockId { + data: vec![10u8; 32], + }; + let parent_block_id = blockchain::BlockId { + data: vec![9u8; 32], + }; + let contents_hash = blockchain::BlockContentsHash { + data: vec![66u8; 32], + }; - let mut source_block = blockchain::Block::new(); - source_block.set_id(block_id); - source_block.set_version(1u32); - source_block.set_parent_id(parent_block_id); - source_block.set_index(2); - source_block.set_root_element(root_element); - source_block.set_contents_hash(contents_hash); + let source_block = blockchain::Block { + id: Some(block_id), + version: 1, + parent_id: Some(parent_block_id), + index: 2, + root_element: Some(root_element), + contents_hash: Some(contents_hash), + cumulative_txo_count: 0, + }; let block = Block::try_from(&source_block).unwrap(); assert_eq!(block.id.as_ref(), [10u8; 32]); @@ -136,7 +175,7 @@ mod tests { // Encode using `protobuf`, decode using `prost`. { let blockchain_block = blockchain::Block::from(&source_block); - let blockchain_block_bytes = blockchain_block.write_to_bytes().unwrap(); + let blockchain_block_bytes = blockchain_block.encode_to_vec(); let block_from_prost: Block = mc_util_serial::decode(&blockchain_block_bytes).expect("failed decoding"); @@ -147,7 +186,7 @@ mod tests { { let prost_block_bytes = mc_util_serial::encode(&source_block); let blockchain_block = - blockchain::Block::parse_from_bytes(&prost_block_bytes).expect("failed decoding"); + blockchain::Block::decode(prost_block_bytes.as_slice()).expect("failed decoding"); assert_eq!(blockchain_block, blockchain::Block::from(&source_block)); } diff --git a/api/src/convert/block_contents.rs b/api/src/convert/block_contents.rs index 3a94ef0014..d5ede13d40 100644 --- a/api/src/convert/block_contents.rs +++ b/api/src/convert/block_contents.rs @@ -12,8 +12,6 @@ use mc_transaction_core::{ impl From<&BlockContents> for blockchain::BlockContents { fn from(source: &BlockContents) -> Self { - let mut block_contents = blockchain::BlockContents::new(); - let key_images = source .key_images .iter() @@ -29,12 +27,12 @@ impl From<&BlockContents> for blockchain::BlockContents { .collect(); let mint_txs = source.mint_txs.iter().map(external::MintTx::from).collect(); - - block_contents.set_key_images(key_images); - block_contents.set_outputs(outputs); - block_contents.set_validated_mint_config_txs(validated_mint_config_txs); - block_contents.set_mint_txs(mint_txs); - block_contents + Self { + key_images, + outputs, + validated_mint_config_txs, + mint_txs, + } } } @@ -43,25 +41,25 @@ impl TryFrom<&blockchain::BlockContents> for BlockContents { fn try_from(source: &blockchain::BlockContents) -> Result { let key_images = source - .get_key_images() + .key_images .iter() .map(KeyImage::try_from) .collect::>()?; let outputs = source - .get_outputs() + .outputs .iter() .map(TxOut::try_from) .collect::>()?; let validated_mint_config_txs = source - .get_validated_mint_config_txs() + .validated_mint_config_txs .iter() .map(ValidatedMintConfigTx::try_from) .collect::>()?; let mint_txs = source - .get_mint_txs() + .mint_txs .iter() .map(MintTx::try_from) .collect::>()?; diff --git a/api/src/convert/block_contents_hash.rs b/api/src/convert/block_contents_hash.rs index c18ae9e763..5a4f32ee55 100644 --- a/api/src/convert/block_contents_hash.rs +++ b/api/src/convert/block_contents_hash.rs @@ -8,9 +8,9 @@ use mc_blockchain_types::BlockContentsHash; /// Convert BlockContentsHash --> blockchain::BlockContentsHash. impl From<&BlockContentsHash> for blockchain::BlockContentsHash { fn from(src: &BlockContentsHash) -> Self { - let mut dst = blockchain::BlockContentsHash::new(); - dst.set_data(src.as_ref().to_vec()); - dst + Self { + data: src.as_ref().to_vec(), + } } } @@ -19,7 +19,8 @@ impl TryFrom<&blockchain::BlockContentsHash> for BlockContentsHash { type Error = ConversionError; fn try_from(src: &blockchain::BlockContentsHash) -> Result { - BlockContentsHash::try_from(src.get_data()).map_err(|_| ConversionError::ArrayCastError) + BlockContentsHash::try_from(src.data.as_slice()) + .map_err(|_| ConversionError::ArrayCastError) } } @@ -32,8 +33,9 @@ mod tests { // error. fn test_from_blockchain_block_contents_hash_error() { // Cannot convert 37 bytes to a BlockContentsHash. - let mut bad_block_contents_hash = blockchain::BlockContentsHash::new(); - bad_block_contents_hash.set_data(vec![1u8; 37]); + let bad_block_contents_hash = blockchain::BlockContentsHash { + data: vec![1u8; 37], + }; let converted = BlockContentsHash::try_from(&bad_block_contents_hash); assert!(converted.is_err()); @@ -43,8 +45,9 @@ mod tests { // Unmarshalling too few bytes into a BlockContentsHash should produce an error. fn test_from_blockchain_block_contents_hash_error_two() { // Cannot convert 11 bytes to a BlockContentsHash. - let mut bad_block_contents_hash = blockchain::BlockContentsHash::new(); - bad_block_contents_hash.set_data(vec![1u8; 11]); + let bad_block_contents_hash = blockchain::BlockContentsHash { + data: vec![1u8; 11], + }; let converted = BlockContentsHash::try_from(&bad_block_contents_hash); assert!(converted.is_err()); diff --git a/api/src/convert/block_id.rs b/api/src/convert/block_id.rs index aa5320a786..19f616e569 100644 --- a/api/src/convert/block_id.rs +++ b/api/src/convert/block_id.rs @@ -1,25 +1,25 @@ // Copyright (c) 2018-2022 The MobileCoin Foundation -//! Convert to/from blockchain::BlockID +//! Convert to/from blockchain::BlockId use crate::{blockchain, ConversionError}; use mc_blockchain_types::BlockID; -/// Convert BlockID --> blockchain::BlockID. -impl From<&BlockID> for blockchain::BlockID { +/// Convert BlockID --> blockchain::BlockId. +impl From<&BlockID> for blockchain::BlockId { fn from(src: &BlockID) -> Self { - let mut dst = blockchain::BlockID::new(); - dst.set_data(src.as_ref().to_vec()); - dst + Self { + data: src.as_ref().to_vec(), + } } } -/// Convert blockchain::BlockID --> BlockID. -impl TryFrom<&blockchain::BlockID> for BlockID { +/// Convert blockchain::BlockId --> BlockID. +impl TryFrom<&blockchain::BlockId> for BlockID { type Error = ConversionError; - fn try_from(src: &blockchain::BlockID) -> Result { - BlockID::try_from(src.get_data()).map_err(|_| ConversionError::ArrayCastError) + fn try_from(src: &blockchain::BlockId) -> Result { + BlockID::try_from(src.data.as_slice()).map_err(|_| ConversionError::ArrayCastError) } } @@ -31,8 +31,9 @@ mod tests { // Unmarshalling too many bytes into a BlockID should produce an error. fn test_from_blockchain_block_id_error() { // Cannot convert 37 bytes to a BlockID. - let mut bad_block_id = blockchain::BlockID::new(); - bad_block_id.set_data(vec![1u8; 37]); + let bad_block_id = blockchain::BlockId { + data: vec![1u8; 37], + }; let converted = BlockID::try_from(&bad_block_id); assert!(converted.is_err()); @@ -42,8 +43,9 @@ mod tests { // Unmarshalling too few bytes into a BlockID should produce an error. fn test_from_blockchain_block_id_error_two() { // Cannot convert 11 bytes to a BlockID. - let mut bad_block_id = blockchain::BlockID::new(); - bad_block_id.set_data(vec![1u8; 11]); + let bad_block_id = blockchain::BlockId { + data: vec![1u8; 11], + }; let converted = BlockID::try_from(&bad_block_id); assert!(converted.is_err()); diff --git a/api/src/convert/block_metadata.rs b/api/src/convert/block_metadata.rs index d16559eb99..f3972d5254 100644 --- a/api/src/convert/block_metadata.rs +++ b/api/src/convert/block_metadata.rs @@ -2,27 +2,27 @@ //! Convert to/from blockchain::BlockMetadataContents. -use crate::{ - blockchain::{self, BlockMetadataContents_oneof_attestation_evidence}, - ConversionError, -}; +use crate::{blockchain, blockchain::block_metadata_contents, ConversionError}; use mc_blockchain_types::{AttestationEvidence, BlockMetadata, BlockMetadataContents}; use mc_common::ResponderId; use std::str::FromStr; impl From<&BlockMetadataContents> for blockchain::BlockMetadataContents { fn from(src: &BlockMetadataContents) -> Self { - let mut proto = Self::new(); - proto.set_block_id(src.block_id().into()); - proto.set_quorum_set(src.quorum_set().into()); - match src.attestation_evidence() { - AttestationEvidence::DcapEvidence(evidence) => proto.set_dcap_evidence(evidence.into()), + let attesetation_evidence = match src.attestation_evidence() { + AttestationEvidence::DcapEvidence(evidence) => { + block_metadata_contents::AttestationEvidence::DcapEvidence(evidence.into()) + } AttestationEvidence::VerificationReport(report) => { - proto.set_verification_report(report.into()) + block_metadata_contents::AttestationEvidence::VerificationReport(report.into()) } + }; + Self { + block_id: Some(src.block_id().into()), + quorum_set: Some(src.quorum_set().into()), + responder_id: src.responder_id().to_string(), + attestation_evidence: Some(attesetation_evidence), } - proto.set_responder_id(src.responder_id().to_string()); - proto } } @@ -30,14 +30,22 @@ impl TryFrom<&blockchain::BlockMetadataContents> for BlockMetadataContents { type Error = ConversionError; fn try_from(src: &blockchain::BlockMetadataContents) -> Result { - let block_id = src.get_block_id().try_into()?; - let quorum_set = src.get_quorum_set().try_into()?; + let block_id = src + .block_id + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let quorum_set = src + .quorum_set + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; let attestation_evidence = match &src.attestation_evidence { - Some(BlockMetadataContents_oneof_attestation_evidence::dcap_evidence(evidence)) => { + Some(block_metadata_contents::AttestationEvidence::DcapEvidence(evidence)) => { let evidence = evidence.into(); AttestationEvidence::DcapEvidence(evidence) } - Some(BlockMetadataContents_oneof_attestation_evidence::verification_report(report)) => { + Some(block_metadata_contents::AttestationEvidence::VerificationReport(report)) => { let report = report.into(); AttestationEvidence::VerificationReport(report) } @@ -60,11 +68,11 @@ impl TryFrom<&blockchain::BlockMetadataContents> for BlockMetadataContents { impl From<&BlockMetadata> for blockchain::BlockMetadata { fn from(src: &BlockMetadata) -> Self { - let mut proto = Self::new(); - proto.set_contents(src.contents().into()); - proto.set_node_key(src.node_key().into()); - proto.set_signature(src.signature().into()); - proto + Self { + contents: Some(src.contents().into()), + node_key: Some(src.node_key().into()), + signature: Some(src.signature().into()), + } } } @@ -72,9 +80,21 @@ impl TryFrom<&blockchain::BlockMetadata> for BlockMetadata { type Error = ConversionError; fn try_from(src: &blockchain::BlockMetadata) -> Result { - let contents = src.get_contents().try_into()?; - let node_key = src.get_node_key().try_into()?; - let signature = src.get_signature().try_into()?; + let contents = src + .contents + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let node_key = src + .node_key + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let signature = src + .signature + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; let metadata = BlockMetadata::new(contents, node_key, signature); metadata.verify()?; Ok(metadata) diff --git a/api/src/convert/block_signature.rs b/api/src/convert/block_signature.rs index 1cf8027927..1062983da5 100644 --- a/api/src/convert/block_signature.rs +++ b/api/src/convert/block_signature.rs @@ -2,18 +2,17 @@ //! Convert to/from blockchain::BlockSignature -use crate::{blockchain, external, ConversionError}; +use crate::{blockchain, ConversionError}; use mc_blockchain_types::BlockSignature; -use mc_crypto_keys::{Ed25519Public, Ed25519Signature}; /// Convert BlockSignature --> blockchain::BlockSignature. impl From<&BlockSignature> for blockchain::BlockSignature { fn from(src: &BlockSignature) -> Self { - let mut dst = blockchain::BlockSignature::new(); - dst.set_signature(external::Ed25519Signature::from(src.signature())); - dst.set_signer(external::Ed25519Public::from(src.signer())); - dst.set_signed_at(src.signed_at()); - dst + Self { + signature: Some(src.signature().into()), + signer: Some(src.signer().into()), + signed_at: src.signed_at(), + } } } @@ -22,9 +21,17 @@ impl TryFrom<&blockchain::BlockSignature> for BlockSignature { type Error = ConversionError; fn try_from(source: &blockchain::BlockSignature) -> Result { - let signature = Ed25519Signature::try_from(source.get_signature())?; - let signer = Ed25519Public::try_from(source.get_signer())?; - let signed_at = source.get_signed_at(); + let signature = source + .signature + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let signer = source + .signer + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let signed_at = source.signed_at; Ok(BlockSignature::new(signature, signer, signed_at)) } } @@ -32,10 +39,11 @@ impl TryFrom<&blockchain::BlockSignature> for BlockSignature { #[cfg(test)] mod tests { use super::*; - use mc_crypto_keys::Ed25519Private; + use crate::external; + use mc_crypto_keys::{Ed25519Private, Ed25519Signature}; use mc_util_from_random::FromRandom; use mc_util_repr_bytes::ReprBytes; - use protobuf::Message; + use prost::Message; use rand::{rngs::StdRng, SeedableRng}; #[test] @@ -51,15 +59,15 @@ mod tests { let block_signature = blockchain::BlockSignature::from(&source_block_signature); assert_eq!( - block_signature.get_signature().get_data(), + block_signature.signature.unwrap().data, source_block_signature.signature().as_ref() ); assert_eq!( - block_signature.get_signer().get_data(), + block_signature.signer.unwrap().data, source_block_signature.signer().to_bytes().as_slice(), ); assert_eq!( - block_signature.get_signed_at(), + block_signature.signed_at, source_block_signature.signed_at(), ); } @@ -75,17 +83,15 @@ mod tests { 31337, ); - let mut source_block_signature = blockchain::BlockSignature::new(); - - let mut signature = external::Ed25519Signature::new(); - signature.set_data(expected_block_signature.signature().to_bytes().to_vec()); - source_block_signature.set_signature(signature); - - let mut signer = external::Ed25519Public::new(); - signer.set_data(expected_block_signature.signer().to_bytes().to_vec()); - source_block_signature.set_signer(signer); - - source_block_signature.set_signed_at(31337); + let source_block_signature = blockchain::BlockSignature { + signature: Some(external::Ed25519Signature { + data: expected_block_signature.signature().to_bytes().to_vec(), + }), + signer: Some(external::Ed25519Public { + data: expected_block_signature.signer().to_bytes().to_vec(), + }), + signed_at: 31337, + }; let block_signature = BlockSignature::try_from(&source_block_signature).unwrap(); assert_eq!(block_signature, expected_block_signature); @@ -108,8 +114,7 @@ mod tests { { let blockchain_block_signature = blockchain::BlockSignature::from(&source_block_signature); - let blockchain_block_signature_bytes = - blockchain_block_signature.write_to_bytes().unwrap(); + let blockchain_block_signature_bytes = blockchain_block_signature.encode_to_vec(); let block_signature_from_prost: BlockSignature = mc_util_serial::decode(&blockchain_block_signature_bytes).expect("failed decoding"); @@ -120,7 +125,7 @@ mod tests { { let prost_block_signature_bytes = mc_util_serial::encode(&source_block_signature); let blockchain_block_signature = - blockchain::BlockSignature::parse_from_bytes(&prost_block_signature_bytes) + blockchain::BlockSignature::decode(prost_block_signature_bytes.as_slice()) .expect("failed decoding"); assert_eq!( diff --git a/api/src/convert/collateral.rs b/api/src/convert/collateral.rs index c4d8be86a8..f753e62e66 100644 --- a/api/src/convert/collateral.rs +++ b/api/src/convert/collateral.rs @@ -6,16 +6,13 @@ use crate::{external, ConversionError}; use mc_attest_verifier_types::prost; use mc_sgx_dcap_types::Collateral; use mc_util_serial::Message; -use protobuf::Message as ProtoMessage; impl TryFrom<&Collateral> for external::Collateral { type Error = ConversionError; fn try_from(src: &Collateral) -> Result { let prost = prost::Collateral::try_from(src)?; let bytes = prost.encode_to_vec(); - let mut proto = Self::default(); - proto - .merge_from_bytes(&bytes) + let proto = Self::decode(bytes.as_slice()) .expect("failure to merge means prost and protobuf are out of sync"); Ok(proto) } @@ -32,12 +29,12 @@ impl TryFrom<&external::Collateral> for Collateral { impl From<&external::Collateral> for prost::Collateral { fn from(src: &external::Collateral) -> Self { Self { - pck_crl_issuer_chain: src.pck_crl_issuer_chain.clone().into_vec(), + pck_crl_issuer_chain: src.pck_crl_issuer_chain.clone(), root_ca_crl: src.root_ca_crl.clone(), pck_crl: src.pck_crl.clone(), - tcb_info_issuer_chain: src.tcb_info_issuer_chain.clone().into_vec(), + tcb_info_issuer_chain: src.tcb_info_issuer_chain.clone(), tcb_info: src.tcb_info.clone(), - qe_identity_issuer_chain: src.qe_identity_issuer_chain.clone().into_vec(), + qe_identity_issuer_chain: src.qe_identity_issuer_chain.clone(), qe_identity: src.qe_identity.clone(), } } diff --git a/api/src/convert/compressed_ristretto.rs b/api/src/convert/compressed_ristretto.rs index 3859ee0e0a..32bf257b96 100644 --- a/api/src/convert/compressed_ristretto.rs +++ b/api/src/convert/compressed_ristretto.rs @@ -9,9 +9,9 @@ use mc_transaction_core::CompressedCommitment; impl From<&CompressedCommitment> for external::CompressedRistretto { fn from(source: &CompressedCommitment) -> Self { - let mut compressed_ristretto = external::CompressedRistretto::new(); - compressed_ristretto.set_data(source.point.as_bytes().to_vec()); - compressed_ristretto + Self { + data: source.point.as_bytes().to_vec(), + } } } @@ -19,7 +19,7 @@ impl TryFrom<&external::CompressedRistretto> for CompressedCommitment { type Error = ConversionError; fn try_from(source: &external::CompressedRistretto) -> Result { - let bytes: &[u8] = source.get_data(); + let bytes: &[u8] = source.data.as_ref(); let point = CompressedRistretto::from_slice(bytes).map_err(|_e| ConversionError::ArrayCastError)?; Ok(CompressedCommitment { point }) @@ -31,7 +31,7 @@ impl TryFrom<&external::CompressedRistretto> for RistrettoPublic { type Error = ConversionError; fn try_from(source: &external::CompressedRistretto) -> Result { - let bytes: &[u8] = source.get_data(); + let bytes: &[u8] = source.data.as_ref(); RistrettoPublic::try_from(bytes).map_err(|_| ConversionError::ArrayCastError) } } @@ -39,18 +39,18 @@ impl TryFrom<&external::CompressedRistretto> for RistrettoPublic { /// Convert CompressedRistrettoPublic --> external::CompressedRistretto impl From<&CompressedRistrettoPublic> for external::CompressedRistretto { fn from(other: &CompressedRistrettoPublic) -> Self { - let mut key = external::CompressedRistretto::new(); - key.set_data(other.as_bytes().to_vec()); - key + Self { + data: other.as_bytes().to_vec(), + } } } /// Convert &RistrettoPublic --> external::CompressedRistretto impl From<&RistrettoPublic> for external::CompressedRistretto { fn from(other: &RistrettoPublic) -> Self { - let mut key = external::CompressedRistretto::new(); - key.set_data(other.to_bytes().to_vec()); - key + Self { + data: other.to_bytes().to_vec(), + } } } @@ -59,7 +59,7 @@ impl TryFrom<&external::CompressedRistretto> for CompressedRistrettoPublic { type Error = ConversionError; fn try_from(source: &external::CompressedRistretto) -> Result { - let bytes: &[u8] = source.get_data(); + let bytes: &[u8] = source.data.as_ref(); CompressedRistrettoPublic::try_from(bytes).map_err(|_| ConversionError::ArrayCastError) } } diff --git a/api/src/convert/curve_scalar.rs b/api/src/convert/curve_scalar.rs index 753681cc17..56bf107006 100644 --- a/api/src/convert/curve_scalar.rs +++ b/api/src/convert/curve_scalar.rs @@ -10,19 +10,19 @@ use mc_transaction_core::ring_signature::CurveScalar; /// Convert RistrettoPrivate --> external::CurveScalar. impl From<&RistrettoPrivate> for external::CurveScalar { fn from(other: &RistrettoPrivate) -> Self { - let mut scalar = external::CurveScalar::new(); let privbytes: &[u8] = other.as_ref(); - scalar.set_data(Vec::from(privbytes)); - scalar + Self { + data: privbytes.to_vec(), + } } } /// Convert CurveScalar --> external::CurveScalar. impl From<&CurveScalar> for external::CurveScalar { fn from(other: &CurveScalar) -> Self { - let mut scalar = external::CurveScalar::new(); - scalar.set_data(other.as_bytes().to_vec()); - scalar + Self { + data: other.as_bytes().to_vec(), + } } } @@ -31,16 +31,16 @@ impl TryFrom<&external::CurveScalar> for CurveScalar { type Error = ConversionError; fn try_from(source: &external::CurveScalar) -> Result { - let bytes: &[u8] = source.get_data(); + let bytes: &[u8] = source.data.as_ref(); CurveScalar::try_from(bytes).map_err(|_| ConversionError::ArrayCastError) } } impl From<&Scalar> for external::CurveScalar { fn from(source: &Scalar) -> Self { - let mut scalar = external::CurveScalar::new(); - scalar.set_data(source.to_bytes().to_vec()); - scalar + Self { + data: source.to_bytes().to_vec(), + } } } @@ -49,7 +49,8 @@ impl TryFrom<&external::CurveScalar> for Scalar { fn try_from(source: &external::CurveScalar) -> Result { let bytes: [u8; 32] = source - .get_data() + .data + .as_slice() .try_into() .map_err(|_| ConversionError::ArrayCastError)?; let maybe_scalar: Option = Scalar::from_canonical_bytes(bytes).into(); diff --git a/api/src/convert/dcap_evidence.rs b/api/src/convert/dcap_evidence.rs index 73857d74d1..0b1a14c153 100644 --- a/api/src/convert/dcap_evidence.rs +++ b/api/src/convert/dcap_evidence.rs @@ -5,7 +5,6 @@ use crate::{external, ConversionError}; use mc_attest_verifier_types::{prost, DcapEvidence}; use mc_util_serial::Message; -use protobuf::Message as ProtoMessage; impl TryFrom<&DcapEvidence> for external::DcapEvidence { type Error = ConversionError; @@ -26,11 +25,8 @@ impl TryFrom<&external::DcapEvidence> for DcapEvidence { impl From<&prost::DcapEvidence> for external::DcapEvidence { fn from(src: &prost::DcapEvidence) -> Self { let bytes = src.encode_to_vec(); - let mut proto = Self::default(); - proto - .merge_from_bytes(&bytes) - .expect("failure to merge means prost and protobuf are out of sync"); - proto + Self::decode(bytes.as_slice()) + .expect("failure to merge means prost and protobuf are out of sync") } } @@ -86,7 +82,7 @@ mod test { let evidence = evidence(); let mut proto_evidence = external::DcapEvidence::try_from(&evidence) .expect("Failed to convert evidence to proto"); - let proto_quote = proto_evidence.mut_quote(); + let proto_quote = proto_evidence.quote.as_mut().unwrap(); proto_quote.data[0] += 1; let error = DcapEvidence::try_from(&proto_evidence); diff --git a/api/src/convert/ed25519_multisig.rs b/api/src/convert/ed25519_multisig.rs index f466caaded..24b20ba7d8 100644 --- a/api/src/convert/ed25519_multisig.rs +++ b/api/src/convert/ed25519_multisig.rs @@ -9,14 +9,13 @@ use mc_crypto_multisig::{MultiSig, SignerSet}; /// Convert MultiSig --> external::Ed25519MultiSig. impl From<&MultiSig> for external::Ed25519MultiSig { fn from(src: &MultiSig) -> Self { - let mut dst = external::Ed25519MultiSig::new(); - dst.set_signatures( - src.signatures() + Self { + signatures: src + .signatures() .iter() .map(external::Ed25519Signature::from) .collect(), - ); - dst + } } } @@ -26,7 +25,7 @@ impl TryFrom<&external::Ed25519MultiSig> for MultiSig { fn try_from(source: &external::Ed25519MultiSig) -> Result { let signatures: Vec = source - .get_signatures() + .signatures .iter() .map(Ed25519Signature::try_from) .collect::, _>>()?; @@ -38,16 +37,15 @@ impl TryFrom<&external::Ed25519MultiSig> for MultiSig { /// Convert SignerSet --> external::Ed25519SignerSet. impl From<&SignerSet> for external::Ed25519SignerSet { fn from(src: &SignerSet) -> Self { - let mut dst = external::Ed25519SignerSet::new(); - dst.set_individual_signers( - src.individual_signers() + Self { + individual_signers: src + .individual_signers() .iter() .map(external::Ed25519Public::from) .collect(), - ); - dst.set_multi_signers(src.multi_signers().iter().map(From::from).collect()); - dst.set_threshold(src.threshold()); - dst + multi_signers: src.multi_signers().iter().map(From::from).collect(), + threshold: src.threshold(), + } } } @@ -57,18 +55,18 @@ impl TryFrom<&external::Ed25519SignerSet> for SignerSet { fn try_from(source: &external::Ed25519SignerSet) -> Result { let individual_signers: Vec = source - .get_individual_signers() + .individual_signers .iter() .map(Ed25519Public::try_from) .collect::, _>>()?; let multi_signers: Vec = source - .get_multi_signers() + .multi_signers .iter() .map(TryFrom::try_from) .collect::, _>>()?; - let threshold = source.get_threshold(); + let threshold = source.threshold; Ok(Self::new_with_multi( individual_signers, @@ -84,7 +82,7 @@ pub mod tests { use mc_crypto_keys::{Ed25519Pair, Signer}; use mc_util_from_random::FromRandom; use mc_util_serial::{decode, encode}; - use protobuf::Message; + use prost::Message; use rand_core::SeedableRng; use rand_hc::Hc128Rng; @@ -147,14 +145,14 @@ pub mod tests { // function. { let bytes = encode(&source); - let recovered = external::Ed25519SignerSet::parse_from_bytes(&bytes).unwrap(); + let recovered = external::Ed25519SignerSet::decode(bytes.as_slice()).unwrap(); assert_eq!(recovered, external::Ed25519SignerSet::from(&source)); } // Encoding with protobuf, decoding with prost should be the identity function. { let external = external::Ed25519SignerSet::from(&source); - let bytes = external.write_to_bytes().unwrap(); + let bytes = external.encode_to_vec(); let recovered: SignerSet = decode(&bytes).unwrap(); assert_eq!(source, recovered); } @@ -185,14 +183,14 @@ pub mod tests { // function. { let bytes = encode(&source); - let recovered = external::Ed25519MultiSig::parse_from_bytes(&bytes).unwrap(); + let recovered = external::Ed25519MultiSig::decode(bytes.as_slice()).unwrap(); assert_eq!(recovered, external::Ed25519MultiSig::from(&source)); } // Encoding with protobuf, decoding with prost should be the identity function. { let external = external::Ed25519MultiSig::from(&source); - let bytes = external.write_to_bytes().unwrap(); + let bytes = external.encode_to_vec(); let recovered: MultiSig = decode(&bytes).unwrap(); assert_eq!(source, recovered); } diff --git a/api/src/convert/ed25519_signature.rs b/api/src/convert/ed25519_signature.rs index 7108b7a7a6..1084c5f279 100644 --- a/api/src/convert/ed25519_signature.rs +++ b/api/src/convert/ed25519_signature.rs @@ -8,9 +8,9 @@ use mc_crypto_keys::{Ed25519Public, Ed25519Signature}; /// Convert Ed25519Signature --> external::Ed25519Signature. impl From<&Ed25519Signature> for external::Ed25519Signature { fn from(src: &Ed25519Signature) -> Self { - let mut dst = external::Ed25519Signature::new(); - dst.set_data(src.to_bytes().to_vec()); - dst + Self { + data: src.to_bytes().to_vec(), + } } } @@ -19,7 +19,7 @@ impl TryFrom<&external::Ed25519Signature> for Ed25519Signature { type Error = ConversionError; fn try_from(source: &external::Ed25519Signature) -> Result { - let bytes: &[u8] = source.get_data(); + let bytes: &[u8] = source.data.as_slice(); Ed25519Signature::try_from(bytes).map_err(|_| ConversionError::ArrayCastError) } } @@ -27,10 +27,10 @@ impl TryFrom<&external::Ed25519Signature> for Ed25519Signature { /// Convert Ed25519Public --> external::Ed25519Public. impl From<&Ed25519Public> for external::Ed25519Public { fn from(src: &Ed25519Public) -> Self { - let mut dst = external::Ed25519Public::new(); let bytes: &[u8] = src.as_ref(); - dst.set_data(bytes.to_vec()); - dst + Self { + data: bytes.to_vec(), + } } } @@ -39,7 +39,7 @@ impl TryFrom<&external::Ed25519Public> for Ed25519Public { type Error = ConversionError; fn try_from(source: &external::Ed25519Public) -> Result { - let bytes: &[u8] = source.get_data(); + let bytes: &[u8] = source.data.as_slice(); Ed25519Public::try_from(bytes).map_err(|_| ConversionError::ArrayCastError) } } diff --git a/api/src/convert/enclave_report_data_contents.rs b/api/src/convert/enclave_report_data_contents.rs index b4129d7b3d..c11f695043 100644 --- a/api/src/convert/enclave_report_data_contents.rs +++ b/api/src/convert/enclave_report_data_contents.rs @@ -5,17 +5,13 @@ use crate::{external, ConversionError}; use mc_attest_verifier_types::{prost, EnclaveReportDataContents}; use mc_util_serial::Message; -use protobuf::Message as ProtoMessage; impl From<&EnclaveReportDataContents> for external::EnclaveReportDataContents { fn from(src: &EnclaveReportDataContents) -> Self { let prost = prost::EnclaveReportDataContents::from(src); let bytes = prost.encode_to_vec(); - let mut proto = Self::default(); - proto - .merge_from_bytes(&bytes) - .expect("failure to merge means prost and protobuf are out of sync"); - proto + Self::decode(bytes.as_slice()) + .expect("failure to merge means prost and protobuf are out of sync") } } diff --git a/api/src/convert/input_ring.rs b/api/src/convert/input_ring.rs index ac4c9086e7..9dfdd28ed3 100644 --- a/api/src/convert/input_ring.rs +++ b/api/src/convert/input_ring.rs @@ -2,7 +2,7 @@ //! Convert to/from mc_transaction_core::ring_ct::InputRing. -use crate::{external, ConversionError}; +use crate::{external, external::input_ring::Ring, ConversionError}; use mc_crypto_ring_signature_signer::SignableInputRing; use mc_transaction_core::ring_ct::{InputRing, PresignedInputRing}; @@ -24,10 +24,10 @@ impl TryFrom<&external::InputRing> for InputRing { .as_ref() .ok_or_else(|| ConversionError::MissingField("ring".to_string()))? { - external::InputRing_oneof_ring::presigned(presigned) => { + external::input_ring::Ring::Presigned(presigned) => { Ok(InputRing::Presigned((presigned).try_into()?)) } - external::InputRing_oneof_ring::signable(signable) => { + external::input_ring::Ring::Signable(signable) => { Ok(InputRing::Signable((signable).try_into()?)) } } @@ -36,18 +36,18 @@ impl TryFrom<&external::InputRing> for InputRing { impl From<&PresignedInputRing> for external::InputRing { fn from(source: &PresignedInputRing) -> Self { - let mut input_ring = external::InputRing::new(); - input_ring.set_presigned(source.into()); - input_ring + Self { + ring: Some(external::input_ring::Ring::Presigned(source.into())), + } } } impl From<&PresignedInputRing> for external::PresignedInputRing { fn from(source: &PresignedInputRing) -> Self { - let mut presigned_input_ring = external::PresignedInputRing::new(); - presigned_input_ring.set_mlsag((&source.mlsag).into()); - presigned_input_ring.set_pseudo_output_secret((&source.pseudo_output_secret).into()); - presigned_input_ring + Self { + mlsag: Some((&source.mlsag).into()), + pseudo_output_secret: Some((&source.pseudo_output_secret).into()), + } } } @@ -56,29 +56,35 @@ impl TryFrom<&external::PresignedInputRing> for PresignedInputRing { fn try_from(source: &external::PresignedInputRing) -> Result { Ok(PresignedInputRing { - mlsag: source.get_mlsag().try_into()?, - pseudo_output_secret: source.get_pseudo_output_secret().try_into()?, + mlsag: source + .mlsag + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?, + pseudo_output_secret: source + .pseudo_output_secret + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?, }) } } impl From<&SignableInputRing> for external::InputRing { fn from(source: &SignableInputRing) -> Self { - let mut input_ring = external::InputRing::new(); - input_ring.set_signable(source.into()); - input_ring + Self { + ring: Some(Ring::Signable(source.into())), + } } } impl From<&SignableInputRing> for external::SignableInputRing { fn from(source: &SignableInputRing) -> Self { - let mut ring = external::SignableInputRing::new(); - ring.set_members(protobuf::RepeatedField::from_vec( - source.members.iter().map(|member| member.into()).collect(), - )); - ring.set_input_secret((&source.input_secret).into()); - ring.set_real_input_index(source.real_input_index as u32); - ring + Self { + members: source.members.iter().map(|member| member.into()).collect(), + input_secret: Some((&source.input_secret).into()), + real_input_index: source.real_input_index as u32, + } } } @@ -87,12 +93,16 @@ impl TryFrom<&external::SignableInputRing> for SignableInputRing { fn try_from(source: &external::SignableInputRing) -> Result { let members = source - .get_members() + .members .iter() .map(|member| member.try_into()) .collect::, _>>()?; - let input_secret = source.get_input_secret().try_into()?; - let real_input_index = source.get_real_input_index() as usize; + let input_secret = source + .input_secret + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let real_input_index = source.real_input_index as usize; Ok(SignableInputRing { members, input_secret, diff --git a/api/src/convert/input_secret.rs b/api/src/convert/input_secret.rs index ea78f0d5f0..a5c878ae42 100644 --- a/api/src/convert/input_secret.rs +++ b/api/src/convert/input_secret.rs @@ -2,41 +2,42 @@ //! Convert to/from mc_crypto_ring_signature_signer::InputSecret. -use crate::{external, ConversionError}; +use crate::{external, external::input_secret, ConversionError}; use mc_crypto_ring_signature_signer::{InputSecret, OneTimeKeyDeriveData}; impl From<&InputSecret> for external::InputSecret { fn from(source: &InputSecret) -> Self { - let mut input_secret = external::InputSecret::new(); - match source.onetime_key_derive_data { + let onetime_key_derive_data = match source.onetime_key_derive_data { OneTimeKeyDeriveData::OneTimeKey(onetime_private_key) => { - input_secret.set_onetime_private_key((&onetime_private_key).into()) + input_secret::OnetimeKeyDeriveData::OnetimePrivateKey((&onetime_private_key).into()) } OneTimeKeyDeriveData::SubaddressIndex(subaddress_index) => { - input_secret.set_subaddress_index(subaddress_index) + input_secret::OnetimeKeyDeriveData::SubaddressIndex(subaddress_index) } + }; + Self { + amount: Some((&source.amount).into()), + blinding: Some((&source.blinding).into()), + onetime_key_derive_data: Some(onetime_key_derive_data), } - input_secret.set_amount((&source.amount).into()); - input_secret.set_blinding((&source.blinding).into()); - input_secret } } -impl TryFrom<&external::InputSecret_oneof_onetime_key_derive_data> for OneTimeKeyDeriveData { +impl TryFrom<&external::input_secret::OnetimeKeyDeriveData> for OneTimeKeyDeriveData { type Error = ConversionError; fn try_from( - source: &external::InputSecret_oneof_onetime_key_derive_data, + source: &external::input_secret::OnetimeKeyDeriveData, ) -> Result { match source { - external::InputSecret_oneof_onetime_key_derive_data::onetime_private_key( + external::input_secret::OnetimeKeyDeriveData::OnetimePrivateKey( onetime_private_key, ) => Ok(OneTimeKeyDeriveData::OneTimeKey( onetime_private_key.try_into()?, )), - external::InputSecret_oneof_onetime_key_derive_data::subaddress_index( - subaddress_index, - ) => Ok(OneTimeKeyDeriveData::SubaddressIndex(*subaddress_index)), + external::input_secret::OnetimeKeyDeriveData::SubaddressIndex(subaddress_index) => { + Ok(OneTimeKeyDeriveData::SubaddressIndex(*subaddress_index)) + } } } } @@ -54,8 +55,12 @@ impl TryFrom<&external::InputSecret> for InputSecret { .try_into()?; Ok(InputSecret { onetime_key_derive_data, - amount: source.get_amount().into(), - blinding: source.get_blinding().try_into()?, + amount: source.amount.as_ref().unwrap_or(&Default::default()).into(), + blinding: source + .blinding + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?, }) } } diff --git a/api/src/convert/key_image.rs b/api/src/convert/key_image.rs index 0b1f1a7fe9..01fb1b728c 100644 --- a/api/src/convert/key_image.rs +++ b/api/src/convert/key_image.rs @@ -8,9 +8,9 @@ use mc_transaction_core::ring_signature::KeyImage; /// Convert KeyImage --> external::KeyImage. impl From<&KeyImage> for external::KeyImage { fn from(other: &KeyImage) -> Self { - let mut key_image = external::KeyImage::new(); - key_image.set_data(other.to_vec()); - key_image + Self { + data: other.to_vec(), + } } } @@ -19,16 +19,14 @@ impl TryFrom<&external::KeyImage> for KeyImage { type Error = ConversionError; fn try_from(source: &external::KeyImage) -> Result { - let bytes: &[u8] = source.get_data(); + let bytes: &[u8] = source.data.as_ref(); Ok(KeyImage::try_from(bytes)?) } } impl From> for external::KeyImage { fn from(src: Vec) -> Self { - let mut key_image = external::KeyImage::new(); - key_image.set_data(src); - key_image + Self { data: src } } } @@ -47,8 +45,9 @@ mod tests { #[test] // external::keyImage --> KeyImage fn test_key_image_try_from() { - let mut source = external::KeyImage::new(); - source.set_data(KeyImage::from(11).to_vec()); + let source = external::KeyImage { + data: KeyImage::from(11).to_vec(), + }; // try_from should succeed. let key_image = KeyImage::try_from(&source).unwrap(); @@ -63,8 +62,9 @@ mod tests { fn test_key_image_try_from_conversion_errors() { // Helper function asserts that a ConversionError::ArrayCastError is produced. fn expects_array_cast_error(bytes: &[u8]) { - let mut source = external::KeyImage::new(); - source.set_data(bytes.to_vec()); + let source = external::KeyImage { + data: bytes.to_vec(), + }; match KeyImage::try_from(&source).unwrap_err() { ConversionError::ArrayCastError => {} // Expected outcome. _ => panic!(), diff --git a/api/src/convert/mint_config.rs b/api/src/convert/mint_config.rs index dcbd054a9b..0920fc0ebc 100644 --- a/api/src/convert/mint_config.rs +++ b/api/src/convert/mint_config.rs @@ -3,17 +3,16 @@ //! Convert to/from external:MintConfig/MintConfigTxPrefix/MintConfigTx. use crate::{external, ConversionError}; -use mc_crypto_multisig::{MultiSig, SignerSet}; use mc_transaction_core::mint::{MintConfig, MintConfigTx, MintConfigTxPrefix}; /// Convert MintConfig --> external::MintConfig. impl From<&MintConfig> for external::MintConfig { fn from(src: &MintConfig) -> Self { - let mut dst = external::MintConfig::new(); - dst.set_token_id(src.token_id); - dst.set_signer_set((&src.signer_set).into()); - dst.set_mint_limit(src.mint_limit); - dst + Self { + token_id: src.token_id, + signer_set: Some((&src.signer_set).into()), + mint_limit: src.mint_limit, + } } } @@ -22,11 +21,15 @@ impl TryFrom<&external::MintConfig> for MintConfig { type Error = ConversionError; fn try_from(source: &external::MintConfig) -> Result { - let signer_set = SignerSet::try_from(source.get_signer_set())?; + let signer_set = source + .signer_set + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; Ok(Self { - token_id: source.get_token_id(), + token_id: source.token_id, signer_set, - mint_limit: source.get_mint_limit(), + mint_limit: source.mint_limit, }) } } @@ -34,13 +37,13 @@ impl TryFrom<&external::MintConfig> for MintConfig { /// Convert MintConfigTxPrefix --> external::MintConfigTxPrefix. impl From<&MintConfigTxPrefix> for external::MintConfigTxPrefix { fn from(src: &MintConfigTxPrefix) -> Self { - let mut dst = external::MintConfigTxPrefix::new(); - dst.set_token_id(src.token_id); - dst.set_configs(src.configs.iter().map(external::MintConfig::from).collect()); - dst.set_nonce(src.nonce.clone()); - dst.set_tombstone_block(src.tombstone_block); - dst.set_total_mint_limit(src.total_mint_limit); - dst + Self { + token_id: src.token_id, + configs: src.configs.iter().map(external::MintConfig::from).collect(), + nonce: src.nonce.clone(), + tombstone_block: src.tombstone_block, + total_mint_limit: src.total_mint_limit, + } } } @@ -50,17 +53,17 @@ impl TryFrom<&external::MintConfigTxPrefix> for MintConfigTxPrefix { fn try_from(source: &external::MintConfigTxPrefix) -> Result { let configs: Vec = source - .get_configs() + .configs .iter() .map(MintConfig::try_from) .collect::, _>>()?; Ok(Self { - token_id: source.get_token_id(), + token_id: source.token_id, configs, - nonce: source.get_nonce().to_vec(), - tombstone_block: source.get_tombstone_block(), - total_mint_limit: source.get_total_mint_limit(), + nonce: source.nonce.clone(), + tombstone_block: source.tombstone_block, + total_mint_limit: source.total_mint_limit, }) } } @@ -68,10 +71,10 @@ impl TryFrom<&external::MintConfigTxPrefix> for MintConfigTxPrefix { /// Convert MintConfigTx --> external::MintConfigTx. impl From<&MintConfigTx> for external::MintConfigTx { fn from(src: &MintConfigTx) -> Self { - let mut dst = external::MintConfigTx::new(); - dst.set_prefix((&src.prefix).into()); - dst.set_signature((&src.signature).into()); - dst + Self { + prefix: Some((&src.prefix).into()), + signature: Some((&src.signature).into()), + } } } @@ -80,8 +83,16 @@ impl TryFrom<&external::MintConfigTx> for MintConfigTx { type Error = ConversionError; fn try_from(source: &external::MintConfigTx) -> Result { - let prefix = MintConfigTxPrefix::try_from(source.get_prefix())?; - let signature = MultiSig::try_from(source.get_signature())?; + let prefix = source + .prefix + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let signature = source + .signature + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; Ok(Self { prefix, signature }) } @@ -92,7 +103,7 @@ mod tests { use super::*; use crate::convert::ed25519_multisig::tests::{test_multi_sig, test_signer_set}; use mc_util_serial::{decode, encode}; - use protobuf::Message; + use prost::Message; #[test] // MintConfig -> external::MintConfig -> MintConfig should be the identity @@ -123,14 +134,14 @@ mod tests { // function. { let bytes = encode(&source); - let recovered = external::MintConfig::parse_from_bytes(&bytes).unwrap(); + let recovered = external::MintConfig::decode(bytes.as_slice()).unwrap(); assert_eq!(recovered, external::MintConfig::from(&source)); } // Encoding with protobuf, decoding with prost should be the identity function. { let external = external::MintConfig::from(&source); - let bytes = external.write_to_bytes().unwrap(); + let bytes = external.encode_to_vec(); let recovered: MintConfig = decode(&bytes).unwrap(); assert_eq!(source, recovered); } @@ -182,14 +193,14 @@ mod tests { // function. { let bytes = encode(&source); - let recovered = external::MintConfigTx::parse_from_bytes(&bytes).unwrap(); + let recovered = external::MintConfigTx::decode(bytes.as_slice()).unwrap(); assert_eq!(recovered, external::MintConfigTx::from(&source)); } // Encoding with protobuf, decoding with prost should be the identity function. { let external = external::MintConfigTx::from(&source); - let bytes = external.write_to_bytes().unwrap(); + let bytes = external.encode_to_vec(); let recovered: MintConfigTx = decode(&bytes).unwrap(); assert_eq!(source, recovered); } diff --git a/api/src/convert/mint_tx.rs b/api/src/convert/mint_tx.rs index d74d0d409b..b193ddc686 100644 --- a/api/src/convert/mint_tx.rs +++ b/api/src/convert/mint_tx.rs @@ -3,8 +3,6 @@ //! Convert to/from external:MintTx/MintTxPrefix. use crate::{external, ConversionError}; -use mc_crypto_keys::RistrettoPublic; -use mc_crypto_multisig::MultiSig; use mc_transaction_core::{ encrypted_fog_hint::EncryptedFogHint, mint::{MintTx, MintTxPrefix}, @@ -13,18 +11,20 @@ use mc_transaction_core::{ /// Convert MintTxPrefix --> external::MintTxPrefix. impl From<&MintTxPrefix> for external::MintTxPrefix { fn from(src: &MintTxPrefix) -> Self { - let mut dst = external::MintTxPrefix::new(); - dst.set_token_id(src.token_id); - dst.set_amount(src.amount); - dst.set_view_public_key((&src.view_public_key).into()); - dst.set_spend_public_key((&src.spend_public_key).into()); - dst.set_nonce(src.nonce.clone()); - dst.set_tombstone_block(src.tombstone_block); - if let Some(e_fog_hint) = &src.e_fog_hint { - let hint_bytes = e_fog_hint.as_ref().to_vec(); - dst.mut_e_fog_hint().set_data(hint_bytes); + Self { + token_id: src.token_id, + amount: src.amount, + view_public_key: Some((&src.view_public_key).into()), + spend_public_key: Some((&src.spend_public_key).into()), + nonce: src.nonce.clone(), + tombstone_block: src.tombstone_block, + e_fog_hint: src + .e_fog_hint + .as_ref() + .map(|hint| external::EncryptedFogHint { + data: hint.as_ref().to_vec(), + }), } - dst } } @@ -33,25 +33,32 @@ impl TryFrom<&external::MintTxPrefix> for MintTxPrefix { type Error = ConversionError; fn try_from(source: &external::MintTxPrefix) -> Result { - let view_public_key = RistrettoPublic::try_from(source.get_view_public_key())?; - let spend_public_key = RistrettoPublic::try_from(source.get_spend_public_key())?; - let e_fog_hint_data = source.get_e_fog_hint().get_data(); - let e_fog_hint = if e_fog_hint_data.is_empty() { - None - } else { - Some( - EncryptedFogHint::try_from(e_fog_hint_data) - .map_err(|_| ConversionError::ArrayCastError)?, - ) - }; + let view_public_key = source + .view_public_key + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let spend_public_key = source + .spend_public_key + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let e_fog_hint = source + .e_fog_hint + .as_ref() + .map(|hint| { + EncryptedFogHint::try_from(hint.data.as_slice()) + .map_err(|_| ConversionError::ArrayCastError) + }) + .transpose()?; Ok(Self { - token_id: source.get_token_id(), - amount: source.get_amount(), + token_id: source.token_id, + amount: source.amount, view_public_key, spend_public_key, - nonce: source.get_nonce().to_vec(), - tombstone_block: source.get_tombstone_block(), + nonce: source.nonce.clone(), + tombstone_block: source.tombstone_block, e_fog_hint, }) } @@ -60,10 +67,10 @@ impl TryFrom<&external::MintTxPrefix> for MintTxPrefix { /// Convert MintTx --> external::MintTx. impl From<&MintTx> for external::MintTx { fn from(src: &MintTx) -> Self { - let mut dst = external::MintTx::new(); - dst.set_prefix((&src.prefix).into()); - dst.set_signature((&src.signature).into()); - dst + Self { + prefix: Some((&src.prefix).into()), + signature: Some((&src.signature).into()), + } } } @@ -72,8 +79,16 @@ impl TryFrom<&external::MintTx> for MintTx { type Error = ConversionError; fn try_from(source: &external::MintTx) -> Result { - let prefix = MintTxPrefix::try_from(source.get_prefix())?; - let signature = MultiSig::try_from(source.get_signature())?; + let prefix = source + .prefix + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let signature = source + .signature + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; Ok(Self { prefix, signature }) } @@ -83,9 +98,10 @@ impl TryFrom<&external::MintTx> for MintTx { mod tests { use super::*; use crate::convert::ed25519_multisig::tests::test_multi_sig; + use mc_crypto_keys::RistrettoPublic; use mc_util_from_random::FromRandom; use mc_util_serial::{decode, encode}; - use protobuf::Message; + use prost::Message; use rand_core::{RngCore, SeedableRng}; use rand_hc::Hc128Rng; @@ -127,14 +143,14 @@ mod tests { // function. { let bytes = encode(&source); - let recovered = external::MintTx::parse_from_bytes(&bytes).unwrap(); + let recovered = external::MintTx::decode(bytes.as_slice()).unwrap(); assert_eq!(recovered, external::MintTx::from(&source)); } // Encoding with protobuf, decoding with prost should be the identity function. { let external = external::MintTx::from(&source); - let bytes = external.write_to_bytes().unwrap(); + let bytes = external.encode_to_vec(); let recovered: MintTx = decode(&bytes).unwrap(); assert_eq!(source, recovered); } diff --git a/api/src/convert/node.rs b/api/src/convert/node.rs index c3d54a5957..8016e3c383 100644 --- a/api/src/convert/node.rs +++ b/api/src/convert/node.rs @@ -8,10 +8,10 @@ use std::str::FromStr; impl From<&NodeID> for NodeProto { fn from(node: &NodeID) -> NodeProto { - let mut proto = NodeProto::new(); - proto.responder_id = node.responder_id.to_string(); - proto.set_public_key((&node.public_key).into()); - proto + Self { + responder_id: node.responder_id.to_string(), + public_key: Some((&node.public_key).into()), + } } } @@ -21,7 +21,11 @@ impl TryFrom<&NodeProto> for NodeID { fn try_from(proto: &NodeProto) -> Result { let responder_id = ResponderId::from_str(&proto.responder_id) .map_err(|_| ConversionError::InvalidContents)?; - let public_key = proto.get_public_key().try_into()?; + let public_key = proto + .public_key + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; Ok(NodeID { responder_id, public_key, diff --git a/api/src/convert/output_secret.rs b/api/src/convert/output_secret.rs index 185037f923..336433deb2 100644 --- a/api/src/convert/output_secret.rs +++ b/api/src/convert/output_secret.rs @@ -7,10 +7,10 @@ use mc_transaction_core::ring_ct::OutputSecret; impl From<&OutputSecret> for external::OutputSecret { fn from(source: &OutputSecret) -> Self { - let mut output_secret = external::OutputSecret::new(); - output_secret.set_amount((&source.amount).into()); - output_secret.set_blinding((&source.blinding).into()); - output_secret + Self { + amount: Some((&source.amount).into()), + blinding: Some((&source.blinding).into()), + } } } @@ -18,10 +18,13 @@ impl TryFrom<&external::OutputSecret> for OutputSecret { type Error = ConversionError; fn try_from(source: &external::OutputSecret) -> Result { - Ok(OutputSecret { - amount: source.get_amount().into(), - blinding: source.get_blinding().try_into()?, - }) + let amount = source.amount.as_ref().unwrap_or(&Default::default()).into(); + let blinding = source + .blinding + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + Ok(OutputSecret { amount, blinding }) } } diff --git a/api/src/convert/public_address.rs b/api/src/convert/public_address.rs index 82374a4236..778e41179d 100644 --- a/api/src/convert/public_address.rs +++ b/api/src/convert/public_address.rs @@ -7,24 +7,13 @@ use mc_account_keys::PublicAddress; impl From<&PublicAddress> for external::PublicAddress { fn from(src: &PublicAddress) -> Self { - let mut dst = external::PublicAddress::new(); - - dst.set_view_public_key(external::CompressedRistretto::from(src.view_public_key())); - dst.set_spend_public_key(external::CompressedRistretto::from(src.spend_public_key())); - - if let Some(url) = src.fog_report_url() { - dst.set_fog_report_url(url.to_string()); - } - - if let Some(sig) = src.fog_authority_sig() { - dst.set_fog_authority_sig(sig.to_vec()); + Self { + view_public_key: Some(src.view_public_key().into()), + spend_public_key: Some(src.spend_public_key().into()), + fog_report_url: src.fog_report_url().unwrap_or_default().to_string(), + fog_report_id: src.fog_report_id().unwrap_or_default().to_string(), + fog_authority_sig: src.fog_authority_sig().unwrap_or_default().to_vec(), } - - if let Some(key) = src.fog_report_id() { - dst.set_fog_report_id(key.to_string()); - } - - dst } } @@ -76,11 +65,11 @@ mod tests { let public_address = AccountKey::random(&mut rng).default_subaddress(); let proto_credentials = external::PublicAddress::from(&public_address); assert_eq!( - *proto_credentials.get_view_public_key(), + *proto_credentials.view_public_key.as_ref().unwrap(), external::CompressedRistretto::from(public_address.view_public_key()) ); assert_eq!( - *proto_credentials.get_spend_public_key(), + *proto_credentials.spend_public_key.as_ref().unwrap(), external::CompressedRistretto::from(public_address.spend_public_key()) ); assert_eq!(proto_credentials.fog_report_url, String::from("")); @@ -108,11 +97,11 @@ mod tests { let proto_credentials = external::PublicAddress::from(&public_address); assert_eq!( - *proto_credentials.get_view_public_key(), + *proto_credentials.view_public_key.as_ref().unwrap(), external::CompressedRistretto::from(public_address.view_public_key()) ); assert_eq!( - *proto_credentials.get_spend_public_key(), + *proto_credentials.spend_public_key.as_ref().unwrap(), external::CompressedRistretto::from(public_address.spend_public_key()) ); assert_eq!( diff --git a/api/src/convert/quorum_set.rs b/api/src/convert/quorum_set.rs index 696412f6d8..0ffe4ee9e7 100644 --- a/api/src/convert/quorum_set.rs +++ b/api/src/convert/quorum_set.rs @@ -4,8 +4,7 @@ use crate::{ quorum_set::{ - QuorumSet as QuorumSetProto, QuorumSetMember as QuorumSetMemberProto, - QuorumSetMember_oneof_member, + quorum_set_member, QuorumSet as QuorumSetProto, QuorumSetMember as QuorumSetMemberProto, }, ConversionError, }; @@ -14,15 +13,15 @@ use mc_blockchain_types::{NodeID, QuorumSet, QuorumSetMember, QuorumSetMemberWra // QuorumSet impl From<&QuorumSet> for QuorumSetProto { fn from(qs: &QuorumSet) -> Self { - let mut proto = QuorumSetProto::new(); let members = qs .members .iter() .filter_map(|m| (*m).as_ref().map(Into::into)) .collect(); - proto.threshold = qs.threshold; - proto.set_members(members); - proto + Self { + threshold: qs.threshold, + members, + } } } @@ -54,12 +53,13 @@ impl TryFrom<&QuorumSetProto> for QuorumSet { // QuorumSetMember impl From<&QuorumSetMember> for QuorumSetMemberProto { fn from(member: &QuorumSetMember) -> QuorumSetMemberProto { - let mut proto = QuorumSetMemberProto::new(); - match member { - QuorumSetMember::Node(id) => proto.set_node(id.into()), - QuorumSetMember::InnerSet(qs) => proto.set_inner_set(qs.into()), + let set_member = match member { + QuorumSetMember::Node(id) => quorum_set_member::Member::Node(id.into()), + QuorumSetMember::InnerSet(qs) => quorum_set_member::Member::InnerSet(qs.into()), + }; + Self { + member: Some(set_member), } - proto } } @@ -68,10 +68,8 @@ impl TryFrom<&QuorumSetMemberProto> for QuorumSetMember { fn try_from(proto: &QuorumSetMemberProto) -> Result { match proto.member.as_ref() { - Some(QuorumSetMember_oneof_member::node(id)) => { - Ok(QuorumSetMember::Node(id.try_into()?)) - } - Some(QuorumSetMember_oneof_member::inner_set(qs)) => { + Some(quorum_set_member::Member::Node(id)) => Ok(QuorumSetMember::Node(id.try_into()?)), + Some(quorum_set_member::Member::InnerSet(qs)) => { Ok(QuorumSetMember::InnerSet(qs.try_into()?)) } None => Err(ConversionError::ObjectMissing), diff --git a/api/src/convert/quote3.rs b/api/src/convert/quote3.rs index 60509d4335..cac03774f1 100644 --- a/api/src/convert/quote3.rs +++ b/api/src/convert/quote3.rs @@ -8,10 +8,9 @@ use mc_sgx_dcap_types::Quote3; impl> From<&Quote3> for external::Quote3 { fn from(src: &Quote3) -> Self { - let mut dst = Self::new(); - dst.set_data(src.as_ref().to_vec()); - - dst + Self { + data: src.as_ref().to_vec(), + } } } diff --git a/api/src/convert/reduced_tx_out.rs b/api/src/convert/reduced_tx_out.rs index 4c4f858dcd..afdd7e5b00 100644 --- a/api/src/convert/reduced_tx_out.rs +++ b/api/src/convert/reduced_tx_out.rs @@ -7,11 +7,11 @@ use mc_transaction_core::ring_signature::ReducedTxOut; impl From<&ReducedTxOut> for external::ReducedTxOut { fn from(source: &ReducedTxOut) -> Self { - let mut reduced_tx_out = external::ReducedTxOut::new(); - reduced_tx_out.set_public_key((&source.public_key).into()); - reduced_tx_out.set_target_key((&source.target_key).into()); - reduced_tx_out.set_commitment((&source.commitment).into()); - reduced_tx_out + Self { + public_key: Some((&source.public_key).into()), + target_key: Some((&source.target_key).into()), + commitment: Some((&source.commitment).into()), + } } } @@ -19,10 +19,25 @@ impl TryFrom<&external::ReducedTxOut> for ReducedTxOut { type Error = ConversionError; fn try_from(source: &external::ReducedTxOut) -> Result { + let public_key = source + .public_key + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let target_key = source + .target_key + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let commitment = source + .commitment + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; Ok(ReducedTxOut { - public_key: source.get_public_key().try_into()?, - target_key: source.get_target_key().try_into()?, - commitment: source.get_commitment().try_into()?, + public_key, + target_key, + commitment, }) } } diff --git a/api/src/convert/ring_mlsag.rs b/api/src/convert/ring_mlsag.rs index f264e368b1..34715b7681 100644 --- a/api/src/convert/ring_mlsag.rs +++ b/api/src/convert/ring_mlsag.rs @@ -3,33 +3,42 @@ //! Convert to/from external::RingMLSAG use crate::{external, ConversionError}; -use mc_transaction_core::ring_signature::{CurveScalar, KeyImage, RingMLSAG}; +use mc_transaction_core::ring_signature::{CurveScalar, RingMLSAG}; -impl From<&RingMLSAG> for external::RingMLSAG { +impl From<&RingMLSAG> for external::RingMlsag { fn from(source: &RingMLSAG) -> Self { - let mut ring_mlsag = external::RingMLSAG::new(); - ring_mlsag.set_c_zero(external::CurveScalar::from(&source.c_zero)); let responses: Vec = source .responses .iter() .map(external::CurveScalar::from) .collect(); - ring_mlsag.set_responses(responses.into()); - ring_mlsag.set_key_image(external::KeyImage::from(&source.key_image)); - ring_mlsag + Self { + c_zero: external::CurveScalar::from(&source.c_zero).into(), + responses, + key_image: external::KeyImage::from(&source.key_image).into(), + } } } -impl TryFrom<&external::RingMLSAG> for RingMLSAG { +impl TryFrom<&external::RingMlsag> for RingMLSAG { type Error = ConversionError; - fn try_from(source: &external::RingMLSAG) -> Result { - let c_zero = CurveScalar::try_from(source.get_c_zero())?; - let mut responses: Vec = Vec::new(); - for response in source.get_responses() { - responses.push(CurveScalar::try_from(response)?); - } - let key_image = KeyImage::try_from(source.get_key_image())?; + fn try_from(source: &external::RingMlsag) -> Result { + let c_zero = source + .c_zero + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let responses = source + .responses + .iter() + .map(CurveScalar::try_from) + .collect::, _>>()?; + let key_image = source + .key_image + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; Ok(RingMLSAG { c_zero, diff --git a/api/src/convert/ristretto_private.rs b/api/src/convert/ristretto_private.rs index 157e4eb494..8899ca1e47 100644 --- a/api/src/convert/ristretto_private.rs +++ b/api/src/convert/ristretto_private.rs @@ -8,9 +8,9 @@ use mc_crypto_keys::RistrettoPrivate; /// Convert RistrettoPrivate --> external::RistrettoPrivate impl From<&RistrettoPrivate> for external::RistrettoPrivate { fn from(other: &RistrettoPrivate) -> Self { - let mut key = external::RistrettoPrivate::new(); - key.set_data(other.to_bytes().to_vec()); - key + Self { + data: other.to_bytes().to_vec(), + } } } @@ -19,7 +19,7 @@ impl TryFrom<&external::RistrettoPrivate> for RistrettoPrivate { type Error = ConversionError; fn try_from(source: &external::RistrettoPrivate) -> Result { - let bytes: &[u8] = source.get_data(); - RistrettoPrivate::try_from(bytes).map_err(|_| ConversionError::ArrayCastError) + RistrettoPrivate::try_from(source.data.as_slice()) + .map_err(|_| ConversionError::ArrayCastError) } } diff --git a/api/src/convert/signature_rct_bulletproofs.rs b/api/src/convert/signature_rct_bulletproofs.rs index 018325311c..0c99b47e36 100644 --- a/api/src/convert/signature_rct_bulletproofs.rs +++ b/api/src/convert/signature_rct_bulletproofs.rs @@ -6,32 +6,28 @@ use crate::{external, ConversionError}; use mc_transaction_core::{ ring_ct::SignatureRctBulletproofs, ring_signature::RingMLSAG, CompressedCommitment, }; -use protobuf::RepeatedField; impl From<&SignatureRctBulletproofs> for external::SignatureRctBulletproofs { fn from(source: &SignatureRctBulletproofs) -> Self { - let mut signature = external::SignatureRctBulletproofs::new(); - - let ring_signatures: Vec = source + let ring_signatures: Vec = source .ring_signatures .iter() - .map(external::RingMLSAG::from) + .map(external::RingMlsag::from) .collect(); - signature.set_ring_signatures(ring_signatures.into()); let pseudo_output_commitments: Vec = source .pseudo_output_commitments .iter() .map(external::CompressedRistretto::from) .collect(); - signature.set_pseudo_output_commitments(pseudo_output_commitments.into()); - - signature.set_range_proof_bytes(source.range_proof_bytes.clone()); - signature.set_range_proofs(RepeatedField::from_vec(source.range_proofs.clone())); - signature.set_pseudo_output_token_ids(source.pseudo_output_token_ids.clone()); - signature.set_output_token_ids(source.output_token_ids.clone()); - - signature + Self { + ring_signatures, + pseudo_output_commitments, + range_proof_bytes: source.range_proof_bytes.clone(), + range_proofs: source.range_proofs.clone(), + pseudo_output_token_ids: source.pseudo_output_token_ids.clone(), + output_token_ids: source.output_token_ids.clone(), + } } } @@ -39,29 +35,24 @@ impl TryFrom<&external::SignatureRctBulletproofs> for SignatureRctBulletproofs { type Error = ConversionError; fn try_from(source: &external::SignatureRctBulletproofs) -> Result { - let mut ring_signatures: Vec = Vec::new(); - for ring_signature in source.get_ring_signatures() { - ring_signatures.push(RingMLSAG::try_from(ring_signature)?); - } - - let mut pseudo_output_commitments: Vec = Vec::new(); - for pseudo_output_commitment in source.get_pseudo_output_commitments() { - pseudo_output_commitments - .push(CompressedCommitment::try_from(pseudo_output_commitment)?); - } - - let range_proof_bytes = source.get_range_proof_bytes().to_vec(); - let range_proofs = source.get_range_proofs().to_vec(); - let pseudo_output_token_ids = source.get_pseudo_output_token_ids().to_vec(); - let output_token_ids = source.get_output_token_ids().to_vec(); + let ring_signatures = source + .ring_signatures + .iter() + .map(RingMLSAG::try_from) + .collect::, _>>()?; + let pseudo_output_commitments = source + .pseudo_output_commitments + .iter() + .map(CompressedCommitment::try_from) + .collect::, _>>()?; Ok(SignatureRctBulletproofs { ring_signatures, pseudo_output_commitments, - range_proof_bytes, - range_proofs, - pseudo_output_token_ids, - output_token_ids, + range_proof_bytes: source.range_proof_bytes.clone(), + range_proofs: source.range_proofs.clone(), + pseudo_output_token_ids: source.pseudo_output_token_ids.clone(), + output_token_ids: source.output_token_ids.clone(), }) } } diff --git a/api/src/convert/signed_contingent_input.rs b/api/src/convert/signed_contingent_input.rs index cbfc075bd5..99a75ce450 100644 --- a/api/src/convert/signed_contingent_input.rs +++ b/api/src/convert/signed_contingent_input.rs @@ -3,27 +3,25 @@ //! Convert to/from external::SignedContingentInput. use crate::{external, ConversionError}; -use mc_transaction_core::{ring_signature::RingMLSAG, tx::TxIn, UnmaskedAmount}; +use mc_transaction_core::UnmaskedAmount; use mc_transaction_extra::SignedContingentInput; /// Convert mc_transaction_extra::SignedContingentInput --> /// external::SignedContingentInput. impl From<&SignedContingentInput> for external::SignedContingentInput { fn from(src: &SignedContingentInput) -> Self { - let mut sci = external::SignedContingentInput::new(); - sci.set_block_version(src.block_version); - sci.set_tx_in(external::TxIn::from(&src.tx_in)); - sci.set_mlsag(external::RingMLSAG::from(&src.mlsag)); - sci.set_pseudo_output_amount(external::UnmaskedAmount::from(&src.pseudo_output_amount)); - sci.set_required_output_amounts( - src.required_output_amounts + Self { + block_version: src.block_version, + tx_in: Some((&src.tx_in).into()), + mlsag: Some((&src.mlsag).into()), + pseudo_output_amount: Some((&src.pseudo_output_amount).into()), + required_output_amounts: src + .required_output_amounts .iter() .map(external::UnmaskedAmount::from) .collect(), - ); - sci.set_tx_out_global_indices(src.tx_out_global_indices.clone()); - - sci + tx_out_global_indices: src.tx_out_global_indices.clone(), + } } } @@ -33,24 +31,34 @@ impl TryFrom<&external::SignedContingentInput> for SignedContingentInput { type Error = ConversionError; fn try_from(src: &external::SignedContingentInput) -> Result { - let block_version = src.get_block_version(); - let tx_in = TxIn::try_from(src.get_tx_in())?; - let mlsag = RingMLSAG::try_from(src.get_mlsag())?; - let pseudo_output_amount = UnmaskedAmount::try_from(src.get_pseudo_output_amount())?; + let tx_in = src + .tx_in + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let mlsag = src + .mlsag + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let pseudo_output_amount = src + .pseudo_output_amount + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; let required_output_amounts = src - .get_required_output_amounts() + .required_output_amounts .iter() .map(UnmaskedAmount::try_from) .collect::, _>>()?; - let tx_out_global_indices = src.get_tx_out_global_indices().to_vec(); Ok(SignedContingentInput { - block_version, + block_version: src.block_version, tx_in, mlsag, pseudo_output_amount, required_output_amounts, - tx_out_global_indices, + tx_out_global_indices: src.tx_out_global_indices.clone(), }) } } @@ -68,7 +76,7 @@ mod tests { use mc_transaction_core::{ constants::MILLIMOB_TO_PICOMOB, tokens::Mob, Amount, BlockVersion, Token, TokenId, }; - use protobuf::Message; + use prost::Message; use rand::{rngs::StdRng, SeedableRng}; #[test] @@ -141,14 +149,14 @@ mod tests { // Encoding with prost, decoding with protobuf should be the identity function. { let bytes = mc_util_serial::encode(&sci); - let recovered_sci = external::SignedContingentInput::parse_from_bytes(&bytes).unwrap(); + let recovered_sci = external::SignedContingentInput::decode(bytes.as_slice()).unwrap(); assert_eq!(recovered_sci, external::SignedContingentInput::from(&sci)); } // Encoding with protobuf, decoding with prost should be the identity function. { let external_sci = external::SignedContingentInput::from(&sci); - let bytes = external_sci.write_to_bytes().unwrap(); + let bytes = external_sci.encode_to_vec(); let recovered_sci = mc_util_serial::decode(&bytes).unwrap(); assert_eq!(sci, recovered_sci); } diff --git a/api/src/convert/signing_data.rs b/api/src/convert/signing_data.rs index 7646df486a..320b9b8c4c 100644 --- a/api/src/convert/signing_data.rs +++ b/api/src/convert/signing_data.rs @@ -7,25 +7,19 @@ use mc_transaction_core::ring_ct::SigningData; impl From<&SigningData> for external::SigningData { fn from(src: &SigningData) -> Self { - let mut signing_data = external::SigningData::new(); - signing_data.set_mlsag_signing_digest(src.mlsag_signing_digest.clone()); - signing_data.set_pseudo_output_blindings( - src.pseudo_output_blindings - .iter() - .map(|blinding| blinding.into()) - .collect(), - ); - signing_data.set_pseudo_output_commitments( - src.pseudo_output_commitments + Self { + mlsag_signing_digest: src.mlsag_signing_digest.clone(), + pseudo_output_blindings: src.pseudo_output_blindings.iter().map(Into::into).collect(), + pseudo_output_commitments: src + .pseudo_output_commitments .iter() - .map(|commitment| commitment.into()) + .map(Into::into) .collect(), - ); - signing_data.set_range_proof_bytes(src.range_proof_bytes.clone()); - signing_data.set_range_proofs(protobuf::RepeatedField::from_vec(src.range_proofs.clone())); - signing_data.set_pseudo_output_token_ids(src.pseudo_output_token_ids.clone()); - signing_data.set_output_token_ids(src.output_token_ids.clone()); - signing_data + range_proof_bytes: src.range_proof_bytes.clone(), + pseudo_output_token_ids: src.pseudo_output_token_ids.clone(), + output_token_ids: src.output_token_ids.clone(), + range_proofs: src.range_proofs.clone(), + } } } diff --git a/api/src/convert/tx.rs b/api/src/convert/tx.rs index e674d9e2c0..82eb6de91a 100644 --- a/api/src/convert/tx.rs +++ b/api/src/convert/tx.rs @@ -3,16 +3,16 @@ //! Convert to/from external::Tx. use crate::{external, ConversionError}; -use mc_transaction_core::{ring_ct::SignatureRctBulletproofs, tx}; +use mc_transaction_core::tx; /// Convert mc_transaction_core::tx::Tx --> external::Tx. impl From<&tx::Tx> for external::Tx { fn from(source: &tx::Tx) -> Self { - let mut tx = external::Tx::new(); - tx.set_prefix(external::TxPrefix::from(&source.prefix)); - tx.set_signature(external::SignatureRctBulletproofs::from(&source.signature)); - tx.set_fee_map_digest(source.fee_map_digest.clone()); - tx + Self { + prefix: Some((&source.prefix).into()), + signature: Some((&source.signature).into()), + fee_map_digest: source.fee_map_digest.clone(), + } } } @@ -21,13 +21,20 @@ impl TryFrom<&external::Tx> for tx::Tx { type Error = ConversionError; fn try_from(source: &external::Tx) -> Result { - let prefix = tx::TxPrefix::try_from(source.get_prefix())?; - let signature = SignatureRctBulletproofs::try_from(source.get_signature())?; - let fee_map_digest = source.get_fee_map_digest().to_vec(); + let prefix = source + .prefix + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let signature = source + .signature + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; Ok(tx::Tx { prefix, signature, - fee_map_digest, + fee_map_digest: source.fee_map_digest.clone(), }) } } @@ -45,7 +52,7 @@ mod tests { use mc_transaction_core::{ constants::MILLIMOB_TO_PICOMOB, tokens::Mob, tx::Tx, Amount, BlockVersion, Token, TokenId, }; - use protobuf::Message; + use prost::Message; use rand::{rngs::StdRng, SeedableRng}; #[test] @@ -108,14 +115,14 @@ mod tests { // Encoding with prost, decoding with protobuf should be the identity function. { let bytes = mc_util_serial::encode(&tx); - let recovered_tx = external::Tx::parse_from_bytes(&bytes).unwrap(); + let recovered_tx = external::Tx::decode(bytes.as_slice()).unwrap(); assert_eq!(recovered_tx, external::Tx::from(&tx)); } // Encoding with protobuf, decoding with prost should be the identity function. { let external_tx: external::Tx = external::Tx::from(&tx); - let bytes = external_tx.write_to_bytes().unwrap(); + let bytes = external_tx.encode_to_vec(); let recovered_tx: Tx = mc_util_serial::decode(&bytes).unwrap(); assert_eq!(tx, recovered_tx); } @@ -226,14 +233,14 @@ mod tests { // Encoding with prost, decoding with protobuf should be the identity function. { let bytes = mc_util_serial::encode(&tx); - let recovered_tx = external::Tx::parse_from_bytes(&bytes).unwrap(); + let recovered_tx = external::Tx::decode(bytes.as_slice()).unwrap(); assert_eq!(recovered_tx, external::Tx::from(&tx)); } // Encoding with protobuf, decoding with prost should be the identity function. { let external_tx: external::Tx = external::Tx::from(&tx); - let bytes = external_tx.write_to_bytes().unwrap(); + let bytes = external_tx.encode_to_vec(); let recovered_tx: Tx = mc_util_serial::decode(&bytes).unwrap(); assert_eq!(tx, recovered_tx); } @@ -358,14 +365,14 @@ mod tests { // Encoding with prost, decoding with protobuf should be the identity function. { let bytes = mc_util_serial::encode(&tx); - let recovered_tx = external::Tx::parse_from_bytes(&bytes).unwrap(); + let recovered_tx = external::Tx::decode(bytes.as_slice()).unwrap(); assert_eq!(recovered_tx, external::Tx::from(&tx)); } // Encoding with protobuf, decoding with prost should be the identity function. { let external_tx: external::Tx = external::Tx::from(&tx); - let bytes = external_tx.write_to_bytes().unwrap(); + let bytes = external_tx.encode_to_vec(); let recovered_tx: Tx = mc_util_serial::decode(&bytes).unwrap(); assert_eq!(tx, recovered_tx); } diff --git a/api/src/convert/tx_hash.rs b/api/src/convert/tx_hash.rs index e56020a04c..edc6e1e18f 100644 --- a/api/src/convert/tx_hash.rs +++ b/api/src/convert/tx_hash.rs @@ -8,9 +8,9 @@ use mc_transaction_core::tx; /// Convert tx::TxHash --> external::TxHash. impl From<&tx::TxHash> for external::TxHash { fn from(other: &tx::TxHash) -> Self { - let mut tx_hash = external::TxHash::new(); - tx_hash.set_hash(other.to_vec()); - tx_hash + Self { + hash: other.to_vec(), + } } } @@ -19,8 +19,7 @@ impl TryFrom<&external::TxHash> for tx::TxHash { type Error = ConversionError; fn try_from(value: &external::TxHash) -> Result { - let hash_bytes: &[u8] = value.get_hash(); - tx::TxHash::try_from(hash_bytes).or(Err(ConversionError::ArrayCastError)) + tx::TxHash::try_from(value.hash.as_slice()).or(Err(ConversionError::ArrayCastError)) } } @@ -39,8 +38,9 @@ mod tests { #[test] // external::TxHash --> tx::TxHash fn test_tx_hash_try_from() { - let mut source = external::TxHash::new(); - source.set_hash(vec![7u8; 32]); + let source = external::TxHash { + hash: vec![7u8; 32], + }; let converted = tx::TxHash::try_from(&source).unwrap(); assert_eq!(converted.0, [7u8; 32]); } @@ -48,16 +48,16 @@ mod tests { #[test] // Unmarshalling too many bytes into a TxHash should produce an error. fn test_tx_hash_try_from_too_many_bytes() { - let mut source = external::TxHash::new(); - source.set_hash(vec![7u8; 99]); // Too many bytes. + let source = external::TxHash { + hash: vec![7u8; 99], + }; assert!(tx::TxHash::try_from(&source).is_err()); } #[test] // Unmarshalling too few bytes into a TxHash should produce an error. fn test_tx_hash_try_from_too_few_bytes() { - let mut source = external::TxHash::new(); - source.set_hash(vec![7u8; 3]); // Too few bytes. + let source = external::TxHash { hash: vec![7u8; 3] }; assert!(tx::TxHash::try_from(&source).is_err()); } } diff --git a/api/src/convert/tx_in.rs b/api/src/convert/tx_in.rs index a9099f352b..0393affed3 100644 --- a/api/src/convert/tx_in.rs +++ b/api/src/convert/tx_in.rs @@ -3,28 +3,16 @@ //! Convert to/from external::TxIn. use crate::{external, ConversionError}; -use mc_transaction_core::{tx, tx::TxOutMembershipProof, InputRules, RevealedTxOut}; +use mc_transaction_core::{tx, InputRules, RevealedTxOut}; /// Convert tx::TxIn --> external::TxIn. impl From<&tx::TxIn> for external::TxIn { fn from(source: &tx::TxIn) -> Self { - let mut tx_in = external::TxIn::new(); - - let ring: Vec = source.ring.iter().map(external::TxOut::from).collect(); - tx_in.set_ring(ring.into()); - - let proofs: Vec = source - .proofs - .iter() - .map(external::TxOutMembershipProof::from) - .collect(); - tx_in.set_proofs(proofs.into()); - - if let Some(input_rules) = source.input_rules.as_ref() { - tx_in.set_input_rules(input_rules.into()); + Self { + ring: source.ring.iter().map(Into::into).collect(), + proofs: source.proofs.iter().map(Into::into).collect(), + input_rules: source.input_rules.as_ref().map(Into::into), } - - tx_in } } @@ -33,18 +21,16 @@ impl TryFrom<&external::TxIn> for tx::TxIn { type Error = ConversionError; fn try_from(source: &external::TxIn) -> Result { - let mut ring: Vec = Vec::new(); - for out in source.get_ring() { - let tx_out = tx::TxOut::try_from(out)?; - ring.push(tx_out); - } - - let mut proofs: Vec = Vec::new(); - for proof in source.get_proofs() { - let tx_proof = TxOutMembershipProof::try_from(proof)?; - proofs.push(tx_proof); - } - + let ring = source + .ring + .iter() + .map(TryFrom::try_from) + .collect::, _>>()?; + let proofs = source + .proofs + .iter() + .map(TryFrom::try_from) + .collect::, _>>()?; let input_rules = source .input_rules .as_ref() @@ -63,31 +49,13 @@ impl TryFrom<&external::TxIn> for tx::TxIn { /// Convert InputRules --> external::InputRules. impl From<&InputRules> for external::InputRules { fn from(source: &InputRules) -> Self { - let mut input_rules = external::InputRules::new(); - - let required_outputs = source - .required_outputs - .iter() - .map(external::TxOut::from) - .collect(); - input_rules.set_required_outputs(required_outputs); - - input_rules.set_max_tombstone_block(source.max_tombstone_block); - - let partial_fill_outputs = source - .partial_fill_outputs - .iter() - .map(external::RevealedTxOut::from) - .collect(); - input_rules.set_partial_fill_outputs(partial_fill_outputs); - - if let Some(partial_fill_change) = source.partial_fill_change.as_ref() { - input_rules.set_partial_fill_change(partial_fill_change.into()); + Self { + required_outputs: source.required_outputs.iter().map(Into::into).collect(), + max_tombstone_block: source.max_tombstone_block, + partial_fill_outputs: source.partial_fill_outputs.iter().map(Into::into).collect(), + partial_fill_change: source.partial_fill_change.as_ref().map(Into::into), + min_partial_fill_value: source.min_partial_fill_value, } - - input_rules.set_min_partial_fill_value(source.min_partial_fill_value); - - input_rules } } @@ -97,7 +65,7 @@ impl TryFrom<&external::InputRules> for InputRules { fn try_from(source: &external::InputRules) -> Result { let required_outputs = source - .get_required_outputs() + .required_outputs .iter() .map(tx::TxOut::try_from) .collect::, _>>()?; @@ -126,10 +94,10 @@ impl TryFrom<&external::InputRules> for InputRules { /// Convert RevealedTxOut --> external::RevealedTxOut. impl From<&RevealedTxOut> for external::RevealedTxOut { fn from(source: &RevealedTxOut) -> Self { - let mut result = external::RevealedTxOut::new(); - result.set_tx_out(external::TxOut::from(&source.tx_out)); - result.set_amount_shared_secret(source.amount_shared_secret.to_vec()); - result + Self { + tx_out: Some((&source.tx_out).into()), + amount_shared_secret: source.amount_shared_secret.clone(), + } } } @@ -140,7 +108,7 @@ impl TryFrom<&external::RevealedTxOut> for RevealedTxOut { fn try_from(source: &external::RevealedTxOut) -> Result { let tx_out = tx::TxOut::try_from(source.tx_out.as_ref().ok_or(Self::Error::ObjectMissing)?)?; - let amount_shared_secret = source.get_amount_shared_secret().to_vec(); + let amount_shared_secret = source.amount_shared_secret.clone(); if amount_shared_secret.len() != 32 { return Err(ConversionError::ArrayCastError); } diff --git a/api/src/convert/tx_out.rs b/api/src/convert/tx_out.rs index 25ed03ee87..83162052c9 100644 --- a/api/src/convert/tx_out.rs +++ b/api/src/convert/tx_out.rs @@ -9,26 +9,17 @@ use mc_transaction_core::{encrypted_fog_hint::EncryptedFogHint, tx, EncryptedMem /// Convert tx::TxOut --> external::TxOut. impl From<&tx::TxOut> for external::TxOut { fn from(source: &tx::TxOut) -> Self { - let mut tx_out = external::TxOut::new(); - - tx_out.masked_amount = source.masked_amount.as_ref().map(Into::into); - - let target_key_bytes = source.target_key.as_bytes().to_vec(); - tx_out.mut_target_key().set_data(target_key_bytes); - - let public_key_bytes = source.public_key.as_bytes().to_vec(); - tx_out.mut_public_key().set_data(public_key_bytes); - - let hint_bytes = source.e_fog_hint.as_ref().to_vec(); - tx_out.mut_e_fog_hint().set_data(hint_bytes); - - if let Some(ref memo) = source.e_memo { - tx_out - .mut_e_memo() - .set_data(AsRef::<[u8]>::as_ref(memo).to_vec()); + Self { + target_key: Some((&source.target_key).into()), + public_key: Some((&source.public_key).into()), + e_fog_hint: Some(external::EncryptedFogHint { + data: source.e_fog_hint.as_ref().to_vec(), + }), + e_memo: source.e_memo.as_ref().map(|m| external::EncryptedMemo { + data: AsRef::<[u8]>::as_ref(m).to_vec(), + }), + masked_amount: source.masked_amount.as_ref().map(Into::into), } - - tx_out } } @@ -43,28 +34,46 @@ impl TryFrom<&external::TxOut> for tx::TxOut { .ok_or(ConversionError::ObjectMissing)?; let masked_amount = Some(MaskedAmount::try_from(oneof_masked_amount)?); - let target_key_bytes: &[u8] = source.get_target_key().get_data(); - let target_key: CompressedRistrettoPublic = RistrettoPublic::try_from(target_key_bytes) - .map_err(|_| ConversionError::KeyCastError)? - .into(); - - let public_key_bytes: &[u8] = source.get_public_key().get_data(); - let public_key: CompressedRistrettoPublic = RistrettoPublic::try_from(public_key_bytes) - .map_err(|_| ConversionError::KeyCastError)? - .into(); - - let e_fog_hint = EncryptedFogHint::try_from(source.get_e_fog_hint().get_data()) - .map_err(|_| ConversionError::ArrayCastError)?; - - let e_memo_bytes = source.get_e_memo().get_data(); - let e_memo = if e_memo_bytes.is_empty() { - None - } else { - Some( - EncryptedMemo::try_from(e_memo_bytes) - .map_err(|_| ConversionError::ArrayCastError)?, - ) - }; + let target_key: CompressedRistrettoPublic = RistrettoPublic::try_from( + source + .target_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ) + .map_err(|_| ConversionError::KeyCastError)? + .into(); + + let public_key: CompressedRistrettoPublic = RistrettoPublic::try_from( + source + .public_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ) + .map_err(|_| ConversionError::KeyCastError)? + .into(); + + let e_fog_hint = EncryptedFogHint::try_from( + source + .e_fog_hint + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ) + .map_err(|_| ConversionError::ArrayCastError)?; + + let e_memo = source + .e_memo + .as_ref() + .map(|m| { + EncryptedMemo::try_from(m.data.as_slice()) + .map_err(|_| ConversionError::ArrayCastError) + }) + .transpose()?; let tx_out = tx::TxOut { masked_amount, diff --git a/api/src/convert/tx_out_confirmation_number.rs b/api/src/convert/tx_out_confirmation_number.rs index 72401fc434..9d7825b7b1 100644 --- a/api/src/convert/tx_out_confirmation_number.rs +++ b/api/src/convert/tx_out_confirmation_number.rs @@ -8,9 +8,7 @@ use mc_transaction_extra::TxOutConfirmationNumber; /// Convert TxOutConfirmationNumber --> external::TxOutConfirmationNumber. impl From<&TxOutConfirmationNumber> for external::TxOutConfirmationNumber { fn from(src: &TxOutConfirmationNumber) -> Self { - let mut tx_confirmation = external::TxOutConfirmationNumber::new(); - tx_confirmation.set_hash(src.to_vec()); - tx_confirmation + Self { hash: src.to_vec() } } } @@ -19,7 +17,7 @@ impl TryFrom<&external::TxOutConfirmationNumber> for TxOutConfirmationNumber { type Error = ConversionError; fn try_from(src: &external::TxOutConfirmationNumber) -> Result { - let bytes: &[u8] = src.get_hash(); + let bytes: &[u8] = src.hash.as_slice(); let mut hash = [0u8; 32]; if bytes.len() != hash.len() { return Err(ConversionError::ArrayCastError); @@ -44,8 +42,9 @@ mod tests { #[test] // external::TxOutConfirmationNumber --> TxOutConfirmationNumber fn test_confirmation_number_try_from() { - let mut source = external::TxOutConfirmationNumber::new(); - source.set_hash(vec![7u8; 32]); + let source = external::TxOutConfirmationNumber { + hash: vec![7u8; 32], + }; let converted = TxOutConfirmationNumber::try_from(&source).unwrap(); assert_eq!(*converted.as_ref(), [7u8; 32]); } @@ -54,8 +53,9 @@ mod tests { // Unmarshalling too many bytes into a TxOutConfirmationNumber should produce an // error. fn test_confirmation_number_try_from_too_many_bytes() { - let mut source = external::TxOutConfirmationNumber::new(); - source.set_hash(vec![7u8; 99]); // Too many bytes. + let source = external::TxOutConfirmationNumber { + hash: vec![7u8; 99], + }; assert!(TxOutConfirmationNumber::try_from(&source).is_err()); } @@ -63,8 +63,7 @@ mod tests { // Unmarshalling too few bytes into a TxOutConfirmationNumber should produce an // error. fn test_confirmation_number_try_from_too_few_bytes() { - let mut source = external::TxOutConfirmationNumber::new(); - source.set_hash(vec![7u8; 3]); // Too few bytes. + let source = external::TxOutConfirmationNumber { hash: vec![7u8; 3] }; assert!(TxOutConfirmationNumber::try_from(&source).is_err()); } } diff --git a/api/src/convert/tx_out_gift_code.rs b/api/src/convert/tx_out_gift_code.rs index 5c9a4dc689..bef977493d 100644 --- a/api/src/convert/tx_out_gift_code.rs +++ b/api/src/convert/tx_out_gift_code.rs @@ -2,20 +2,17 @@ //! Convert to/from printable::TxOutGiftCode -use crate::{external, printable, ConversionError}; -use mc_crypto_keys::{CompressedRistrettoPublic, RistrettoPrivate, RistrettoPublic}; +use crate::{printable, ConversionError}; use mc_transaction_extra::TxOutGiftCode; /// Convert TxOutGiftCode --> printable::TxOutGiftCode. impl From<&TxOutGiftCode> for printable::TxOutGiftCode { fn from(src: &TxOutGiftCode) -> Self { - let mut tx_out_gift_code = printable::TxOutGiftCode::new(); - tx_out_gift_code.set_global_index(src.global_index); - tx_out_gift_code - .set_onetime_private_key(external::RistrettoPrivate::from(&src.onetime_private_key)); - tx_out_gift_code.set_shared_secret(external::CompressedRistretto::from(&src.shared_secret)); - - tx_out_gift_code + Self { + global_index: src.global_index, + onetime_private_key: Some((&src.onetime_private_key).into()), + shared_secret: Some((&src.shared_secret).into()), + } } } @@ -24,14 +21,19 @@ impl TryFrom<&printable::TxOutGiftCode> for TxOutGiftCode { type Error = ConversionError; fn try_from(src: &printable::TxOutGiftCode) -> Result { - let global_index = src.get_global_index(); - let onetime_private_key = RistrettoPrivate::try_from(src.get_onetime_private_key())?; - let compressed_shared_secret = - CompressedRistrettoPublic::try_from(src.get_shared_secret())?; - let shared_secret = RistrettoPublic::try_from(&compressed_shared_secret)?; + let onetime_private_key = src + .onetime_private_key + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let shared_secret = src + .shared_secret + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; Ok(Self { - global_index, + global_index: src.global_index, onetime_private_key, shared_secret, }) @@ -41,9 +43,10 @@ impl TryFrom<&printable::TxOutGiftCode> for TxOutGiftCode { #[cfg(test)] mod tests { use super::*; + use mc_crypto_keys::{RistrettoPrivate, RistrettoPublic}; use mc_util_from_random::FromRandom; use mc_util_serial::{decode, encode}; - use protobuf::Message; + use prost::Message; use rand::rngs::StdRng; use rand_core::SeedableRng; @@ -75,14 +78,14 @@ mod tests { // Encoding with prost, decoding with protobuf should produce the same object { let bytes = encode(&source); - let recovered = printable::TxOutGiftCode::parse_from_bytes(&bytes).unwrap(); + let recovered = printable::TxOutGiftCode::decode(bytes.as_slice()).unwrap(); assert_eq!(recovered, printable::TxOutGiftCode::from(&source)); } // Encoding with protobuf, decoding with prost should produce the same object { let external = printable::TxOutGiftCode::from(&source); - let bytes = external.write_to_bytes().unwrap(); + let bytes = external.encode_to_vec(); let recovered: TxOutGiftCode = decode(&bytes).unwrap(); assert_eq!(source, recovered); } diff --git a/api/src/convert/tx_out_membership_element.rs b/api/src/convert/tx_out_membership_element.rs index 26a0dcfc49..403442747f 100644 --- a/api/src/convert/tx_out_membership_element.rs +++ b/api/src/convert/tx_out_membership_element.rs @@ -11,11 +11,15 @@ use mc_transaction_core::{ /// Convert TxOutMembershipElement -> external::TxOutMembershipElement impl From<&TxOutMembershipElement> for external::TxOutMembershipElement { fn from(src: &TxOutMembershipElement) -> Self { - let mut dst = external::TxOutMembershipElement::new(); - dst.mut_range().set_from(src.range.from); - dst.mut_range().set_to(src.range.to); - dst.mut_hash().set_data(src.hash.to_vec()); - dst + Self { + range: Some(external::Range { + from: src.range.from, + to: src.range.to, + }), + hash: Some(external::TxOutMembershipHash { + data: src.hash.to_vec(), + }), + } } } @@ -24,10 +28,18 @@ impl TryFrom<&external::TxOutMembershipElement> for TxOutMembershipElement { type Error = ConversionError; fn try_from(src: &external::TxOutMembershipElement) -> Result { - let range = Range::new(src.get_range().get_from(), src.get_range().get_to()) - .map_err(|_e| ConversionError::Other)?; + let default_range = Default::default(); + let src_range = src.range.as_ref().unwrap_or(&default_range); + let range = + Range::new(src_range.from, src_range.to).map_err(|_e| ConversionError::Other)?; - let bytes: &[u8] = src.get_hash().get_data(); + let default_membership_hash = Default::default(); + let bytes: &[u8] = src + .hash + .as_ref() + .unwrap_or(&default_membership_hash) + .data + .as_slice(); let mut hash = [0u8; 32]; if bytes.len() != hash.len() { return Err(ConversionError::ArrayCastError); diff --git a/api/src/convert/tx_out_membership_proof.rs b/api/src/convert/tx_out_membership_proof.rs index b5344b9bb0..ad0f74d640 100644 --- a/api/src/convert/tx_out_membership_proof.rs +++ b/api/src/convert/tx_out_membership_proof.rs @@ -3,27 +3,20 @@ //! Convert to/from external::TxOutMembershipProof use crate::{external, ConversionError}; -use mc_transaction_core::{ - membership_proofs::Range, - tx::{TxOutMembershipElement, TxOutMembershipProof}, -}; -use protobuf::RepeatedField; +use mc_transaction_core::tx::{TxOutMembershipElement, TxOutMembershipProof}; /// Convert TxOutMembershipProof -> external::MembershipProof. impl From<&TxOutMembershipProof> for external::TxOutMembershipProof { fn from(tx_out_membership_proof: &TxOutMembershipProof) -> Self { - let mut membership_proof = external::TxOutMembershipProof::new(); - membership_proof.set_index(tx_out_membership_proof.index); - membership_proof.set_highest_index(tx_out_membership_proof.highest_index); - - let elements: Vec = tx_out_membership_proof - .elements - .iter() - .map(external::TxOutMembershipElement::from) - .collect(); - - membership_proof.set_elements(RepeatedField::from_vec(elements)); - membership_proof + Self { + index: tx_out_membership_proof.index, + highest_index: tx_out_membership_proof.highest_index, + elements: tx_out_membership_proof + .elements + .iter() + .map(Into::into) + .collect(), + } } } @@ -32,22 +25,14 @@ impl TryFrom<&external::TxOutMembershipProof> for TxOutMembershipProof { type Error = ConversionError; fn try_from(membership_proof: &external::TxOutMembershipProof) -> Result { - let index: u64 = membership_proof.get_index(); - let highest_index: u64 = membership_proof.get_highest_index(); + let index: u64 = membership_proof.index; + let highest_index: u64 = membership_proof.highest_index; - let mut elements = Vec::::default(); - for element in membership_proof.get_elements() { - let range = Range::new(element.get_range().get_from(), element.get_range().get_to()) - .map_err(|_e| ConversionError::Other)?; - - let bytes: &[u8] = element.get_hash().get_data(); - let mut hash = [0u8; 32]; - if bytes.len() != hash.len() { - return Err(ConversionError::ArrayCastError); - } - hash.copy_from_slice(bytes); - elements.push(TxOutMembershipElement::new(range, hash)); - } + let elements = membership_proof + .elements + .iter() + .map(TxOutMembershipElement::try_from) + .collect::, _>>()?; let tx_out_membership_proof = TxOutMembershipProof::new(index, highest_index, elements); Ok(tx_out_membership_proof) } @@ -56,6 +41,7 @@ impl TryFrom<&external::TxOutMembershipProof> for TxOutMembershipProof { #[cfg(test)] mod tests { use super::*; + use mc_transaction_core::membership_proofs::Range; #[test] /// Convert TxOutMembershipProof -> external::TxOutMembershipProof. @@ -72,18 +58,21 @@ mod tests { TxOutMembershipProof::new(index, highest_index, hashes.clone()); let membership_proof = external::TxOutMembershipProof::from(&tx_out_membership_proof); - assert_eq!(membership_proof.get_index(), index); - assert_eq!(membership_proof.get_highest_index(), highest_index); + assert_eq!(membership_proof.index, index); + assert_eq!(membership_proof.highest_index, highest_index); - let elements = membership_proof.get_elements(); + let elements = membership_proof.elements; assert_eq!(elements.len(), hashes.len()); for (idx, element) in elements.iter().enumerate() { - let range = - Range::new(element.get_range().get_from(), element.get_range().get_to()).unwrap(); + let range = Range::new( + element.range.as_ref().unwrap().from, + element.range.as_ref().unwrap().to, + ) + .unwrap(); assert_eq!(range, hashes.get(idx).unwrap().range); let expected_hash = &hashes.get(idx).unwrap().hash; - let bytes = element.get_hash().get_data(); + let bytes = element.hash.as_ref().unwrap().data.as_slice(); assert_eq!(bytes.len(), expected_hash.as_ref().len()); assert_eq!(bytes, expected_hash.as_ref()); } diff --git a/api/src/convert/tx_prefix.rs b/api/src/convert/tx_prefix.rs index 75db7d014f..bfd7ac10f3 100644 --- a/api/src/convert/tx_prefix.rs +++ b/api/src/convert/tx_prefix.rs @@ -8,22 +8,13 @@ use mc_transaction_core::tx; /// Convert tx::TxPrefix --> external::TxPrefix. impl From<&tx::TxPrefix> for external::TxPrefix { fn from(source: &tx::TxPrefix) -> Self { - let mut tx_prefix = external::TxPrefix::new(); - - let inputs: Vec = source.inputs.iter().map(external::TxIn::from).collect(); - tx_prefix.set_inputs(inputs.into()); - - let outputs: Vec = - source.outputs.iter().map(external::TxOut::from).collect(); - tx_prefix.set_outputs(outputs.into()); - - tx_prefix.set_fee(source.fee); - - tx_prefix.set_fee_token_id(source.fee_token_id); - - tx_prefix.set_tombstone_block(source.tombstone_block); - - tx_prefix + Self { + inputs: source.inputs.iter().map(Into::into).collect(), + outputs: source.outputs.iter().map(Into::into).collect(), + fee: source.fee, + fee_token_id: source.fee_token_id, + tombstone_block: source.tombstone_block, + } } } @@ -32,24 +23,23 @@ impl TryFrom<&external::TxPrefix> for tx::TxPrefix { type Error = ConversionError; fn try_from(source: &external::TxPrefix) -> Result { - let mut inputs: Vec = Vec::new(); - for out in source.get_inputs() { - let tx_out = tx::TxIn::try_from(out)?; - inputs.push(tx_out); - } - - let mut outputs: Vec = Vec::new(); - for out in source.get_outputs() { - let tx_out = tx::TxOut::try_from(out)?; - outputs.push(tx_out); - } + let inputs = source + .inputs + .iter() + .map(TryFrom::try_from) + .collect::, _>>()?; + let outputs = source + .outputs + .iter() + .map(TryFrom::try_from) + .collect::, _>>()?; let tx_prefix = tx::TxPrefix { inputs, outputs, - fee: source.get_fee(), - fee_token_id: source.get_fee_token_id(), - tombstone_block: source.get_tombstone_block(), + fee: source.fee, + fee_token_id: source.fee_token_id, + tombstone_block: source.tombstone_block, }; Ok(tx_prefix) } diff --git a/api/src/convert/unsigned_tx.rs b/api/src/convert/unsigned_tx.rs index 637bcdcce7..539273b6d4 100644 --- a/api/src/convert/unsigned_tx.rs +++ b/api/src/convert/unsigned_tx.rs @@ -10,20 +10,16 @@ use mc_transaction_summary::TxOutSummaryUnblindingData; impl From<&UnsignedTx> for external::UnsignedTx { fn from(source: &UnsignedTx) -> Self { - let mut unsigned_tx = external::UnsignedTx::new(); - unsigned_tx.set_tx_prefix((&source.tx_prefix).into()); - unsigned_tx.set_rings(protobuf::RepeatedField::from_vec( - source.rings.iter().map(|input| input.into()).collect(), - )); - unsigned_tx.set_tx_out_unblinding_data(protobuf::RepeatedField::from_vec( - source + Self { + tx_prefix: Some((&source.tx_prefix).into()), + rings: source.rings.iter().map(Into::into).collect(), + block_version: *source.block_version, + tx_out_unblinding_data: source .tx_out_unblinding_data .iter() .map(Into::into) .collect(), - )); - unsigned_tx.set_block_version(*source.block_version); - unsigned_tx + } } } @@ -31,10 +27,15 @@ impl TryFrom<&external::UnsignedTx> for UnsignedTx { type Error = ConversionError; fn try_from(source: &external::UnsignedTx) -> Result { + let tx_prefix = source + .tx_prefix + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; Ok(UnsignedTx { - tx_prefix: source.get_tx_prefix().try_into()?, + tx_prefix, rings: source - .get_rings() + .rings .iter() .map(|input| input.try_into()) .collect::>()?, @@ -43,22 +44,18 @@ impl TryFrom<&external::UnsignedTx> for UnsignedTx { .iter() .map(|data| data.try_into()) .collect::>()?, - block_version: BlockVersion::try_from(source.get_block_version())?, + block_version: BlockVersion::try_from(source.block_version)?, }) } } impl From<&TxOutSummaryUnblindingData> for external::TxOutSummaryUnblindingData { fn from(src: &TxOutSummaryUnblindingData) -> Self { - let mut data = external::TxOutSummaryUnblindingData::new(); - data.set_unmasked_amount((&src.unmasked_amount).into()); - if let Some(address) = &src.address { - data.set_address(address.into()); + Self { + unmasked_amount: Some((&src.unmasked_amount).into()), + address: src.address.as_ref().map(Into::into), + tx_private_key: src.tx_private_key.as_ref().map(Into::into), } - if let Some(tx_private_key) = &src.tx_private_key { - data.set_tx_private_key(tx_private_key.into()); - } - data } } @@ -84,11 +81,11 @@ impl TryFrom<&external::TxOutSummaryUnblindingData> for TxOutSummaryUnblindingDa impl From<&UnmaskedAmount> for external::UnmaskedAmount { fn from(src: &UnmaskedAmount) -> Self { - let mut data = external::UnmaskedAmount::new(); - data.set_value(src.value); - data.set_token_id(src.token_id); - data.set_blinding((&src.blinding).into()); - data + Self { + value: src.value, + token_id: src.token_id, + blinding: Some((&src.blinding).into()), + } } } @@ -96,10 +93,15 @@ impl TryFrom<&external::UnmaskedAmount> for UnmaskedAmount { type Error = ConversionError; fn try_from(source: &external::UnmaskedAmount) -> Result { + let blinding = source + .blinding + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; Ok(UnmaskedAmount { - value: source.get_value(), - token_id: source.get_token_id(), - blinding: source.get_blinding().try_into()?, + value: source.value, + token_id: source.token_id, + blinding, }) } } diff --git a/api/src/convert/validated_mint_config.rs b/api/src/convert/validated_mint_config.rs index 4bfa493523..612c196bf9 100644 --- a/api/src/convert/validated_mint_config.rs +++ b/api/src/convert/validated_mint_config.rs @@ -3,16 +3,15 @@ //! Convert between the Rust and Protobuf versions of [ValidatedMintConfigTx] use crate::{external, ConversionError}; -use mc_crypto_multisig::SignerSet; -use mc_transaction_core::mint::{MintConfigTx, ValidatedMintConfigTx}; +use mc_transaction_core::mint::ValidatedMintConfigTx; /// Convert ValidatedMintConfigTx --> external::ValidatedMintConfigTx. impl From<&ValidatedMintConfigTx> for external::ValidatedMintConfigTx { fn from(src: &ValidatedMintConfigTx) -> Self { - let mut dst = external::ValidatedMintConfigTx::new(); - dst.set_mint_config_tx((&src.mint_config_tx).into()); - dst.set_signer_set((&src.signer_set).into()); - dst + Self { + mint_config_tx: Some((&src.mint_config_tx).into()), + signer_set: Some((&src.signer_set).into()), + } } } @@ -21,8 +20,16 @@ impl TryFrom<&external::ValidatedMintConfigTx> for ValidatedMintConfigTx { type Error = ConversionError; fn try_from(source: &external::ValidatedMintConfigTx) -> Result { - let mint_config_tx = MintConfigTx::try_from(source.get_mint_config_tx())?; - let signer_set = SignerSet::try_from(source.get_signer_set())?; + let mint_config_tx = source + .mint_config_tx + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; + let signer_set = source + .signer_set + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?; Ok(Self { mint_config_tx, signer_set, @@ -34,9 +41,9 @@ impl TryFrom<&external::ValidatedMintConfigTx> for ValidatedMintConfigTx { mod tests { use super::*; use crate::convert::ed25519_multisig::tests::{test_multi_sig, test_signer_set}; - use mc_transaction_core::mint::{MintConfig, MintConfigTxPrefix}; + use mc_transaction_core::mint::{MintConfig, MintConfigTx, MintConfigTxPrefix}; use mc_util_serial::{decode, encode}; - use protobuf::Message; + use prost::Message; #[test] // ValidatedMintConfigTx -> external::ValidatedMintConfigTx -> @@ -87,14 +94,14 @@ mod tests { // function. { let bytes = encode(&source); - let recovered = external::ValidatedMintConfigTx::parse_from_bytes(&bytes).unwrap(); + let recovered = external::ValidatedMintConfigTx::decode(bytes.as_slice()).unwrap(); assert_eq!(recovered, external::ValidatedMintConfigTx::from(&source)); } // Encoding with protobuf, decoding with prost should be the identity function. { let external = external::ValidatedMintConfigTx::from(&source); - let bytes = external.write_to_bytes().unwrap(); + let bytes = external.encode_to_vec(); let recovered: ValidatedMintConfigTx = decode(&bytes).unwrap(); assert_eq!(source, recovered); } diff --git a/api/src/convert/verification_report.rs b/api/src/convert/verification_report.rs index e2761b64cb..5f8bc760f3 100644 --- a/api/src/convert/verification_report.rs +++ b/api/src/convert/verification_report.rs @@ -7,21 +7,20 @@ use mc_attest_verifier_types::VerificationReport; impl From<&VerificationReport> for external::VerificationReport { fn from(src: &VerificationReport) -> Self { - let mut dst = external::VerificationReport::new(); - - dst.set_sig((&src.sig).into()); - dst.set_chain(src.chain.as_slice().into()); - dst.set_http_body(src.http_body.clone()); - dst + Self { + sig: Some((&src.sig).into()), + chain: src.chain.as_slice().into(), + http_body: src.http_body.clone(), + } } } impl From<&external::VerificationReport> for VerificationReport { fn from(src: &external::VerificationReport) -> Self { VerificationReport { - sig: src.get_sig().into(), - chain: src.get_chain().to_vec(), - http_body: src.get_http_body().to_owned(), + sig: src.sig.as_ref().map(Into::into).unwrap_or_default(), + chain: src.chain.to_vec(), + http_body: src.http_body.clone(), } } } diff --git a/api/src/convert/verification_signature.rs b/api/src/convert/verification_signature.rs index e64287c3e5..7b9d9b1b59 100644 --- a/api/src/convert/verification_signature.rs +++ b/api/src/convert/verification_signature.rs @@ -7,15 +7,15 @@ use mc_attest_verifier_types::VerificationSignature; impl From<&VerificationSignature> for external::VerificationSignature { fn from(src: &VerificationSignature) -> Self { - let mut dst = external::VerificationSignature::new(); - dst.set_contents(src.clone().into()); - dst + Self { + contents: src.clone().into(), + } } } impl From<&external::VerificationSignature> for VerificationSignature { fn from(src: &external::VerificationSignature) -> Self { - src.get_contents().into() + src.contents.clone().into() } } diff --git a/api/src/display.rs b/api/src/display.rs index c0e051431d..58f61fff4d 100644 --- a/api/src/display.rs +++ b/api/src/display.rs @@ -6,7 +6,7 @@ use crate::printable; use crc::Crc; use displaydoc::Display; -use protobuf::Message; +use prost::Message; /// Decoding / encoding errors #[derive(Clone, Debug, Eq, PartialEq, Display)] @@ -43,9 +43,7 @@ fn calculate_checksum(data: &[u8]) -> [u8; 4] { impl printable::PrintableWrapper { /// Converts the proto to bytes and then encodes as b58 pub fn b58_encode(&self) -> Result { - let wrapper_bytes = self - .write_to_bytes() - .map_err(|err| Error::Serialization(err.to_string()))?; + let wrapper_bytes = self.encode_to_vec(); let mut bytes_vec = Vec::new(); bytes_vec.extend_from_slice(&calculate_checksum(&wrapper_bytes)); bytes_vec.extend_from_slice(&wrapper_bytes); @@ -65,7 +63,7 @@ impl printable::PrintableWrapper { if expected_checksum.to_vec() != decoded_bytes { return Err(Error::ChecksumMismatch); } - let wrapper = Self::parse_from_bytes(&wrapper_bytes) + let wrapper = Self::decode(wrapper_bytes.as_slice()) .map_err(|err| Error::Deserialization(err.to_string()))?; Ok(wrapper) } @@ -76,7 +74,7 @@ mod display_tests { use super::Error; use crate::{ external, - printable::{PaymentRequest, PrintableWrapper, TransferPayload}, + printable::{printable_wrapper, PaymentRequest, PrintableWrapper, TransferPayload}, }; use mc_test_vectors_b58_encodings::{ B58EncodePublicAddressWithFog, B58EncodePublicAddressWithoutFog, @@ -85,26 +83,25 @@ mod display_tests { use mc_util_test_with_data::test_with_data; fn sample_public_address() -> external::PublicAddress { - let mut public_address = external::PublicAddress::new(); - - let mut view_bytes = external::CompressedRistretto::new(); - view_bytes.set_data(vec![1u8; 32]); - public_address.set_view_public_key(view_bytes); - - let mut spend_bytes = external::CompressedRistretto::new(); - spend_bytes.set_data(vec![1u8; 32]); - public_address.set_spend_public_key(spend_bytes); - - public_address.set_fog_report_url("mob://fog.example.com".to_string()); - public_address + external::PublicAddress { + view_public_key: Some(external::CompressedRistretto { + data: vec![1u8; 32], + }), + spend_public_key: Some(external::CompressedRistretto { + data: vec![1u8; 32], + }), + fog_report_url: "mob://fog.example.com".to_string(), + ..Default::default() + } } #[test] fn test_public_address_roundtrip() { let public_address = sample_public_address(); - let mut wrapper = PrintableWrapper::new(); - wrapper.set_public_address(public_address); + let wrapper = PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress(public_address)), + }; let encoded = wrapper.b58_encode().unwrap(); let decoded = PrintableWrapper::b58_decode(encoded).unwrap(); assert_eq!(wrapper, decoded); @@ -113,20 +110,18 @@ mod display_tests { fn printable_wrapper_from_b58_encode_public_address_without_fog( case: &B58EncodePublicAddressWithoutFog, ) -> PrintableWrapper { - let mut public_address = external::PublicAddress::new(); - - let mut view_bytes = external::CompressedRistretto::new(); - view_bytes.set_data(case.view_public_key.to_vec()); - public_address.set_view_public_key(view_bytes); - - let mut spend_bytes = external::CompressedRistretto::new(); - spend_bytes.set_data(case.spend_public_key.to_vec()); - public_address.set_spend_public_key(spend_bytes); - - let mut wrapper = PrintableWrapper::new(); - wrapper.set_public_address(public_address); - - wrapper + let public_address = external::PublicAddress { + view_public_key: Some(external::CompressedRistretto { + data: case.view_public_key.to_vec(), + }), + spend_public_key: Some(external::CompressedRistretto { + data: case.spend_public_key.to_vec(), + }), + ..Default::default() + }; + PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress(public_address)), + } } #[test_with_data(B58EncodePublicAddressWithoutFog::from_jsonl("../test-vectors/vectors"))] @@ -145,24 +140,21 @@ mod display_tests { fn printable_wrapper_from_b58_encode_public_address_with_fog( case: &B58EncodePublicAddressWithFog, ) -> PrintableWrapper { - let mut public_address = external::PublicAddress::new(); - - let mut view_bytes = external::CompressedRistretto::new(); - view_bytes.set_data(case.view_public_key.to_vec()); - public_address.set_view_public_key(view_bytes); - - let mut spend_bytes = external::CompressedRistretto::new(); - spend_bytes.set_data(case.spend_public_key.to_vec()); - public_address.set_spend_public_key(spend_bytes); - - public_address.set_fog_report_url(case.fog_report_url.clone()); - public_address.set_fog_report_id(case.fog_report_id.clone()); - public_address.set_fog_authority_sig(case.fog_authority_sig.clone()); - - let mut wrapper = PrintableWrapper::new(); - wrapper.set_public_address(public_address); - - wrapper + let public_address = external::PublicAddress { + view_public_key: Some(external::CompressedRistretto { + data: case.view_public_key.to_vec(), + }), + spend_public_key: Some(external::CompressedRistretto { + data: case.spend_public_key.to_vec(), + }), + fog_report_url: case.fog_report_url.clone(), + fog_report_id: case.fog_report_id.clone(), + fog_authority_sig: case.fog_authority_sig.clone(), + }; + + PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress(public_address)), + } } #[test_with_data(B58EncodePublicAddressWithFog::from_jsonl("../test-vectors/vectors"))] @@ -182,13 +174,16 @@ mod display_tests { fn test_payment_request_roundtrip() { let public_address = sample_public_address(); - let mut payment_request = PaymentRequest::new(); - payment_request.set_public_address(public_address); - payment_request.set_value(10); - payment_request.set_memo("Please me pay!".to_string()); + let payment_request = PaymentRequest { + public_address: Some(public_address.clone()), + value: 10, + memo: "Please me pay!".to_string(), + ..Default::default() + }; - let mut wrapper = PrintableWrapper::new(); - wrapper.set_payment_request(payment_request); + let wrapper = PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PaymentRequest(payment_request)), + }; let encoded = wrapper.b58_encode().unwrap(); let decoded = PrintableWrapper::b58_decode(encoded).unwrap(); assert_eq!(wrapper, decoded); @@ -196,15 +191,21 @@ mod display_tests { #[test] fn test_transfer_payload_roundtrip() { - let mut transfer_payload = TransferPayload::new(); - transfer_payload.set_root_entropy(vec![1u8; 32]); - transfer_payload.set_bip39_entropy(vec![12u8; 32]); - transfer_payload - .mut_tx_out_public_key() - .set_data(vec![2u8; 32]); - - let mut wrapper = PrintableWrapper::new(); - wrapper.set_transfer_payload(transfer_payload); + #[allow(deprecated)] + let transfer_payload = TransferPayload { + root_entropy: vec![1u8; 32], + tx_out_public_key: Some(external::CompressedRistretto { + data: vec![2u8; 32], + }), + bip39_entropy: vec![12u8; 32], + ..Default::default() + }; + + let wrapper = PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::TransferPayload( + transfer_payload.clone(), + )), + }; let encoded = wrapper.b58_encode().unwrap(); let decoded = PrintableWrapper::b58_decode(encoded).unwrap(); assert_eq!(wrapper, decoded); @@ -214,8 +215,9 @@ mod display_tests { fn test_bad_checksum() { let public_address = sample_public_address(); - let mut wrapper = PrintableWrapper::new(); - wrapper.set_public_address(public_address); + let wrapper = PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress(public_address)), + }; let encoded = wrapper.b58_encode().unwrap(); // Change the checksum diff --git a/api/src/lib.rs b/api/src/lib.rs index 697c5f84f7..8d1bd06fcf 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -2,17 +2,7 @@ //! MobileCoin gRPC API. -// workaround for #![allow(box_pointers)] in protobuf generated files. -#![allow(renamed_and_removed_lints)] - mod autogenerated_code { - pub use protobuf::well_known_types::Empty; - - // Needed due to how to the auto-generated code references the Empty message. - pub mod empty { - pub use protobuf::well_known_types::Empty; - } - // Include the auto-generated code. include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/mod.rs")); } diff --git a/api/tests/tokens.rs b/api/tests/tokens.rs index f47e94840e..74d7924566 100644 --- a/api/tests/tokens.rs +++ b/api/tests/tokens.rs @@ -1,22 +1,15 @@ use mc_api::external::KnownTokenId; use mc_transaction_core::{tokens, Token}; -use protobuf::ProtobufEnum; -use std::collections::HashMap; // Test that protobuf KnownTokens enum matches the tokens in mc-transaction-core #[test] fn test_known_tokens_enum_vs_mc_transaction_core_tokens() { - // Collect known tokens from proto - let mut known_tokens = HashMap::::default(); - - let descriptor = KnownTokenId::enum_descriptor_static(); - for value in KnownTokenId::values() { - known_tokens.insert( - descriptor.value_by_number(value.value()).name().to_string(), - value.value(), - ); + let known_tokens = [KnownTokenId::Mob]; + for token in known_tokens.iter() { + match token { + KnownTokenId::Mob => { + assert_eq!(*token as u64, *tokens::Mob::ID); + } + } } - - assert_eq!(known_tokens.len(), 1); - assert_eq!(*known_tokens.get("MOB").unwrap() as u64, *tokens::Mob::ID); } diff --git a/attest/api/Cargo.toml b/attest/api/Cargo.toml index 6530b2944c..bd8f9c42e1 100644 --- a/attest/api/Cargo.toml +++ b/attest/api/Cargo.toml @@ -29,8 +29,8 @@ mc-util-serial = { path = "../../util/serial" } aead = "0.5" digest = "0.10" futures = "0.3" -grpcio = "0.13" -protobuf = "2.27.1" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } +prost = { version = "0.11", default-features = false } [dev-dependencies] assert_matches = "1.5.0" diff --git a/attest/api/src/convert.rs b/attest/api/src/convert.rs index e20ef0128a..c2eb53b520 100644 --- a/attest/api/src/convert.rs +++ b/attest/api/src/convert.rs @@ -20,16 +20,13 @@ where DigestAlgo: NoiseDigest, { fn from(src: AuthRequestOutput) -> Self { - let mut retval = Self::default(); - retval.set_data(src.into()); - retval + Self { data: src.into() } } } impl From for AuthResponseOutput { fn from(src: AuthMessage) -> AuthResponseOutput { - let mut taken_self = src; - AuthResponseOutput::from(taken_self.take_data()) + src.data.into() } } @@ -41,9 +38,7 @@ impl From for PeerAuthRequest { impl From for AuthMessage { fn from(src: PeerAuthRequest) -> AuthMessage { - let mut retval = AuthMessage::default(); - retval.set_data(src.into()); - retval + Self { data: src.into() } } } @@ -55,9 +50,7 @@ impl From for ClientAuthRequest { impl From for AuthMessage { fn from(src: ClientAuthRequest) -> AuthMessage { - let mut retval = AuthMessage::default(); - retval.set_data(src.into()); - retval + Self { data: src.into() } } } @@ -69,9 +62,7 @@ impl From for NonceAuthRequest { impl From for AuthMessage { fn from(src: NonceAuthRequest) -> AuthMessage { - let mut retval = AuthMessage::default(); - retval.set_data(src.into()); - retval + Self { data: src.into() } } } @@ -83,9 +74,7 @@ impl From for NonceAuthResponse { impl From for AuthMessage { fn from(src: NonceAuthResponse) -> AuthMessage { - let mut retval = AuthMessage::default(); - retval.set_data(src.into()); - retval + Self { data: src.into() } } } @@ -97,9 +86,7 @@ impl From for PeerAuthResponse { impl From for AuthMessage { fn from(src: PeerAuthResponse) -> AuthMessage { - let mut retval = AuthMessage::default(); - retval.set_data(src.into()); - retval + Self { data: src.into() } } } @@ -111,9 +98,7 @@ impl From for ClientAuthResponse { impl From for AuthMessage { fn from(src: ClientAuthResponse) -> AuthMessage { - let mut retval = AuthMessage::default(); - retval.set_data(src.into()); - retval + Self { data: src.into() } } } @@ -129,11 +114,11 @@ impl From for EnclaveMessage { impl From> for Message { fn from(src: EnclaveMessage) -> Message { - let mut retval = Message::default(); - retval.set_aad(src.aad); - retval.set_channel_id(src.channel_id.into()); - retval.set_data(src.data); - retval + Self { + aad: src.aad, + channel_id: src.channel_id.into(), + data: src.data, + } } } @@ -150,13 +135,13 @@ impl From for EnclaveMessage { impl From> for NonceMessage { fn from(src: EnclaveMessage) -> NonceMessage { - let mut retval = NonceMessage::default(); - retval.set_aad(src.aad); - // it doesn't matter if we don't bump the nonce when retrieving it, - // src.channel_id will be discarded anyways. - retval.set_nonce(src.channel_id.nonce()); - retval.set_channel_id(src.channel_id.into()); - retval.set_data(src.data); - retval + Self { + aad: src.aad, + // it doesn't matter if we don't bump the nonce when retrieving it, + // src.channel_id will be discarded anyway. + nonce: src.channel_id.nonce(), + channel_id: src.channel_id.into(), + data: src.data, + } } } diff --git a/attest/api/src/lib.rs b/attest/api/src/lib.rs index 7d13a8abab..12fc52d27d 100644 --- a/attest/api/src/lib.rs +++ b/attest/api/src/lib.rs @@ -2,18 +2,7 @@ //! A gRPC API module for attestation -// workaround for #![allow(box_pointers)] in protobuf generated files. -#![allow(renamed_and_removed_lints)] - mod autogenerated_code { - // Expose proto data types from included third-party/external proto files. - pub use protobuf::well_known_types::Empty; - - // Needed due to how to the auto-generated code references the Empty message. - pub mod empty { - pub use protobuf::well_known_types::Empty; - } - // Include the auto-generated code. include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/mod.rs")); } diff --git a/connection/Cargo.toml b/connection/Cargo.toml index 0a9382c802..3e65056b31 100644 --- a/connection/Cargo.toml +++ b/connection/Cargo.toml @@ -10,6 +10,7 @@ rust-version = { workspace = true } [dependencies] der = "0.7.8" +mc-api = { path = "../api" } mc-attest-ake = { path = "../attest/ake" } mc-attest-api = { path = "../attest/api" } mc-attest-core = { path = "../attest/core" } @@ -27,9 +28,10 @@ mc-util-uri = { path = "../util/uri" } aes-gcm = "0.10.3" cookie = "0.18" displaydoc = "0.2" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } mc-attestation-verifier = "0.4.3" mc-rand = "1" +prost = { version = "0.11", default-features = false, features = ["prost-derive"] } retry = "2.0" secrecy = "0.8" serde = "1.0" diff --git a/connection/src/thick.rs b/connection/src/thick.rs index 220b968391..74f96af345 100644 --- a/connection/src/thick.rs +++ b/connection/src/thick.rs @@ -20,10 +20,11 @@ use grpcio::{ CallOption, ChannelBuilder, ClientUnaryReceiver, Environment, Error as GrpcError, MetadataBuilder, }; +use mc_api::blockchain; use mc_attest_ake::{ AuthResponseInput, ClientInitiate, Error as AkeError, Ready, Start, Transition, }; -use mc_attest_api::{attest::Message, attest_grpc::AttestedApiClient}; +use mc_attest_api::attest::{AttestedApiClient, Message}; use mc_attest_core::EvidenceKind; use mc_attestation_verifier::TrustedIdentity; use mc_blockchain_types::{Block, BlockID, BlockIndex}; @@ -33,10 +34,8 @@ use mc_common::{ trace_time, }; use mc_consensus_api::{ - consensus_client_grpc::ConsensusClientApiClient, - consensus_common::{BlocksRequest, ProposeTxResult}, - consensus_common_grpc::BlockchainApiClient, - empty::Empty, + consensus_client::ConsensusClientApiClient, + consensus_common::{BlockchainApiClient, BlocksRequest, ProposeTxResult}, }; use mc_crypto_keys::X25519; use mc_crypto_noise::CipherError; @@ -354,16 +353,18 @@ impl BlockchainConnection for ThickClient { fn fetch_blocks(&mut self, range: Range) -> Result> { trace_time!(self.logger, "ThickClient::get_blocks"); - let mut request = BlocksRequest::new(); - request.set_offset(range.start); - let limit = u32::try_from(range.end - range.start).or(Err(Error::RequestTooLarge))?; - request.set_limit(limit); + let request = BlocksRequest { + offset: range.start, + limit: (range.end - range.start) + .try_into() + .or(Err(Error::RequestTooLarge))?, + }; self.authenticated_attested_call(|this, call_option| { this.blockchain_api_client .get_blocks_async_opt(&request, call_option) })? - .get_blocks() + .blocks .iter() .map(|proto_block| Block::try_from(proto_block).map_err(Error::from)) .collect::>>() @@ -372,18 +373,24 @@ impl BlockchainConnection for ThickClient { fn fetch_block_ids(&mut self, range: Range) -> Result> { trace_time!(self.logger, "ThickClient::get_block_ids"); - let mut request = BlocksRequest::new(); - request.set_offset(range.start); - let limit = u32::try_from(range.end - range.start).or(Err(Error::RequestTooLarge))?; - request.set_limit(limit); + let request = BlocksRequest { + offset: range.start, + limit: (range.end - range.start) + .try_into() + .or(Err(Error::RequestTooLarge))?, + }; + let default_block = blockchain::BlockId::default(); self.authenticated_attested_call(|this, call_option| { this.blockchain_api_client .get_blocks_async_opt(&request, call_option) })? - .get_blocks() + .blocks .iter() - .map(|proto_block| BlockID::try_from(proto_block.get_id()).map_err(Error::from)) + .map(|proto_block| { + BlockID::try_from(proto_block.id.as_ref().unwrap_or(&default_block)) + .map_err(Error::from) + }) .collect::>>() } @@ -393,7 +400,7 @@ impl BlockchainConnection for ThickClient { Ok(self .authenticated_attested_call(|this, call_option| { this.blockchain_api_client - .get_last_block_info_async_opt(&Empty::new(), call_option) + .get_last_block_info_async_opt(&(), call_option) })? .index) } @@ -403,7 +410,7 @@ impl BlockchainConnection for ThickClient { let block_info = self.authenticated_attested_call(|this, call_option| { this.blockchain_api_client - .get_last_block_info_async_opt(&Empty::new(), call_option) + .get_last_block_info_async_opt(&(), call_option) })?; Ok(block_info.into()) @@ -423,26 +430,27 @@ impl UserTxConnection for ThickClient { .as_mut() .expect("no enclave_connection even though attest succeeded"); - let mut msg = Message::new(); - msg.set_channel_id(Vec::from(enclave_connection.binding())); - // Don't leave the plaintext serialization floating around let tx_plaintext = SecretVec::new(encode(tx)); let tx_ciphertext = enclave_connection.encrypt(&[], tx_plaintext.expose_secret().as_ref())?; - msg.set_data(tx_ciphertext); + let msg = Message { + channel_id: enclave_connection.binding().to_vec(), + data: tx_ciphertext, + ..Default::default() + }; let resp = self.authenticated_attested_call(|this, call_option| { this.consensus_client_api_client .client_tx_propose_async_opt(&msg, call_option) })?; - if resp.get_result() == ProposeTxResult::Ok { - Ok(resp.get_block_count()) + if resp.result() == ProposeTxResult::Ok { + Ok(resp.block_count) } else { Err(Error::TransactionValidation( - resp.get_result(), - resp.get_err_msg().to_owned(), + resp.result(), + resp.err_msg.to_owned(), )) } } diff --git a/connection/src/traits.rs b/connection/src/traits.rs index acfeefb3b5..ee0b14f199 100644 --- a/connection/src/traits.rs +++ b/connection/src/traits.rs @@ -104,6 +104,7 @@ impl Display for BlockInfo { impl From for BlockInfo { fn from(src: LastBlockInfoResponse) -> Self { + #[allow(deprecated)] // Needed for nodes that do not yet return the fee map. let minimum_fees = if src.minimum_fees.is_empty() { [(Mob::ID, src.mob_minimum_fee)].into() @@ -124,16 +125,16 @@ impl From for BlockInfo { impl From for LastBlockInfoResponse { fn from(src: BlockInfo) -> Self { - let mut result = LastBlockInfoResponse::new(); - result.index = src.block_index; - result.network_block_version = src.network_block_version; - result.set_minimum_fees( - src.minimum_fees + Self { + index: src.block_index, + minimum_fees: src + .minimum_fees .into_iter() .map(|(token_id, fee)| (*token_id, fee)) .collect(), - ); - result + network_block_version: src.network_block_version, + ..Default::default() + } } } diff --git a/consensus/api/Cargo.toml b/consensus/api/Cargo.toml index 3594f16049..b292ae81f7 100644 --- a/consensus/api/Cargo.toml +++ b/consensus/api/Cargo.toml @@ -16,8 +16,8 @@ mc-ledger-db = { path = "../../ledger/db" } mc-transaction-core = { path = "../../transaction/core" } futures = "0.3" -grpcio = "0.13" -protobuf = "2.27.1" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } +prost = { version = "0.11", default-features = false } [dev-dependencies] mc-crypto-multisig = { path = "../../crypto/multisig" } diff --git a/consensus/api/src/conversions.rs b/consensus/api/src/conversions.rs index a11392adab..7ed23dcbd6 100644 --- a/consensus/api/src/conversions.rs +++ b/consensus/api/src/conversions.rs @@ -99,59 +99,59 @@ impl From for MintValidationResult { fn from(src: MintValidationError) -> Self { match src { MintValidationError::InvalidBlockVersion(block_version) => Self { - code: MintValidationResultCode::InvalidBlockVersion, + code: MintValidationResultCode::InvalidBlockVersion.into(), block_version: *block_version, ..Default::default() }, MintValidationError::InvalidTokenId(token_id) => Self { - code: MintValidationResultCode::InvalidTokenId, + code: MintValidationResultCode::InvalidTokenId.into(), token_id: *token_id, ..Default::default() }, MintValidationError::InvalidNonceLength(len) => Self { - code: MintValidationResultCode::InvalidNonceLength, + code: MintValidationResultCode::InvalidNonceLength.into(), nonce_length: len as u64, ..Default::default() }, MintValidationError::InvalidSignerSet => Self { - code: MintValidationResultCode::InvalidSignerSet, + code: MintValidationResultCode::InvalidSignerSet.into(), ..Default::default() }, MintValidationError::InvalidSignature => Self { - code: MintValidationResultCode::InvalidSignature, + code: MintValidationResultCode::InvalidSignature.into(), ..Default::default() }, MintValidationError::TombstoneBlockExceeded => Self { - code: MintValidationResultCode::TombstoneBlockExceeded, + code: MintValidationResultCode::TombstoneBlockExceeded.into(), ..Default::default() }, MintValidationError::TombstoneBlockTooFar => Self { - code: MintValidationResultCode::TombstoneBlockTooFar, + code: MintValidationResultCode::TombstoneBlockTooFar.into(), ..Default::default() }, MintValidationError::Unknown => Self { - code: MintValidationResultCode::Unknown, + code: MintValidationResultCode::Unknown.into(), ..Default::default() }, MintValidationError::AmountExceedsMintLimit => Self { - code: MintValidationResultCode::AmountExceedsMintLimit, + code: MintValidationResultCode::AmountExceedsMintLimit.into(), ..Default::default() }, MintValidationError::NoGovernors(token_id) => Self { - code: MintValidationResultCode::NoGovernors, + code: MintValidationResultCode::NoGovernors.into(), token_id: *token_id, ..Default::default() }, MintValidationError::NonceAlreadyUsed => Self { - code: MintValidationResultCode::NonceAlreadyUsed, + code: MintValidationResultCode::NonceAlreadyUsed.into(), ..Default::default() }, MintValidationError::NoMatchingMintConfig => Self { - code: MintValidationResultCode::NoMatchingMintConfig, + code: MintValidationResultCode::NoMatchingMintConfig.into(), ..Default::default() }, MintValidationError::MintingToFogNotSupported => Self { - code: MintValidationResultCode::MintingToFogNotSupported, + code: MintValidationResultCode::MintingToFogNotSupported.into(), ..Default::default() }, } @@ -163,7 +163,7 @@ impl TryInto for MintValidationResult { type Error = String; fn try_into(self) -> Result { - match self.code { + match self.code() { MintValidationResultCode::Ok => { Err("Ok value cannot be converted into MintValidationError".to_string()) } @@ -208,10 +208,10 @@ impl TryInto for MintValidationResult { /// consensus_config::ActiveMintConfig impl From<&mc_ledger_db::ActiveMintConfig> for consensus_config::ActiveMintConfig { fn from(src: &mc_ledger_db::ActiveMintConfig) -> Self { - let mut dst = Self::new(); - dst.set_mint_config((&src.mint_config).into()); - dst.set_total_minted(src.total_minted); - dst + Self { + mint_config: Some((&src.mint_config).into()), + total_minted: src.total_minted, + } } } @@ -221,10 +221,15 @@ impl TryFrom<&consensus_config::ActiveMintConfig> for mc_ledger_db::ActiveMintCo type Error = ConversionError; fn try_from(src: &consensus_config::ActiveMintConfig) -> Result { - let mint_config = src.get_mint_config().try_into()?; + let mint_config = src + .mint_config + .as_ref() + .map(TryInto::try_into) + .transpose()? + .unwrap_or_default(); Ok(Self { mint_config, - total_minted: src.get_total_minted(), + total_minted: src.total_minted, }) } } @@ -233,10 +238,10 @@ impl TryFrom<&consensus_config::ActiveMintConfig> for mc_ledger_db::ActiveMintCo /// consensus_config::ActiveMintConfigs impl From<&mc_ledger_db::ActiveMintConfigs> for consensus_config::ActiveMintConfigs { fn from(src: &mc_ledger_db::ActiveMintConfigs) -> Self { - let mut dst = Self::new(); - dst.set_configs(src.configs.iter().map(|config| config.into()).collect()); - dst.set_mint_config_tx((&src.mint_config_tx).into()); - dst + Self { + configs: src.configs.iter().map(|config| config.into()).collect(), + mint_config_tx: Some((&src.mint_config_tx).into()), + } } } @@ -247,11 +252,16 @@ impl TryFrom<&consensus_config::ActiveMintConfigs> for mc_ledger_db::ActiveMintC fn try_from(src: &consensus_config::ActiveMintConfigs) -> Result { let configs = src - .get_configs() + .configs .iter() .map(TryInto::try_into) .collect::, _>>()?; - let mint_config_tx = src.get_mint_config_tx().try_into()?; + let mint_config_tx = src + .mint_config_tx + .as_ref() + .map(TryInto::try_into) + .transpose()? + .unwrap_or_default(); Ok(Self { configs, mint_config_tx, @@ -266,7 +276,7 @@ mod conversion_tests { use mc_transaction_core::mint::MintConfig; use mc_transaction_core_test_utils::create_mint_config_tx_and_signers; use mc_util_serial::{decode, encode}; - use protobuf::Message; + use prost::Message; use rand_core::SeedableRng; use rand_hc::Hc128Rng; @@ -305,14 +315,14 @@ mod conversion_tests { // function. { let bytes = encode(&source); - let recovered = consensus_config::ActiveMintConfig::parse_from_bytes(&bytes).unwrap(); + let recovered = consensus_config::ActiveMintConfig::decode(bytes.as_slice()).unwrap(); assert_eq!(recovered, consensus_config::ActiveMintConfig::from(&source)); } // Encoding with protobuf, decoding with prost should be the identity function. { let external = consensus_config::ActiveMintConfig::from(&source); - let bytes = external.write_to_bytes().unwrap(); + let bytes = external.encode_to_vec(); let recovered: mc_ledger_db::ActiveMintConfig = decode(&bytes).unwrap(); assert_eq!(source, recovered); } @@ -356,7 +366,7 @@ mod conversion_tests { // function. { let bytes = encode(&source); - let recovered = consensus_config::ActiveMintConfigs::parse_from_bytes(&bytes).unwrap(); + let recovered = consensus_config::ActiveMintConfigs::decode(bytes.as_slice()).unwrap(); assert_eq!( recovered, consensus_config::ActiveMintConfigs::from(&source) @@ -366,7 +376,7 @@ mod conversion_tests { // Encoding with protobuf, decoding with prost should be the identity function. { let external = consensus_config::ActiveMintConfigs::from(&source); - let bytes = external.write_to_bytes().unwrap(); + let bytes = external.encode_to_vec(); let recovered: mc_ledger_db::ActiveMintConfigs = decode(&bytes).unwrap(); assert_eq!(source, recovered); } diff --git a/consensus/api/src/lib.rs b/consensus/api/src/lib.rs index 36526ed4f9..a9b227fb9b 100644 --- a/consensus/api/src/lib.rs +++ b/consensus/api/src/lib.rs @@ -2,23 +2,39 @@ //! MobileCoin gRPC API. -// workaround for #![allow(box_pointers)] in protobuf generated files. -#![allow(renamed_and_removed_lints)] - mod autogenerated_code { // Expose proto data types from included third-party/external proto files. pub use mc_api::{blockchain, external}; pub use mc_attest_api::attest; - pub use protobuf::well_known_types::Empty; - - // Needed due to how to the auto-generated code references the Empty message. - pub mod empty { - pub use protobuf::well_known_types::Empty; + #[path = "consensus_client.rs"] + pub mod consensus_client { + include!(concat!( + env!("OUT_DIR"), + "/protos-auto-gen/consensus_client.rs" + )); + } + #[path = "consensus_peer.rs"] + pub mod consensus_peer { + include!(concat!( + env!("OUT_DIR"), + "/protos-auto-gen/consensus_peer.rs" + )); + } + #[path = "consensus_common.rs"] + pub mod consensus_common { + include!(concat!( + env!("OUT_DIR"), + "/protos-auto-gen/consensus_common.rs" + )); + } + #[path = "consensus_config.rs"] + pub mod consensus_config { + include!(concat!( + env!("OUT_DIR"), + "/protos-auto-gen/consensus_config.rs" + )); } - - // Include the auto-generated code. - include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/mod.rs")); } pub mod conversions; diff --git a/consensus/enclave/tests/enclave_api_tests.rs b/consensus/enclave/tests/enclave_api_tests.rs index f117145bec..8ef5ab25bf 100644 --- a/consensus/enclave/tests/enclave_api_tests.rs +++ b/consensus/enclave/tests/enclave_api_tests.rs @@ -101,9 +101,11 @@ fn consensus_enclave_client_tx_propose(logger: Logger) { let ciphertext = initiator.encrypt(&[], &encode(&req)).unwrap(); - let mut msg = Message::new(); - msg.set_channel_id(Vec::from(initiator.binding())); - msg.set_data(ciphertext); + let msg = Message { + channel_id: Vec::from(initiator.binding()), + data: ciphertext, + ..Default::default() + }; enclave .client_tx_propose(msg.into()) @@ -114,9 +116,11 @@ fn consensus_enclave_client_tx_propose(logger: Logger) { let tx_ciphertext = initiator.encrypt(&[], &bad_req_bytes).unwrap(); - let mut msg = Message::new(); - msg.set_channel_id(Vec::from(initiator.binding())); - msg.set_data(tx_ciphertext); + let msg = Message { + channel_id: Vec::from(initiator.binding()), + data: tx_ciphertext, + ..Default::default() + }; let result = enclave.client_tx_propose(msg.into()); assert!(result.is_err(), "unexpected success with bad serialized Tx"); @@ -127,9 +131,11 @@ fn consensus_enclave_client_tx_propose(logger: Logger) { let ciphertext = initiator.encrypt(&[], &encode(&req)).unwrap(); - let mut msg = Message::new(); - msg.set_channel_id(Vec::from(initiator.binding())); - msg.set_data(ciphertext); + let msg = Message { + channel_id: Vec::from(initiator.binding()), + data: ciphertext, + ..Default::default() + }; assert_eq!( enclave.client_tx_propose(msg.into()), @@ -142,9 +148,11 @@ fn consensus_enclave_client_tx_propose(logger: Logger) { let ciphertext = initiator.encrypt(&[], &encode(&req)).unwrap(); - let mut msg = Message::new(); - msg.set_channel_id(Vec::from(initiator.binding())); - msg.set_data(ciphertext); + let msg = Message { + channel_id: Vec::from(initiator.binding()), + data: ciphertext, + ..Default::default() + }; enclave .client_tx_propose(msg.into()) diff --git a/consensus/mint-client/Cargo.toml b/consensus/mint-client/Cargo.toml index 0a244feb1e..430aee9417 100644 --- a/consensus/mint-client/Cargo.toml +++ b/consensus/mint-client/Cargo.toml @@ -37,11 +37,10 @@ mc-util-uri = { path = "../../util/uri" } clap = { version = "4.5", features = ["derive", "env"] } displaydoc = "0.2" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } hex = { version = "0.4", features = ["serde"] } mc-attestation-verifier = "0.4.3" pem = "3.0" -protobuf = "2.27.1" rand = "0.8" serde = "1" serde_json = "1.0" diff --git a/consensus/mint-client/src/bin/main.rs b/consensus/mint-client/src/bin/main.rs index 6f327d04bb..9c13fa8412 100644 --- a/consensus/mint-client/src/bin/main.rs +++ b/consensus/mint-client/src/bin/main.rs @@ -6,8 +6,7 @@ use clap::Parser; use grpcio::{ChannelBuilder, EnvBuilder}; use mc_common::logger::{create_app_logger, o}; use mc_consensus_api::{ - consensus_client_grpc::ConsensusClientApiClient, consensus_common_grpc::BlockchainApiClient, - empty::Empty, + consensus_client::ConsensusClientApiClient, consensus_common::BlockchainApiClient, }; use mc_consensus_enclave_api::GovernorsSigner; use mc_consensus_mint_client::{printers, Commands, Config, FogContext}; @@ -19,7 +18,6 @@ use mc_transaction_core::{ mint::{MintConfigTx, MintTx}, }; use mc_util_grpc::{common_headers_call_option, ConnectionUriGrpcioChannel}; -use protobuf::ProtobufEnum; use std::{fs, process::exit, sync::Arc}; fn main() { @@ -41,7 +39,7 @@ fn main() { let tx = params .try_into_mint_config_tx(|| { let last_block_info = blockchain_api - .get_last_block_info(&Empty::new()) + .get_last_block_info(&()) .expect("get last block info"); last_block_info.index + MAX_TOMBSTONE_BLOCKS - 1 }) @@ -59,7 +57,7 @@ fn main() { // Relying on the success result code being 0, we terminate ourselves in a way // that allows whoever started this binary to easily determine if submitting the // transaction succeeded. - exit(resp.get_result().get_code().value()); + exit(resp.result.unwrap().code); } Commands::GenerateMintConfigTx { @@ -74,7 +72,7 @@ fn main() { .connect_to_uri(node, &logger); let blockchain_api = BlockchainApiClient::new(ch); let last_block_info = blockchain_api - .get_last_block_info(&Empty::new()) + .get_last_block_info(&()) .expect("get last block info"); last_block_info.index + MAX_TOMBSTONE_BLOCKS - 1 } else { @@ -146,7 +144,7 @@ fn main() { // Relying on the success result code being 0, we terminate ourselves in a way // that allows whoever started this binary to easily determine if submitting the // transaction succeeded. - exit(resp.get_result().get_code().value()); + exit(resp.result.unwrap().code); } Commands::GenerateAndSubmitMintTx { @@ -170,7 +168,7 @@ fn main() { let tx = params .try_into_mint_tx(maybe_fog_bits, || { let last_block_info = blockchain_api - .get_last_block_info(&Empty::new()) + .get_last_block_info(&()) .expect("get last block info"); last_block_info.index + MAX_TOMBSTONE_BLOCKS - 1 }) @@ -188,7 +186,7 @@ fn main() { // Relying on the success result code being 0, we terminate ourselves in a way // that allows whoever started this binary to easily determine if submitting the // transaction succeeded. - exit(resp.get_result().get_code().value()); + exit(resp.result.unwrap().code); } Commands::GenerateMintTx { @@ -212,7 +210,7 @@ fn main() { .connect_to_uri(node, &logger); let blockchain_api = BlockchainApiClient::new(ch); let last_block_info = blockchain_api - .get_last_block_info(&Empty::new()) + .get_last_block_info(&()) .expect("get last block info"); last_block_info.index + MAX_TOMBSTONE_BLOCKS - 1 } else { @@ -284,7 +282,7 @@ fn main() { // Relying on the success result code being 0, we terminate ourselves in a way // that allows whoever started this binary to easily determine if submitting the // transaction succeeded. - exit(resp.get_result().get_code().value()); + exit(resp.result.unwrap().code); } Commands::SignGovernors { diff --git a/consensus/mint-client/src/config.rs b/consensus/mint-client/src/config.rs index d9566c08df..14ea58e6c3 100644 --- a/consensus/mint-client/src/config.rs +++ b/consensus/mint-client/src/config.rs @@ -5,7 +5,7 @@ use crate::FogContext; use clap::{Args, Parser, Subcommand}; use mc_account_keys::PublicAddress; -use mc_api::printable::PrintableWrapper; +use mc_api::printable::{printable_wrapper, PrintableWrapper}; use mc_consensus_mint_client_types::{MintConfigTxFile, TxFile}; use mc_consensus_service_config::TokensConfig; use mc_crypto_keys::{ @@ -546,13 +546,14 @@ fn parse_public_address(b58: &str) -> Result { let printable_wrapper = PrintableWrapper::b58_decode(b58.into()) .map_err(|err| format!("failed parsing b58 address '{b58}': {err}"))?; - if printable_wrapper.has_public_address() { - let public_address = PublicAddress::try_from(printable_wrapper.get_public_address()) - .map_err(|err| format!("failed converting b58 public address '{b58}': {err}"))?; + match printable_wrapper.wrapper { + Some(printable_wrapper::Wrapper::PublicAddress(public_address)) => { + let public_address = PublicAddress::try_from(&public_address) + .map_err(|err| format!("failed converting b58 public address '{b58}': {err}"))?; - Ok(public_address) - } else { - Err(format!("b58 address '{b58}' is not a public address")) + Ok(public_address) + } + _ => Err(format!("b58 address '{b58}' is not a public address")), } } diff --git a/consensus/mint-client/src/printers.rs b/consensus/mint-client/src/printers.rs index 4e3aae9c19..c9f3e045ed 100644 --- a/consensus/mint-client/src/printers.rs +++ b/consensus/mint-client/src/printers.rs @@ -3,7 +3,7 @@ //! Utility functions for printing objects in a human-friendly way. use mc_account_keys::PublicAddress; -use mc_api::printable::PrintableWrapper; +use mc_api::printable::{printable_wrapper, PrintableWrapper}; use mc_crypto_keys::{DistinguishedEncoding, Ed25519Public, Ed25519Signature}; use mc_crypto_multisig::{MultiSig, SignerSet}; use mc_transaction_core::mint::{ @@ -62,8 +62,11 @@ pub fn print_mint_tx(tx: &MintTx, indent: usize) { pub fn print_mint_tx_prefix(prefix: &MintTxPrefix, indent: usize) { let recipient = PublicAddress::new(&prefix.spend_public_key, &prefix.view_public_key); - let mut wrapper = PrintableWrapper::new(); - wrapper.set_public_address((&recipient).into()); + let wrapper = PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress( + (&recipient).into(), + )), + }; let b58_recipient = wrapper.b58_encode().expect("failed encoding b58 address"); let mut indent_str = INDENT_STR.repeat(indent); diff --git a/consensus/service/Cargo.toml b/consensus/service/Cargo.toml index d3c4de458d..fe50c65f8c 100644 --- a/consensus/service/Cargo.toml +++ b/consensus/service/Cargo.toml @@ -51,11 +51,10 @@ clap = { version = "4.5", features = ["derive", "env"] } displaydoc = { version = "0.2", default-features = false } fs_extra = "1.3" futures = "0.3" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } hex = "0.4" lazy_static = "1.4" once_cell = "1.19" -protobuf = "2.27.1" rand = "0.8" rayon = "1.9" retry = "2.0" diff --git a/consensus/service/src/api/attested_api_service.rs b/consensus/service/src/api/attested_api_service.rs index 29dc3e10bc..f48f74e4b9 100644 --- a/consensus/service/src/api/attested_api_service.rs +++ b/consensus/service/src/api/attested_api_service.rs @@ -4,7 +4,7 @@ use crate::SVC_COUNTERS; use grpcio::{RpcContext, UnarySink}; -use mc_attest_api::{attest::AuthMessage, attest_grpc::AttestedApi}; +use mc_attest_api::attest::{AttestedApi, AuthMessage}; use mc_attest_enclave_api::{ClientSession, PeerSession, Session}; use mc_common::{ logger::{log, Logger}, @@ -143,7 +143,7 @@ mod peer_tests { ChannelBuilder, Environment, Error as GrpcError, RpcStatusCode, Server, ServerBuilder, ServerCredentials, }; - use mc_attest_api::attest_grpc::{self, AttestedApiClient}; + use mc_attest_api::attest::{self, AttestedApiClient}; use mc_common::{logger::test_with_logger, time::SystemTimeProvider}; use mc_consensus_enclave_mock::MockConsensusEnclave; use mc_util_grpc::TokenAuthenticator; @@ -151,7 +151,7 @@ mod peer_tests { /// Starts the service on localhost and connects a client to it. fn get_client_server(instance: AttestedApiService) -> (AttestedApiClient, Server) { - let service = attest_grpc::create_attested_api(instance); + let service = attest::create_attested_api(instance); let env = Arc::new(Environment::new(1)); let mut server = ServerBuilder::new(env.clone()) .register_service(service) @@ -207,7 +207,7 @@ mod client_tests { ChannelBuilder, Environment, Error as GrpcError, RpcStatusCode, Server, ServerBuilder, ServerCredentials, }; - use mc_attest_api::attest_grpc::{self, AttestedApiClient}; + use mc_attest_api::attest::{self, AttestedApiClient}; use mc_common::{logger::test_with_logger, time::SystemTimeProvider}; use mc_consensus_enclave_mock::MockConsensusEnclave; use mc_util_grpc::TokenAuthenticator; @@ -217,7 +217,7 @@ mod client_tests { fn get_client_server( instance: AttestedApiService, ) -> (AttestedApiClient, Server) { - let service = attest_grpc::create_attested_api(instance); + let service = attest::create_attested_api(instance); let env = Arc::new(Environment::new(1)); let mut server = ServerBuilder::new(env.clone()) .register_service(service) diff --git a/consensus/service/src/api/blockchain_api_service.rs b/consensus/service/src/api/blockchain_api_service.rs index 73a0c7dbad..9504d14696 100644 --- a/consensus/service/src/api/blockchain_api_service.rs +++ b/consensus/service/src/api/blockchain_api_service.rs @@ -7,15 +7,12 @@ use grpcio::{RpcContext, RpcStatus, RpcStatusCode, UnarySink}; use mc_common::logger::{log, Logger}; use mc_consensus_api::{ blockchain, - consensus_common::{BlocksRequest, BlocksResponse, LastBlockInfoResponse}, - consensus_common_grpc::BlockchainApi, - empty::Empty, + consensus_common::{BlockchainApi, BlocksRequest, BlocksResponse, LastBlockInfoResponse}, }; use mc_ledger_db::Ledger; use mc_transaction_core::{tokens::Mob, BlockVersion, FeeMap, Token}; use mc_util_grpc::{rpc_logger, send_result, Authenticator}; -use protobuf::RepeatedField; -use std::{cmp, collections::HashMap, sync::Arc}; +use std::{cmp, collections::BTreeMap, sync::Arc}; #[derive(Clone)] pub struct BlockchainApiService { @@ -66,21 +63,20 @@ impl BlockchainApiService { /// Returns information about the last block. fn get_last_block_info_helper(&mut self) -> Result { let num_blocks = self.ledger.num_blocks()?; - let mut resp = LastBlockInfoResponse::new(); - resp.set_index(num_blocks - 1); - resp.set_mob_minimum_fee( - self.fee_map + #[allow(deprecated)] + Ok(LastBlockInfoResponse { + index: num_blocks - 1, + mob_minimum_fee: self + .fee_map .get_fee_for_token(&Mob::ID) .expect("should always have a fee for MOB"), - ); - resp.set_minimum_fees(HashMap::from_iter( - self.fee_map - .iter() - .map(|(token_id, fee)| (**token_id, *fee)), - )); - resp.set_network_block_version(*self.network_block_version); - - Ok(resp) + minimum_fees: BTreeMap::from_iter( + self.fee_map + .iter() + .map(|(token_id, fee)| (**token_id, *fee)), + ), + network_block_version: *self.network_block_version, + }) } /// Returns blocks in the range [offset, offset + limit). @@ -121,9 +117,7 @@ impl BlockchainApiService { .map(|block| blockchain::Block::from(&block)) .collect(); - let mut response = BlocksResponse::new(); - response.set_blocks(RepeatedField::from_vec(blocks)); - Ok(response) + Ok(BlocksResponse { blocks }) } } @@ -132,7 +126,7 @@ impl BlockchainApi for BlockchainApiService { fn get_last_block_info( &mut self, ctx: RpcContext, - _request: Empty, + _request: (), sink: UnarySink, ) { let _timer = SVC_COUNTERS.req(&ctx); @@ -185,7 +179,7 @@ mod tests { ChannelBuilder, Environment, Error as GrpcError, Server, ServerBuilder, ServerCredentials, }; use mc_common::{logger::test_with_logger, time::SystemTimeProvider}; - use mc_consensus_api::consensus_common_grpc::{self, BlockchainApiClient}; + use mc_consensus_api::consensus_common::{self, BlockchainApiClient}; use mc_ledger_db::test_utils::{create_ledger, initialize_ledger}; use mc_transaction_core::TokenId; use mc_transaction_core_test_utils::AccountKey; @@ -197,7 +191,7 @@ mod tests { fn get_client_server( instance: BlockchainApiService, ) -> (BlockchainApiClient, Server) { - let service = consensus_common_grpc::create_blockchain_api(instance); + let service = consensus_common::create_blockchain_api(instance); let env = Arc::new(Environment::new(1)); let mut server = ServerBuilder::new(env.clone()) .register_service(service) @@ -231,11 +225,13 @@ mod tests { ); let last_index = blocks_data.last().unwrap().block().index; - let mut expected_response = LastBlockInfoResponse::new(); - expected_response.set_index(last_index); - expected_response.set_mob_minimum_fee(4000000000); - expected_response.set_minimum_fees(HashMap::from_iter([(0, 4000000000), (60, 128000)])); - expected_response.set_network_block_version(*BlockVersion::MAX); + #[allow(deprecated)] + let expected_response = LastBlockInfoResponse { + index: last_index, + mob_minimum_fee: 4000000000, + minimum_fees: BTreeMap::from_iter([(0, 4000000000), (60, 128000)]), + network_block_version: *BlockVersion::MAX, + }; assert_eq!(last_index + 1, ledger_db.num_blocks().unwrap()); let mut blockchain_api_service = @@ -266,7 +262,7 @@ mod tests { let (client, _server) = get_client_server(blockchain_api_service); - match client.get_last_block_info(&Empty::default()) { + match client.get_last_block_info(&()) { Ok(response) => { panic!("Unexpected response {response:?}"); } diff --git a/consensus/service/src/api/client_api_service.rs b/consensus/service/src/api/client_api_service.rs index 440860a2c6..c8d4c91145 100644 --- a/consensus/service/src/api/client_api_service.rs +++ b/consensus/service/src/api/client_api_service.rs @@ -15,11 +15,9 @@ use mc_attest_api::attest::Message; use mc_attest_enclave_api::ClientSession; use mc_common::{logger::Logger, LruCache}; use mc_consensus_api::{ - consensus_client::{ProposeMintConfigTxResponse, ProposeMintTxResponse}, - consensus_client_grpc::ConsensusClientApi, + consensus_client::{ConsensusClientApi, ProposeMintConfigTxResponse, ProposeMintTxResponse}, consensus_common::ProposeTxResponse, consensus_config::{ConsensusNodeConfig, TokenConfig}, - empty::Empty, }; use mc_consensus_enclave::ConsensusEnclave; use mc_consensus_service_config::Config; @@ -166,7 +164,7 @@ impl ClientApiService { (*self.propose_tx_callback)(ConsensusValue::TxHash(tx_hash), None, None); counters::ADD_TX.inc(); - let response = ProposeTxResponse::new(); + let response = ProposeTxResponse::default(); Ok(response) } @@ -182,7 +180,7 @@ impl ClientApiService { counters::PROPOSE_MINT_CONFIG_TX_INITIATED.inc(); let mint_config_tx = MintConfigTx::try_from(&grpc_tx) .map_err(|err| ConsensusGrpcError::InvalidArgument(format!("{err:?}")))?; - let response = ProposeMintConfigTxResponse::new(); + let response = ProposeMintConfigTxResponse::default(); // Validate the transaction. // This is done here as a courtesy to give clients immediate feedback about the @@ -208,7 +206,7 @@ impl ClientApiService { counters::PROPOSE_MINT_TX_INITIATED.inc(); let mint_tx = MintTx::try_from(&grpc_tx) .map_err(|err| ConsensusGrpcError::InvalidArgument(format!("{err:?}")))?; - let response = ProposeMintTxResponse::new(); + let response = ProposeMintTxResponse::default(); // Validate the transaction. // This is done here as a courtesy to give clients immediate feedback about the @@ -229,38 +227,36 @@ impl ClientApiService { .tokens() .iter() .map(|token_config| { - let mut grpc_token_config = TokenConfig::new(); - grpc_token_config.set_token_id(*token_config.token_id()); - grpc_token_config - .set_minimum_fee(token_config.minimum_fee_or_default().unwrap_or(0)); - if let Some(governors) = token_config.governors()? { - grpc_token_config.set_governors((&governors).into()); - } - - let active_mint_configs = self - .ledger - .get_active_mint_configs(token_config.token_id())?; - if let Some(active_mint_configs) = active_mint_configs.as_ref() { - grpc_token_config.set_active_mint_configs(active_mint_configs.into()); - } - + let grpc_token_config = TokenConfig { + token_id: *token_config.token_id(), + minimum_fee: token_config.minimum_fee_or_default().unwrap_or(0), + governors: token_config + .governors()? + .as_ref() + .map(|governors| governors.into()), + active_mint_configs: self + .ledger + .get_active_mint_configs(token_config.token_id())? + .as_ref() + .map(|active_mint_configs| active_mint_configs.into()), + }; Ok((*token_config.token_id(), grpc_token_config)) }) .collect::>()?; - let mut response = ConsensusNodeConfig::new(); - response.set_minting_trust_root((&self.enclave.get_minting_trust_root()?).into()); - response.set_token_config_map(token_config_map); - if let Some(governors_signature) = tokens_config.governors_signature.as_ref() { - response.set_governors_signature(governors_signature.into()); - } - response.set_peer_responder_id(self.config.peer_responder_id.to_string()); - response.set_client_responder_id(self.config.client_responder_id.to_string()); - response.set_block_signing_key((&self.enclave.get_signer()?).into()); - response.set_block_version(*self.config.block_version); - response.set_scp_message_signing_key((&self.config.msg_signer_key.public_key()).into()); - - Ok(response) + Ok(ConsensusNodeConfig { + minting_trust_root: Some((&self.enclave.get_minting_trust_root()?).into()), + token_config_map, + governors_signature: tokens_config + .governors_signature + .as_ref() + .map(|governors_signature| governors_signature.into()), + peer_responder_id: self.config.peer_responder_id.to_string(), + client_responder_id: self.config.client_responder_id.to_string(), + block_signing_key: Some((&self.enclave.get_signer()?).into()), + block_version: *self.config.block_version, + scp_message_signing_key: Some((&self.config.msg_signer_key.public_key()).into()), + }) } } @@ -313,8 +309,8 @@ impl ConsensusClientApi for ClientApiService { result = result.and_then(|mut response| { let num_blocks = self.ledger.num_blocks().map_err(ConsensusGrpcError::from)?; - response.set_block_count(num_blocks); - response.set_block_version(*self.config.block_version); + response.block_count = num_blocks; + response.block_version = *self.config.block_version; Ok(response) }); @@ -351,8 +347,8 @@ impl ConsensusClientApi for ClientApiService { result = result.and_then(|mut response| { let num_blocks = self.ledger.num_blocks().map_err(ConsensusGrpcError::from)?; - response.set_block_count(num_blocks); - response.set_block_version(*self.config.block_version); + response.block_count = num_blocks; + response.block_version = *self.config.block_version; Ok(response) }); @@ -389,8 +385,8 @@ impl ConsensusClientApi for ClientApiService { result = result.and_then(|mut response| { let num_blocks = self.ledger.num_blocks().map_err(ConsensusGrpcError::from)?; - response.set_block_count(num_blocks); - response.set_block_version(*self.config.block_version); + response.block_count = num_blocks; + response.block_version = *self.config.block_version; Ok(response) }); @@ -402,7 +398,7 @@ impl ConsensusClientApi for ClientApiService { fn get_node_config( &mut self, ctx: RpcContext, - _empty: Empty, + _empty: (), sink: UnarySink, ) { let result = self.get_node_config_impl().map_err(RpcStatus::from); @@ -433,8 +429,9 @@ mod client_api_tests { LruCache, NodeID, ResponderId, }; use mc_consensus_api::{ - consensus_client::MintValidationResultCode, consensus_client_grpc, - consensus_client_grpc::ConsensusClientApiClient, consensus_common::ProposeTxResult, + consensus_client, + consensus_client::{ConsensusClientApiClient, MintValidationResultCode}, + consensus_common::ProposeTxResult, }; use mc_consensus_enclave::{Error as EnclaveError, TxContext}; use mc_consensus_enclave_mock::MockConsensusEnclave; @@ -461,7 +458,7 @@ mod client_api_tests { /// Starts the service on localhost and connects a client to it. fn get_client_server(instance: ClientApiService) -> (ConsensusClientApiClient, Server) { - let service = consensus_client_grpc::create_consensus_client_api(instance); + let service = consensus_client::create_consensus_client_api(instance); let env = Arc::new(Environment::new(1)); let mut server = ServerBuilder::new(env.clone()) .register_service(service) @@ -578,8 +575,8 @@ mod client_api_tests { let message = Message::default(); match client.client_tx_propose(&message) { Ok(propose_tx_response) => { - assert_eq!(propose_tx_response.get_result(), ProposeTxResult::Ok); - assert_eq!(propose_tx_response.get_block_count(), num_blocks); + assert_eq!(propose_tx_response.result(), ProposeTxResult::Ok); + assert_eq!(propose_tx_response.block_count, num_blocks); } Err(e) => panic!("Unexpected error: {e:?}"), } @@ -652,8 +649,8 @@ mod client_api_tests { // Try with chain id header match client.client_tx_propose_opt(&message, call_option("local")) { Ok(propose_tx_response) => { - assert_eq!(propose_tx_response.get_result(), ProposeTxResult::Ok); - assert_eq!(propose_tx_response.get_block_count(), num_blocks); + assert_eq!(propose_tx_response.result(), ProposeTxResult::Ok); + assert_eq!(propose_tx_response.block_count, num_blocks); } Err(e) => panic!("Unexpected error: {e:?}"), } @@ -785,10 +782,10 @@ mod client_api_tests { match client.client_tx_propose(&message) { Ok(propose_tx_response) => { assert_eq!( - propose_tx_response.get_result(), + propose_tx_response.result(), ProposeTxResult::ContainsSpentKeyImage ); - assert_eq!(propose_tx_response.get_block_count(), num_blocks); + assert_eq!(propose_tx_response.block_count, num_blocks); } Err(e) => panic!("Unexpected error: {e:?}"), } @@ -848,10 +845,10 @@ mod client_api_tests { match client.client_tx_propose(&message) { Ok(propose_tx_response) => { assert_eq!( - propose_tx_response.get_result(), + propose_tx_response.result(), ProposeTxResult::FeeMapDigestMismatch ); - assert_eq!(propose_tx_response.get_block_count(), num_blocks); + assert_eq!(propose_tx_response.block_count, num_blocks); } Err(e) => panic!("Unexpected error: {e:?}"), } @@ -919,10 +916,10 @@ mod client_api_tests { match client.client_tx_propose(&message) { Ok(propose_tx_response) => { assert_eq!( - propose_tx_response.get_result(), + propose_tx_response.result(), ProposeTxResult::InvalidRangeProof ); - assert_eq!(propose_tx_response.get_block_count(), num_blocks); + assert_eq!(propose_tx_response.block_count, num_blocks); } Err(e) => panic!("Unexpected error: {e:?}"), } @@ -1141,10 +1138,10 @@ mod client_api_tests { match client.propose_mint_config_tx(&(&tx).into()) { Ok(propose_tx_response) => { assert_eq!( - propose_tx_response.get_result().get_code(), + propose_tx_response.result.unwrap().code(), MintValidationResultCode::Ok ); - assert_eq!(propose_tx_response.get_block_count(), num_blocks); + assert_eq!(propose_tx_response.block_count, num_blocks); } Err(e) => panic!("Unexpected error: {e:?}"), } @@ -1213,10 +1210,10 @@ mod client_api_tests { match client.propose_mint_config_tx(&(&tx).into()) { Ok(propose_tx_response) => { assert_eq!( - propose_tx_response.get_result().get_code(), + propose_tx_response.result.unwrap().code(), MintValidationResultCode::NonceAlreadyUsed ); - assert_eq!(propose_tx_response.get_block_count(), num_blocks); + assert_eq!(propose_tx_response.block_count, num_blocks); } Err(e) => panic!("Unexpected error: {e:?}"), } @@ -1454,10 +1451,10 @@ mod client_api_tests { match client.propose_mint_tx(&(&tx).into()) { Ok(propose_tx_response) => { assert_eq!( - propose_tx_response.get_result().get_code(), + propose_tx_response.result.unwrap().code(), MintValidationResultCode::Ok ); - assert_eq!(propose_tx_response.get_block_count(), num_blocks); + assert_eq!(propose_tx_response.block_count, num_blocks); } Err(e) => panic!("Unexpected error: {e:?}"), } @@ -1531,10 +1528,10 @@ mod client_api_tests { match client.propose_mint_tx(&(&tx).into()) { Ok(propose_tx_response) => { assert_eq!( - propose_tx_response.get_result().get_code(), + propose_tx_response.result.unwrap().code(), MintValidationResultCode::NonceAlreadyUsed ); - assert_eq!(propose_tx_response.get_block_count(), num_blocks); + assert_eq!(propose_tx_response.block_count, num_blocks); } Err(e) => panic!("Unexpected error: {e:?}"), } @@ -1805,8 +1802,8 @@ mod client_api_tests { let propose_tx_response = client .client_tx_propose(&message) .expect("Client tx propose error"); - assert_eq!(propose_tx_response.get_result(), ProposeTxResult::Ok); - assert_eq!(propose_tx_response.get_block_count(), NUM_BLOCKS); + assert_eq!(propose_tx_response.result(), ProposeTxResult::Ok); + assert_eq!(propose_tx_response.block_count, NUM_BLOCKS); let tracker = tracked_sessions .lock() diff --git a/consensus/service/src/api/grpc_error.rs b/consensus/service/src/api/grpc_error.rs index b99c9d34f3..746350ac77 100644 --- a/consensus/service/src/api/grpc_error.rs +++ b/consensus/service/src/api/grpc_error.rs @@ -145,17 +145,17 @@ impl From for RpcStatus { impl From for Result { fn from(src: ConsensusGrpcError) -> Result { match src { - ConsensusGrpcError::TransactionValidation(err) => { - let mut resp = ProposeTxResponse::new(); - resp.set_err_msg(err.to_string()); - resp.set_result(ProposeTxResult::from(err)); - Ok(resp) - } + ConsensusGrpcError::TransactionValidation(err) => Ok(ProposeTxResponse { + err_msg: err.to_string(), + result: ProposeTxResult::from(err).into(), + ..Default::default() + }), ConsensusGrpcError::Enclave(EnclaveError::FeeMapDigestMismatch) => { - let mut resp = ProposeTxResponse::new(); - resp.set_err_msg(EnclaveError::FeeMapDigestMismatch.to_string()); - resp.set_result(ProposeTxResult::FeeMapDigestMismatch); - Ok(resp) + Ok(ProposeTxResponse { + err_msg: EnclaveError::FeeMapDigestMismatch.to_string(), + result: ProposeTxResult::FeeMapDigestMismatch.into(), + ..Default::default() + }) } _ => Err(RpcStatus::from(src)), @@ -169,7 +169,7 @@ impl From for Result fn from(src: ConsensusGrpcError) -> Result { match src { ConsensusGrpcError::MintValidation(err) => Ok(ProposeMintConfigTxResponse { - result: Some(MintValidationResult::from(err)).into(), + result: Some(MintValidationResult::from(err)), ..Default::default() }), _ => Err(RpcStatus::from(src)), @@ -183,7 +183,7 @@ impl From for Result { fn from(src: ConsensusGrpcError) -> Result { match src { ConsensusGrpcError::MintValidation(err) => Ok(ProposeMintTxResponse { - result: Some(MintValidationResult::from(err)).into(), + result: Some(MintValidationResult::from(err)), ..Default::default() }), _ => Err(RpcStatus::from(src)), diff --git a/consensus/service/src/api/peer_api_service.rs b/consensus/service/src/api/peer_api_service.rs index 4ca9fc61a3..c47b403eae 100644 --- a/consensus/service/src/api/peer_api_service.rs +++ b/consensus/service/src/api/peer_api_service.rs @@ -20,11 +20,10 @@ use mc_common::{ use mc_consensus_api::{ consensus_common::ProposeTxResponse, consensus_peer::{ - ConsensusMsg as GrpcConsensusMsg, ConsensusMsgResponse, ConsensusMsgResult, - GetLatestMsgResponse, GetTxsRequest, GetTxsResponse, TxHashesNotInCache, + get_txs_response, ConsensusMsg as GrpcConsensusMsg, ConsensusMsgResponse, + ConsensusMsgResult, ConsensusPeerApi, GetLatestMsgResponse, GetTxsRequest, GetTxsResponse, + TxHashesNotInCache, }, - consensus_peer_grpc::ConsensusPeerApi, - empty::Empty, }; use mc_consensus_enclave::{ConsensusEnclave, Error}; use mc_ledger_db::Ledger; @@ -241,11 +240,10 @@ impl ConsensusPeerApi for PeerApiService { mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { let result: Result = match self.handle_tx_propose(enclave_msg, logger) { - Ok(num_blocks) => { - let mut response = ProposeTxResponse::new(); - response.set_block_count(num_blocks); - Ok(response) - } + Ok(num_blocks) => Ok(ProposeTxResponse { + block_count: num_blocks, + ..Default::default() + }), Err(err @ PeerServiceError::Enclave(Error::Attest(_))) => { Err(rpc_permissions_error("peer_tx_propose", err, logger)) @@ -267,7 +265,7 @@ impl ConsensusPeerApi for PeerApiService { let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { // The peer who delivered this message to us. - let from_responder_id = match ResponderId::from_str(request.get_from_responder_id()) { + let from_responder_id = match ResponderId::from_str(&request.from_responder_id) { Ok(responder_id) => responder_id, Err(_) => { let result = Err(rpc_invalid_arg_error( @@ -280,32 +278,29 @@ impl ConsensusPeerApi for PeerApiService { } }; - let consensus_msg: mc_peers::ConsensusMsg = match deserialize(request.get_payload()) { - Ok(consensus_msg) => consensus_msg, - Err(_) => { - let result = Err(rpc_invalid_arg_error( - "send_consensus_msg", - "consensus_msg", - logger, - )); - send_result(ctx, sink, result, logger); - return; - } - }; + let consensus_msg: mc_peers::ConsensusMsg = + match deserialize(request.payload.as_slice()) { + Ok(consensus_msg) => consensus_msg, + Err(_) => { + let result = Err(rpc_invalid_arg_error( + "send_consensus_msg", + "consensus_msg", + logger, + )); + send_result(ctx, sink, result, logger); + return; + } + }; let result: Result = match self .handle_consensus_msg(consensus_msg, from_responder_id) { - Ok(()) => { - let mut response = ConsensusMsgResponse::new(); - response.set_result(ConsensusMsgResult::Ok); - Ok(response) - } - Err(PeerServiceError::UnknownPeer(_)) => { - let mut response = ConsensusMsgResponse::new(); - response.set_result(ConsensusMsgResult::UnknownPeer); - Ok(response) - } + Ok(()) => Ok(ConsensusMsgResponse { + result: ConsensusMsgResult::Ok.into(), + }), + Err(PeerServiceError::UnknownPeer(_)) => Ok(ConsensusMsgResponse { + result: ConsensusMsgResult::UnknownPeer.into(), + }), Err(PeerServiceError::ConsensusMsgInvalidSignature) => Err(rpc_invalid_arg_error( "send_consensus_msg", "InvalidConsensusMsgSignature", @@ -326,17 +321,17 @@ impl ConsensusPeerApi for PeerApiService { fn get_latest_msg( &mut self, ctx: RpcContext, - _request: Empty, + _request: (), sink: UnarySink, ) { let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { - let mut response = GetLatestMsgResponse::new(); - if let Some(latest_msg) = (self.fetch_latest_msg_fn)() { - let serialized_msg = mc_util_serial::serialize(&latest_msg) - .expect("Failed serializing consensus msg"); - response.set_payload(serialized_msg); - } + let payload = if let Some(latest_msg) = (self.fetch_latest_msg_fn)() { + mc_util_serial::serialize(&latest_msg).expect("Failed serializing consensus msg") + } else { + Vec::new() + }; + let response = GetLatestMsgResponse { payload }; send_result(ctx, sink, Ok(response), logger); }); } @@ -352,7 +347,7 @@ impl ConsensusPeerApi for PeerApiService { let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { let mut tx_hashes: Vec = Vec::new(); - for tx_hash_bytes in request.get_tx_hashes() { + for tx_hash_bytes in request.tx_hashes.iter() { match TxHash::try_from(&tx_hash_bytes[..]) { Ok(tx_hash) => tx_hashes.push(tx_hash), Err(_) => { @@ -363,24 +358,22 @@ impl ConsensusPeerApi for PeerApiService { } } - let peer_session = PeerSession::from(request.get_channel_id()); + let peer_session = PeerSession::from(request.channel_id); let result: Result = match self.handle_get_txs(tx_hashes, peer_session, logger) { - Ok(enclave_message) => { - let mut response = GetTxsResponse::new(); - response.set_success(enclave_message.into()); - Ok(response) - } + Ok(enclave_message) => Ok(GetTxsResponse { + payload: Some(get_txs_response::Payload::Success(enclave_message.into())), + }), Err(PeerServiceError::UnknownTransactions(tx_hashes)) => { - let mut tx_hashes_not_in_cache = TxHashesNotInCache::new(); - tx_hashes_not_in_cache.set_tx_hashes( - tx_hashes.iter().map(|tx_hash| tx_hash.to_vec()).collect(), - ); - - let mut response = GetTxsResponse::new(); - response.set_tx_hashes_not_in_cache(tx_hashes_not_in_cache); - Ok(response) + let tx_hashes_not_in_cache = TxHashesNotInCache { + tx_hashes: tx_hashes.iter().map(|tx_hash| tx_hash.to_vec()).collect(), + }; + Ok(GetTxsResponse { + payload: Some(get_txs_response::Payload::TxHashesNotInCache( + tx_hashes_not_in_cache, + )), + }) } // Unexpected errors: Err(err) => Err(rpc_internal_error("get_txs", err, logger)), @@ -400,9 +393,8 @@ mod tests { }; use mc_blockchain_types::Block; use mc_common::{logger::test_with_logger, NodeID}; - use mc_consensus_api::{ - consensus_peer::ConsensusMsg, - consensus_peer_grpc::{create_consensus_peer_api, ConsensusPeerApiClient}, + use mc_consensus_api::consensus_peer::{ + create_consensus_peer_api, ConsensusMsg, ConsensusPeerApiClient, }; use mc_consensus_enclave_mock::MockConsensusEnclave; use mc_consensus_scp::{ @@ -519,14 +511,15 @@ mod tests { mc_peers::ConsensusMsg::from_scp_msg(&ledger, scp_msg, &node_x_signer_key).unwrap() }; - let mut message = ConsensusMsg::new(); - message.set_from_responder_id(from.to_string()); - message.set_payload(mc_util_serial::serialize(&payload).unwrap()); + let message = ConsensusMsg { + from_responder_id: from.to_string(), + payload: mc_util_serial::serialize(&payload).unwrap(), + }; match client.send_consensus_msg(&message) { Ok(consensus_msg_response) => { assert_eq!( - consensus_msg_response.get_result(), + consensus_msg_response.result(), ConsensusMsgResult::UnknownPeer ); } @@ -593,13 +586,14 @@ mod tests { mc_peers::ConsensusMsg::from_scp_msg(&ledger, scp_msg, &node_a_signer_key).unwrap() }; - let mut message = ConsensusMsg::new(); - message.set_from_responder_id(from.to_string()); - message.set_payload(mc_util_serial::serialize(&payload).unwrap()); + let message = ConsensusMsg { + from_responder_id: from.to_string(), + payload: mc_util_serial::serialize(&payload).unwrap(), + }; match client.send_consensus_msg(&message) { Ok(consensus_msg_response) => { - assert_eq!(consensus_msg_response.get_result(), ConsensusMsgResult::Ok); + assert_eq!(consensus_msg_response.result(), ConsensusMsgResult::Ok); } Err(e) => panic!("Unexpected error: {e:?}"), } @@ -633,10 +627,11 @@ mod tests { // A message from a known peer. The payload does not deserialize to a // ConsensusMsg. - let mut message = ConsensusMsg::new(); let from = known_responder_ids[0].clone(); - message.set_from_responder_id(from.to_string()); - message.set_payload(vec![240, 159, 146, 150]); // UTF-8 "sparkle heart". + let message = ConsensusMsg { + from_responder_id: from.to_string(), + payload: vec![240, 159, 146, 150], // UTF-8 "sparkle heart". + }; match client.send_consensus_msg(&message) { Ok(response) => panic!("Unexpected response: {response:?}"), @@ -711,9 +706,10 @@ mod tests { mc_peers::ConsensusMsg::from_scp_msg(&ledger, scp_msg, &wrong_signer_key).unwrap() }; - let mut message = ConsensusMsg::new(); - message.set_from_responder_id(from.to_string()); - message.set_payload(mc_util_serial::serialize(&payload).unwrap()); + let message = ConsensusMsg { + from_responder_id: from.to_string(), + payload: mc_util_serial::serialize(&payload).unwrap(), + }; match client.send_consensus_msg(&message) { Ok(response) => panic!("Unexpected response: {response:?}"), diff --git a/consensus/service/src/consensus_service.rs b/consensus/service/src/consensus_service.rs index cc320e7db7..87aa191edc 100644 --- a/consensus/service/src/consensus_service.rs +++ b/consensus/service/src/consensus_service.rs @@ -18,7 +18,7 @@ use base64::{engine::general_purpose::URL_SAFE as URL_SAFE_BASE64_ENGINE, Engine use displaydoc::Display; use futures::executor::block_on; use grpcio::{EnvBuilder, Environment, Server, ServerBuilder}; -use mc_attest_api::attest_grpc::create_attested_api; +use mc_attest_api::attest::create_attested_api; use mc_attest_enclave_api::{ClientSession, PeerSession}; use mc_common::{ logger::{log, Logger}, @@ -26,7 +26,7 @@ use mc_common::{ LruCache, NodeID, ResponderId, }; use mc_connection::{Connection, ConnectionManager}; -use mc_consensus_api::{consensus_client_grpc, consensus_common_grpc, consensus_peer_grpc}; +use mc_consensus_api::{consensus_client, consensus_common, consensus_peer}; use mc_consensus_enclave::{ConsensusEnclave, Error as ConsensusEnclaveError}; use mc_consensus_service_config::{Config, Error as ConfigError}; use mc_crypto_keys::DistinguishedEncoding; @@ -334,19 +334,18 @@ impl< // Setup GRPC services. let enclave = Arc::new(self.enclave.clone()); - let client_service = - consensus_client_grpc::create_consensus_client_api(ClientApiService::new( - self.config.clone(), - enclave.clone(), - self.create_scp_client_value_sender_fn(), - Arc::new(self.ledger_db.clone()), - self.tx_manager.clone(), - self.mint_tx_manager.clone(), - self.create_is_serving_user_requests_fn(), - self.client_authenticator.clone(), - self.logger.clone(), - self.tracked_sessions.clone(), - )); + let client_service = consensus_client::create_consensus_client_api(ClientApiService::new( + self.config.clone(), + enclave.clone(), + self.create_scp_client_value_sender_fn(), + Arc::new(self.ledger_db.clone()), + self.tx_manager.clone(), + self.mint_tx_manager.clone(), + self.create_is_serving_user_requests_fn(), + self.client_authenticator.clone(), + self.logger.clone(), + self.tracked_sessions.clone(), + )); let attested_service = create_attested_api(AttestedApiService::::new( self.config.chain_id.clone(), @@ -356,7 +355,7 @@ impl< )); let blockchain_service = - consensus_common_grpc::create_blockchain_api(BlockchainApiService::new( + consensus_common::create_blockchain_api(BlockchainApiService::new( self.ledger_db.clone(), self.client_authenticator.clone(), self.config.tokens().fee_map()?, @@ -368,9 +367,9 @@ impl< let health_check_callback: Arc HealthCheckStatus + Sync + Send> = Arc::new(move |_| { if is_serving_user_requests() { - HealthCheckStatus::SERVING + HealthCheckStatus::Serving } else { - HealthCheckStatus::NOT_SERVING + HealthCheckStatus::NotServing } }); let health_service = @@ -455,7 +454,7 @@ impl< }); let blockchain_service = - consensus_common_grpc::create_blockchain_api(BlockchainApiService::new( + consensus_common::create_blockchain_api(BlockchainApiService::new( self.ledger_db.clone(), peer_authenticator.clone(), self.config.tokens().fee_map()?, @@ -463,7 +462,7 @@ impl< self.logger.clone(), )); - let peer_service = consensus_peer_grpc::create_consensus_peer_api(PeerApiService::new( + let peer_service = consensus_peer::create_consensus_peer_api(PeerApiService::new( Arc::new(self.enclave.clone()), Arc::new(self.ledger_db.clone()), self.tx_manager.clone(), diff --git a/consensus/tool/Cargo.toml b/consensus/tool/Cargo.toml index 2c196058cc..e62fd76ebf 100644 --- a/consensus/tool/Cargo.toml +++ b/consensus/tool/Cargo.toml @@ -15,5 +15,5 @@ mc-util-grpc = { path = "../../util/grpc" } mc-util-uri = { path = "../../util/uri" } clap = { version = "4.5", features = ["derive", "env"] } -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } serde_json = "1" diff --git a/consensus/tool/src/main.rs b/consensus/tool/src/main.rs index b2d739f746..fef0b5019f 100644 --- a/consensus/tool/src/main.rs +++ b/consensus/tool/src/main.rs @@ -8,7 +8,7 @@ use clap::{Parser, Subcommand}; use grpcio::{ChannelBuilder, EnvBuilder}; use mc_common::logger::{create_app_logger, o}; use mc_connection::BlockInfo; -use mc_consensus_api::{consensus_common_grpc::BlockchainApiClient, empty::Empty}; +use mc_consensus_api::consensus_common::BlockchainApiClient; use mc_util_grpc::ConnectionUriGrpcioChannel; use mc_util_uri::ConsensusClientUri; use serde_json::to_string_pretty; @@ -96,9 +96,7 @@ fn main() { match config.tool_command { ToolCommand::Status => { for (uri, conn) in &blockchain_conns { - let last_block_info = conn - .get_last_block_info(&Empty::new()) - .expect("get last block info"); + let last_block_info = conn.get_last_block_info(&()).expect("get last block info"); let block_info = BlockInfo::from(last_block_info); @@ -112,7 +110,7 @@ fn main() { ToolCommand::WaitForBlock { index, period } => loop { let mut needs_retry = false; for (uri, conn) in &blockchain_conns { - match conn.get_last_block_info(&Empty::new()) { + match conn.get_last_block_info(&()) { Ok(last_block_info) => { if last_block_info.index < index { needs_retry = true; @@ -139,7 +137,7 @@ fn main() { let last_block_index = loop { let mut was_updated = false; for (uri, conn) in &blockchain_conns { - match conn.get_last_block_info(&Empty::new()) { + match conn.get_last_block_info(&()) { Ok(last_block_info) => { if last_block_index != Some(last_block_info.index) { last_block_index = Some(last_block_info.index); diff --git a/fog/api/Cargo.toml b/fog/api/Cargo.toml index 314a53dc54..45cf6405bc 100644 --- a/fog/api/Cargo.toml +++ b/fog/api/Cargo.toml @@ -11,9 +11,8 @@ rust-version = { workspace = true } [dependencies] displaydoc = { version = "0.2", default-features = false } futures = "0.3" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } prost = { version = "0.11", default-features = false, features = ["prost-derive"] } -protobuf = "2.27.1" mc-api = { path = "../../api" } mc-attest-api = { path = "../../attest/api" } diff --git a/fog/api/src/conversions.rs b/fog/api/src/conversions.rs index 2e3d434ca5..31592bf859 100644 --- a/fog/api/src/conversions.rs +++ b/fog/api/src/conversions.rs @@ -3,13 +3,14 @@ // Contains helper methods that enable conversions for Fog Api types. use crate::{ - fog_common, ingest_common, ledger::MultiKeyImageStoreRequest, view::MultiViewStoreQueryRequest, + fog_common, fog_ledger::MultiKeyImageStoreRequest, fog_view::MultiViewStoreQueryRequest, + ingest_common, }; use mc_api::ConversionError; use mc_attest_api::attest; use mc_attest_enclave_api::{EnclaveMessage, NonceSession}; use mc_crypto_keys::CompressedRistrettoPublic; -use mc_fog_types::{common, common::BlockRange, view::MultiViewStoreQueryResponseStatus}; +use mc_fog_types::{common, view::MultiViewStoreQueryResponseStatus}; use mc_fog_uri::{ConnectionUri, FogViewStoreUri}; use std::str::FromStr; @@ -25,10 +26,9 @@ impl From>> for MultiViewStoreQueryRequest { impl From> for MultiViewStoreQueryRequest { fn from(attested_query_messages: Vec) -> MultiViewStoreQueryRequest { - let mut multi_view_store_query_request = MultiViewStoreQueryRequest::new(); - multi_view_store_query_request.set_queries(attested_query_messages.into()); - - multi_view_store_query_request + Self { + queries: attested_query_messages, + } } } @@ -44,20 +44,18 @@ impl From>> for MultiKeyImageStoreRequest { impl From> for MultiKeyImageStoreRequest { fn from(attested_query_messages: Vec) -> MultiKeyImageStoreRequest { - let mut multi_key_image_store_request = MultiKeyImageStoreRequest::new(); - multi_key_image_store_request.set_queries(attested_query_messages.into()); - - multi_key_image_store_request + Self { + queries: attested_query_messages, + } } } impl From<&common::BlockRange> for fog_common::BlockRange { fn from(common_block_range: &common::BlockRange) -> fog_common::BlockRange { - let mut proto_block_range = fog_common::BlockRange::new(); - proto_block_range.start_block = common_block_range.start_block; - proto_block_range.end_block = common_block_range.end_block; - - proto_block_range + Self { + start_block: common_block_range.start_block, + end_block: common_block_range.end_block, + } } } @@ -70,7 +68,7 @@ impl From for common::BlockRange { impl TryFrom<&ingest_common::IngestSummary> for mc_fog_types::ingest_common::IngestSummary { type Error = ConversionError; fn try_from(proto_ingest_summary: &ingest_common::IngestSummary) -> Result { - let ingest_controller_mode = match proto_ingest_summary.mode { + let ingest_controller_mode = match proto_ingest_summary.mode() { ingest_common::IngestControllerMode::Idle => { mc_fog_types::ingest_common::IngestControllerMode::IDLE } @@ -78,15 +76,19 @@ impl TryFrom<&ingest_common::IngestSummary> for mc_fog_types::ingest_common::Ing mc_fog_types::ingest_common::IngestControllerMode::ACTIVE } }; - let ingress_pubkey: CompressedRistrettoPublic = - CompressedRistrettoPublic::try_from(proto_ingest_summary.get_ingress_pubkey())?; + let ingress_pubkey: CompressedRistrettoPublic = CompressedRistrettoPublic::try_from( + proto_ingest_summary + .ingress_pubkey + .as_ref() + .unwrap_or(&Default::default()), + )?; let result = mc_fog_types::ingest_common::IngestSummary { ingest_controller_mode, next_block_index: proto_ingest_summary.next_block_index, pubkey_expiry_window: proto_ingest_summary.pubkey_expiry_window, ingress_pubkey, - egress_pubkey: proto_ingest_summary.get_egress_pubkey().to_vec(), + egress_pubkey: proto_ingest_summary.egress_pubkey.to_vec(), kex_rng_version: proto_ingest_summary.kex_rng_version, peers: proto_ingest_summary.peers.to_vec(), ingest_invocation_id: proto_ingest_summary.ingest_invocation_id, @@ -96,39 +98,42 @@ impl TryFrom<&ingest_common::IngestSummary> for mc_fog_types::ingest_common::Ing } } -impl TryFrom +impl TryFrom for mc_fog_types::view::MultiViewStoreQueryResponse { type Error = ConversionError; fn try_from( - mut proto_response: crate::view::MultiViewStoreQueryResponse, + proto_response: crate::fog_view::MultiViewStoreQueryResponse, ) -> Result { let store_responder_id = - FogViewStoreUri::from_str(proto_response.get_store_uri())?.responder_id()?; + FogViewStoreUri::from_str(&proto_response.store_uri)?.responder_id()?; + let status = proto_response.status(); let result = mc_fog_types::view::MultiViewStoreQueryResponse { - encrypted_query_response: proto_response.take_query_response().into(), + encrypted_query_response: proto_response.query_response.unwrap_or_default().into(), store_responder_id, - store_uri: proto_response.get_store_uri().to_string(), - status: proto_response.get_status().into(), - block_range: BlockRange::from(proto_response.take_block_range()), + store_uri: proto_response.store_uri.to_string(), + status: status.into(), + block_range: proto_response.block_range.unwrap_or_default().into(), }; Ok(result) } } -impl From for MultiViewStoreQueryResponseStatus { - fn from(proto_status: crate::view::MultiViewStoreQueryResponseStatus) -> Self { +impl From + for MultiViewStoreQueryResponseStatus +{ + fn from(proto_status: crate::fog_view::MultiViewStoreQueryResponseStatus) -> Self { match proto_status { - crate::view::MultiViewStoreQueryResponseStatus::UNKNOWN => { + crate::fog_view::MultiViewStoreQueryResponseStatus::Unknown => { MultiViewStoreQueryResponseStatus::Unknown } - crate::view::MultiViewStoreQueryResponseStatus::SUCCESS => { + crate::fog_view::MultiViewStoreQueryResponseStatus::Success => { MultiViewStoreQueryResponseStatus::Success } - crate::view::MultiViewStoreQueryResponseStatus::AUTHENTICATION_ERROR => { + crate::fog_view::MultiViewStoreQueryResponseStatus::AuthenticationError => { MultiViewStoreQueryResponseStatus::AuthenticationError } - crate::view::MultiViewStoreQueryResponseStatus::NOT_READY => { + crate::fog_view::MultiViewStoreQueryResponseStatus::NotReady => { MultiViewStoreQueryResponseStatus::NotReady } } diff --git a/fog/api/src/lib.rs b/fog/api/src/lib.rs index 48565cb680..36ec8562d9 100644 --- a/fog/api/src/lib.rs +++ b/fog/api/src/lib.rs @@ -1,21 +1,39 @@ #![allow(clippy::result_large_err)] -// workaround for #![allow(box_pointers)] in protobuf generated files. -#![allow(renamed_and_removed_lints)] mod autogenerated_code { // Expose proto data types from included third-party/external proto files. pub use mc_api::external; pub use mc_attest_api::attest; - pub use mc_fog_report_api::{report, report_grpc}; - pub use protobuf::well_known_types::Empty; + pub use mc_fog_report_api::fog_report; + // Include the auto-generated code. - // Needed due to how to the auto-generated code references the Empty message. - pub mod empty { - pub use protobuf::well_known_types::Empty; + pub mod account_ingest { + include!(concat!( + env!("OUT_DIR"), + "/protos-auto-gen/account_ingest.rs" + )); + } + pub mod fog_view { + include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/fog_view.rs")); + } + pub mod fog_ledger { + include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/fog_ledger.rs")); + } + pub mod ingest_common { + include!(concat!( + env!("OUT_DIR"), + "/protos-auto-gen/ingest_common.rs" + )); + } + pub mod kex_rng { + include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/kex_rng.rs")); + } + pub mod fog_common { + include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/fog_common.rs")); + } + pub mod ingest_peer { + include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/ingest_peer.rs")); } - - // Include the auto-generated code. - include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/mod.rs")); } pub use autogenerated_code::*; @@ -30,8 +48,8 @@ use std::{collections::BTreeSet, str::FromStr}; // For tests, we need to implement Eq on view::QueryRequest // They implement PartialEq but not Eq for some reason -impl Eq for autogenerated_code::view::QueryRequest {} -impl Eq for autogenerated_code::view::QueryRequestAAD {} +impl Eq for autogenerated_code::fog_view::QueryRequest {} +impl Eq for autogenerated_code::fog_view::QueryRequestAad {} impl Eq for autogenerated_code::kex_rng::KexRngPubkey {} impl Eq for autogenerated_code::kex_rng::StoredRng {} @@ -50,7 +68,7 @@ impl ingest_common::IngestSummary { // because of orphan rules use mc_fog_enclave_connection::EnclaveGrpcChannel; -impl EnclaveGrpcChannel for view_grpc::FogViewApiClient { +impl EnclaveGrpcChannel for fog_view::FogViewApiClient { fn auth( &mut self, msg: &attest::AuthMessage, @@ -67,7 +85,7 @@ impl EnclaveGrpcChannel for view_grpc::FogViewApiClient { } } -impl EnclaveGrpcChannel for ledger_grpc::FogKeyImageApiClient { +impl EnclaveGrpcChannel for fog_ledger::FogKeyImageApiClient { fn auth( &mut self, msg: &attest::AuthMessage, @@ -84,7 +102,7 @@ impl EnclaveGrpcChannel for ledger_grpc::FogKeyImageApiClient { } } -impl EnclaveGrpcChannel for ledger_grpc::FogMerkleProofApiClient { +impl EnclaveGrpcChannel for fog_ledger::FogMerkleProofApiClient { fn auth( &mut self, msg: &attest::AuthMessage, diff --git a/fog/api/tests/fog_types.rs b/fog/api/tests/fog_types.rs index ac7c955ea1..e311c98ab9 100644 --- a/fog/api/tests/fog_types.rs +++ b/fog/api/tests/fog_types.rs @@ -6,7 +6,7 @@ use mc_crypto_keys::RistrettoPrivate; use mc_fog_api::kex_rng; use mc_fog_kex_rng::{KexRngPubkey, StoredRng}; -use mc_fog_report_api_test_utils::{round_trip_message, round_trip_protobuf_object}; +use mc_fog_report_api_test_utils::round_trip_message; use mc_transaction_core::{ membership_proofs::Range, tx::{TxOut, TxOutMembershipElement, TxOutMembershipHash, TxOutMembershipProof}, @@ -22,7 +22,7 @@ use mc_watcher_api::TimestampResultCode; fn fog_view_query_request_round_trip() { { let test_val: mc_fog_types::view::QueryRequest = Default::default(); - round_trip_message::( + round_trip_message::( &test_val, ); } @@ -34,7 +34,7 @@ fn fog_view_query_request_round_trip() { .map(|_| <[u8; 32]>::sample(&mut rng).to_vec()) .collect(), }; - round_trip_message::( + round_trip_message::( &test_val, ); }); @@ -45,16 +45,14 @@ fn fog_view_query_request_round_trip() { #[test] fn fog_view_query_request_protobuf_round_trip() { run_with_several_seeds(|mut rng| { - let mut test_val = mc_fog_api::view::QueryRequest::new(); - for _ in 0..20 { - test_val - .get_txos - .push(<[u8; 32]>::sample(&mut rng).to_vec()); - } - round_trip_protobuf_object::< - mc_fog_api::view::QueryRequest, - mc_fog_types::view::QueryRequest, - >(&test_val); + let test_val = mc_fog_api::fog_view::QueryRequest { + get_txos: (0..20_usize) + .map(|_| <[u8; 32]>::sample(&mut rng).to_vec()) + .collect(), + }; + round_trip_message::( + &test_val, + ); }); } @@ -64,9 +62,10 @@ fn fog_view_query_request_protobuf_round_trip() { fn fog_view_query_request_aad_round_trip() { { let test_val: mc_fog_types::view::QueryRequestAAD = Default::default(); - round_trip_message::( - &test_val, - ); + round_trip_message::< + mc_fog_types::view::QueryRequestAAD, + mc_fog_api::fog_view::QueryRequestAad, + >(&test_val); } run_with_several_seeds(|mut rng| { @@ -74,9 +73,10 @@ fn fog_view_query_request_aad_round_trip() { start_from_user_event_id: rng.next_u64() as i64, start_from_block_index: rng.next_u64(), }; - round_trip_message::( - &test_val, - ); + round_trip_message::< + mc_fog_types::view::QueryRequestAAD, + mc_fog_api::fog_view::QueryRequestAad, + >(&test_val); }); } @@ -85,22 +85,24 @@ fn fog_view_query_request_aad_round_trip() { #[test] fn fog_view_query_request_aad_protobuf_round_trip() { run_with_several_seeds(|mut rng| { - let mut test_val = mc_fog_api::view::QueryRequestAAD::new(); - test_val.start_from_user_event_id = rng.next_u64() as i64; - test_val.start_from_block_index = rng.next_u64(); + let test_val = mc_fog_api::fog_view::QueryRequestAad { + start_from_user_event_id: rng.next_u64() as i64, + start_from_block_index: rng.next_u64(), + }; - round_trip_protobuf_object::< - mc_fog_api::view::QueryRequestAAD, + round_trip_message::< + mc_fog_api::fog_view::QueryRequestAad, mc_fog_types::view::QueryRequestAAD, >(&test_val); }); run_with_several_seeds(|mut rng| { - let mut test_val = mc_fog_api::view::QueryRequestAAD::new(); - test_val.start_from_user_event_id = rng.next_u64() as i64; - test_val.start_from_block_index = rng.next_u64(); - round_trip_protobuf_object::< - mc_fog_api::view::QueryRequestAAD, + let test_val = mc_fog_api::fog_view::QueryRequestAad { + start_from_user_event_id: rng.next_u64() as i64, + start_from_block_index: rng.next_u64(), + }; + round_trip_message::< + mc_fog_api::fog_view::QueryRequestAad, mc_fog_types::view::QueryRequestAAD, >(&test_val); }); @@ -112,7 +114,7 @@ fn fog_view_query_request_aad_protobuf_round_trip() { fn fog_view_query_response_round_trip() { { let test_val: mc_fog_types::view::QueryResponse = Default::default(); - round_trip_message::( + round_trip_message::( &test_val, ); } @@ -136,7 +138,7 @@ fn fog_view_query_response_round_trip() { last_known_block_cumulative_txo_count: rng.next_u32() as u64, tx_out_search_results: vec![], }; - round_trip_message::( + round_trip_message::( &test_val, ); }); @@ -160,7 +162,7 @@ fn fog_view_query_response_round_trip() { last_known_block_cumulative_txo_count: rng.next_u32() as u64, tx_out_search_results: vec![], }; - round_trip_message::( + round_trip_message::( &test_val, ); }); @@ -191,7 +193,7 @@ fn fog_view_query_response_round_trip() { last_known_block_cumulative_txo_count: rng.next_u32() as u64, tx_out_search_results: vec![], }; - round_trip_message::( + round_trip_message::( &test_val, ); }); @@ -203,7 +205,7 @@ fn fog_view_query_response_round_trip() { fn tx_out_record_round_trip() { { let test_val: mc_fog_types::view::TxOutRecord = Default::default(); - round_trip_message::( + round_trip_message::( &test_val, ); } @@ -217,7 +219,7 @@ fn tx_out_record_round_trip() { }; let test_val = mc_fog_types::view::TxOutRecord::new(fog_txout, meta); - round_trip_message::( + round_trip_message::( &test_val, ); }); @@ -231,7 +233,7 @@ fn get_output_response_round_trip() { let test_val = mc_fog_types::ledger::GetOutputsResponse::default(); round_trip_message::< mc_fog_types::ledger::GetOutputsResponse, - mc_fog_api::ledger::GetOutputsResponse, + mc_fog_api::fog_ledger::GetOutputsResponse, >(&test_val); } @@ -245,7 +247,7 @@ fn get_output_response_round_trip() { round_trip_message::< mc_fog_types::ledger::GetOutputsResponse, - mc_fog_api::ledger::GetOutputsResponse, + mc_fog_api::fog_ledger::GetOutputsResponse, >(&test_val); }); } @@ -258,7 +260,7 @@ fn check_key_images_response_round_trip() { let test_val = mc_fog_types::ledger::CheckKeyImagesResponse::default(); round_trip_message::< mc_fog_types::ledger::CheckKeyImagesResponse, - mc_fog_api::ledger::CheckKeyImagesResponse, + mc_fog_api::fog_ledger::CheckKeyImagesResponse, >(&test_val); } @@ -276,7 +278,7 @@ fn check_key_images_response_round_trip() { round_trip_message::< mc_fog_types::ledger::CheckKeyImagesResponse, - mc_fog_api::ledger::CheckKeyImagesResponse, + mc_fog_api::fog_ledger::CheckKeyImagesResponse, >(&test_val); }); } @@ -287,23 +289,23 @@ fn check_key_images_response_round_trip() { fn test_tx_out_search_result_enum_values() { assert_eq!( mc_fog_types::view::TxOutSearchResultCode::Found as u32, - mc_fog_api::view::TxOutSearchResultCode::Found as u32 + mc_fog_api::fog_view::TxOutSearchResultCode::Found as u32 ); assert_eq!( mc_fog_types::view::TxOutSearchResultCode::NotFound as u32, - mc_fog_api::view::TxOutSearchResultCode::NotFound as u32 + mc_fog_api::fog_view::TxOutSearchResultCode::NotFound as u32 ); assert_eq!( mc_fog_types::view::TxOutSearchResultCode::BadSearchKey as u32, - mc_fog_api::view::TxOutSearchResultCode::BadSearchKey as u32 + mc_fog_api::fog_view::TxOutSearchResultCode::BadSearchKey as u32 ); assert_eq!( mc_fog_types::view::TxOutSearchResultCode::InternalError as u32, - mc_fog_api::view::TxOutSearchResultCode::InternalError as u32 + mc_fog_api::fog_view::TxOutSearchResultCode::InternalError as u32 ); assert_eq!( mc_fog_types::view::TxOutSearchResultCode::RateLimited as u32, - mc_fog_api::view::TxOutSearchResultCode::RateLimited as u32 + mc_fog_api::fog_view::TxOutSearchResultCode::RateLimited as u32 ); } @@ -312,15 +314,15 @@ fn test_tx_out_search_result_enum_values() { fn test_key_image_result_code_enum_values() { assert_eq!( mc_fog_types::ledger::KeyImageResultCode::Spent as u32, - mc_fog_api::ledger::KeyImageResultCode::Spent as u32 + mc_fog_api::fog_ledger::KeyImageResultCode::Spent as u32 ); assert_eq!( mc_fog_types::ledger::KeyImageResultCode::NotSpent as u32, - mc_fog_api::ledger::KeyImageResultCode::NotSpent as u32 + mc_fog_api::fog_ledger::KeyImageResultCode::NotSpent as u32 ); assert_eq!( mc_fog_types::ledger::KeyImageResultCode::KeyImageError as u32, - mc_fog_api::ledger::KeyImageResultCode::KeyImageError as u32 + mc_fog_api::fog_ledger::KeyImageResultCode::KeyImageError as u32 ); } @@ -338,11 +340,12 @@ fn test_kex_rng_pubkey_round_trip() { #[test] fn test_kex_rng_pubkey_round_trip_protobuf() { run_with_several_seeds(|mut rng| { - let mut test_val = kex_rng::KexRngPubkey::new(); - test_val.set_pubkey(<[u8; 32]>::sample(&mut rng).to_vec()); - test_val.version = rng.next_u32(); + let test_val = kex_rng::KexRngPubkey { + pubkey: <[u8; 32]>::sample(&mut rng).to_vec(), + version: rng.next_u32(), + }; - round_trip_protobuf_object::(&test_val); + round_trip_message::(&test_val); }); } @@ -365,13 +368,14 @@ fn test_stored_kex_rng_round_trip() { #[test] fn test_stored_kex_rng_round_trip_protobuf() { run_with_several_seeds(|mut rng| { - let mut test_val = kex_rng::StoredRng::new(); - test_val.set_secret(<[u8; 32]>::sample(&mut rng).to_vec()); - test_val.set_buffer(<[u8; 16]>::sample(&mut rng).to_vec()); - test_val.counter = rng.next_u64(); - test_val.version = rng.next_u32(); + let test_val = kex_rng::StoredRng { + secret: <[u8; 32]>::sample(&mut rng).to_vec(), + buffer: <[u8; 16]>::sample(&mut rng).to_vec(), + counter: rng.next_u64(), + version: rng.next_u32(), + }; - round_trip_protobuf_object::(&test_val); + round_trip_message::(&test_val); }); } diff --git a/fog/block_provider/Cargo.toml b/fog/block_provider/Cargo.toml index 82b6d57ccb..f9724a4537 100644 --- a/fog/block_provider/Cargo.toml +++ b/fog/block_provider/Cargo.toml @@ -22,6 +22,6 @@ mc-watcher-api = { path = "../../watcher/api" } displaydoc = "0.2" dyn-clone = "1.0.17" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } [dev-dependencies] diff --git a/fog/block_provider/src/lib.rs b/fog/block_provider/src/lib.rs index 6f6d3b7208..6be88e5d79 100644 --- a/fog/block_provider/src/lib.rs +++ b/fog/block_provider/src/lib.rs @@ -10,7 +10,7 @@ mod mobilecoind; use dyn_clone::DynClone; use mc_blockchain_types::{Block, BlockData, BlockIndex}; use mc_crypto_keys::CompressedRistrettoPublic; -use mc_fog_api::ledger::TxOutResult; +use mc_fog_api::fog_ledger::TxOutResult; use mc_transaction_core::tx::{TxOut, TxOutMembershipProof}; use mc_watcher_api::TimestampResultCode; use std::time::Duration; diff --git a/fog/block_provider/src/local.rs b/fog/block_provider/src/local.rs index 9f234f3eed..c3eac0bb34 100644 --- a/fog/block_provider/src/local.rs +++ b/fog/block_provider/src/local.rs @@ -5,7 +5,7 @@ use crate::{ }; use mc_blockchain_types::{Block, BlockIndex}; use mc_crypto_keys::CompressedRistrettoPublic; -use mc_fog_api::ledger::{TxOutResult, TxOutResultCode}; +use mc_fog_api::fog_ledger::{TxOutResult, TxOutResultCode}; use mc_ledger_db::{Error as LedgerError, Ledger}; use mc_transaction_core::tx::{TxOut, TxOutMembershipProof}; use mc_watcher::watcher_db::WatcherDB; @@ -30,13 +30,15 @@ impl LocalBlockProvider { &self, tx_out_pubkey: &CompressedRistrettoPublic, ) -> Result { - let mut result = TxOutResult::new(); - result.set_tx_out_pubkey(tx_out_pubkey.into()); + let mut result = TxOutResult { + tx_out_pubkey: Some(tx_out_pubkey.into()), + ..Default::default() + }; let tx_out_index = match self.ledger.get_tx_out_index_by_public_key(tx_out_pubkey) { Ok(index) => index, Err(LedgerError::NotFound) => { - result.result_code = TxOutResultCode::NotFound; + result.result_code = TxOutResultCode::NotFound.into(); return Ok(result); } Err(err) => { @@ -44,7 +46,7 @@ impl LocalBlockProvider { } }; - result.result_code = TxOutResultCode::Found; + result.result_code = TxOutResultCode::Found.into(); result.tx_out_global_index = tx_out_index; let block_index = match self.ledger.get_block_index_by_tx_out_index(tx_out_index) { @@ -57,7 +59,7 @@ impl LocalBlockProvider { // tx_out_index, // err // ); - result.result_code = TxOutResultCode::DatabaseError; + result.result_code = TxOutResultCode::DatabaseError.into(); return Ok(result); } }; diff --git a/fog/block_provider/src/mobilecoind.rs b/fog/block_provider/src/mobilecoind.rs index b749c7e2d8..f65e089d3e 100644 --- a/fog/block_provider/src/mobilecoind.rs +++ b/fog/block_provider/src/mobilecoind.rs @@ -9,7 +9,7 @@ use mc_blockchain_types::{Block, BlockData, BlockIndex}; use mc_common::logger::{log, Logger}; use mc_crypto_keys::CompressedRistrettoPublic; use mc_mobilecoind_api::{ - mobilecoind_api_grpc::MobilecoindApiClient, GetBlockRequest, GetBlocksDataRequest, + mobilecoind_api::MobilecoindApiClient, GetBlockRequest, GetBlocksDataRequest, GetMembershipProofsRequest, GetTxOutResultsByPubKeyRequest, MobilecoindUri, }; use mc_transaction_core::tx::{TxOut, TxOutMembershipProof}; @@ -54,13 +54,12 @@ impl BlockProvider for MobilecoindBlockProvider { fn get_latest_block(&self) -> Result { let response = self.client.get_latest_block(&Default::default())?; - Ok(response.get_block().try_into()?) + Ok((&response.block.unwrap_or_default()).try_into()?) } fn get_blocks_data(&self, block_indices: &[BlockIndex]) -> Result { let request = GetBlocksDataRequest { blocks: block_indices.to_vec(), - ..Default::default() }; let response = self.client.get_blocks_data(&request)?; @@ -73,14 +72,21 @@ impl BlockProvider for MobilecoindBlockProvider { } Ok(Some(BlockDataWithTimestamp { - block_data: BlockData::try_from(result.get_block_data())?, + block_data: BlockData::try_from( + result.block_data.as_ref().unwrap_or(&Default::default()), + )?, block_timestamp: result.timestamp, - block_timestamp_result_code: (&result.timestamp_result_code).try_into()?, + block_timestamp_result_code: (&result.timestamp_result_code()).try_into()?, })) }) .collect::, Error>>()?; - let latest_block = Block::try_from(response.get_latest_block())?; + let latest_block = Block::try_from( + response + .latest_block + .as_ref() + .unwrap_or(&Default::default()), + )?; Ok(BlocksDataResponse { results, @@ -94,17 +100,14 @@ impl BlockProvider for MobilecoindBlockProvider { return u64::MAX; } - let request = GetBlockRequest { - block: block_index, - ..Default::default() - }; + let request = GetBlockRequest { block: block_index }; // Timer that tracks how long we have had WatcherBehind error for, // if this exceeds watcher_timeout, we log a warning. let mut watcher_behind_timer = Instant::now(); loop { match self.client.get_block(&request) { - Ok(response) => match response.timestamp_result_code { + Ok(response) => match response.timestamp_result_code() { TimestampResultCode::WatcherBehind => { if watcher_behind_timer.elapsed() > watcher_timeout { log::warn!(self.logger, "watcher is still behind on block index = {} after waiting {} seconds, caller will be blocked", block_index, watcher_timeout.as_secs()); @@ -171,8 +174,18 @@ impl BlockProvider for MobilecoindBlockProvider { } let tx_out_with_proof = response.output_list.first().unwrap(); - let tx_out = TxOut::try_from(tx_out_with_proof.get_output())?; - let proof = TxOutMembershipProof::try_from(tx_out_with_proof.get_proof())?; + let tx_out = TxOut::try_from( + tx_out_with_proof + .output + .as_ref() + .unwrap_or(&Default::default()), + )?; + let proof = TxOutMembershipProof::try_from( + tx_out_with_proof + .proof + .as_ref() + .unwrap_or(&Default::default()), + )?; Ok((tx_out, proof)) } @@ -182,14 +195,18 @@ impl BlockProvider for MobilecoindBlockProvider { ) -> Result { let request = GetTxOutResultsByPubKeyRequest { tx_out_public_keys: tx_out_pub_keys.iter().map(|pk| pk.into()).collect(), - ..Default::default() }; let response = self.client.get_tx_out_results_by_pub_key(&request)?; - let latest_block = Block::try_from(response.get_latest_block())?; + let latest_block = Block::try_from( + response + .latest_block + .as_ref() + .unwrap_or(&Default::default()), + )?; Ok(TxOutInfoByPublicKeyResponse { - results: response.get_results().to_vec(), + results: response.results.to_vec(), latest_block, }) } diff --git a/fog/distribution/Cargo.toml b/fog/distribution/Cargo.toml index 11a4e10664..196708901a 100644 --- a/fog/distribution/Cargo.toml +++ b/fog/distribution/Cargo.toml @@ -31,7 +31,7 @@ mc-util-uri = { path = "../../util/uri" } clap = { version = "4.5", features = ["derive", "env"] } crossbeam-channel = "0.5" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } lazy_static = "1.4" mc-attestation-verifier = "0.4.3" rand = "0.8" diff --git a/fog/enclave_connection/Cargo.toml b/fog/enclave_connection/Cargo.toml index 007fb0303a..2406ab5c4c 100644 --- a/fog/enclave_connection/Cargo.toml +++ b/fog/enclave_connection/Cargo.toml @@ -24,7 +24,7 @@ aes-gcm = "0.10.3" cookie = "0.18" der = "0.7.8" displaydoc = { version = "0.2", default-features = false } -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } mc-attestation-verifier = "0.4.3" retry = "2.0" sha2 = { version = "0.10", default-features = false } diff --git a/fog/enclave_connection/src/lib.rs b/fog/enclave_connection/src/lib.rs index 1cacb3abf7..8206747218 100644 --- a/fog/enclave_connection/src/lib.rs +++ b/fog/enclave_connection/src/lib.rs @@ -217,15 +217,13 @@ impl EnclaveConnection { .as_mut() .expect("no enclave_connection even though attest succeeded"); - let mut msg = Message::new(); - msg.set_channel_id(Vec::from(attest_cipher.binding())); - msg.set_aad(aad.to_vec()); - let plaintext_bytes = mc_util_serial::encode(plaintext_request); - let request_ciphertext = attest_cipher.encrypt(aad, &plaintext_bytes)?; - msg.set_data(request_ciphertext); - msg + Message { + channel_id: attest_cipher.binding().to_vec(), + aad: aad.to_vec(), + data: request_ciphertext, + } }; // make an attested call to EnclaveGrpcChannel::enclave_request, @@ -256,7 +254,8 @@ impl EnclaveConnection { .as_mut() .expect("no enclave_connection even though attest succeeded"); - let plaintext_bytes = attest_cipher.decrypt(message.get_aad(), message.get_data())?; + let plaintext_bytes = + attest_cipher.decrypt(message.aad.as_slice(), message.data.as_slice())?; let plaintext_response: ResponseMessage = mc_util_serial::decode(&plaintext_bytes)?; Ok(plaintext_response) } diff --git a/fog/ingest/client/Cargo.toml b/fog/ingest/client/Cargo.toml index 19acacbff4..357003abc9 100644 --- a/fog/ingest/client/Cargo.toml +++ b/fog/ingest/client/Cargo.toml @@ -35,9 +35,8 @@ rand = "0.8" # third party clap = { version = "4.5", features = ["derive", "env"] } displaydoc = { version = "0.2", default-features = false } -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } hex = "0.4" -protobuf = "2.27.1" retry = "2.0" serde_json = "1.0" diff --git a/fog/ingest/client/src/lib.rs b/fog/ingest/client/src/lib.rs index 4f66f74223..9ec276fa81 100644 --- a/fog/ingest/client/src/lib.rs +++ b/fog/ingest/client/src/lib.rs @@ -8,19 +8,16 @@ use grpcio::{ChannelBuilder, Environment}; use mc_common::logger::{log, o, Logger}; use mc_crypto_keys::CompressedRistrettoPublic; use mc_fog_api::{ - empty::Empty, - ingest::{ - GetIngressKeyRecordsRequest, IngressPublicKeyRecord, ReportLostIngressKeyRequest, - SetPubkeyExpiryWindowRequest, SyncKeysFromRemoteRequest, + account_ingest::{ + AccountIngestApiClient, GetIngressKeyRecordsRequest, IngressPublicKeyRecord, + ReportLostIngressKeyRequest, SetPubkeyExpiryWindowRequest, SyncKeysFromRemoteRequest, }, ingest_common::{IngestSummary, SetPeersRequest}, - ingest_grpc::AccountIngestApiClient, }; use mc_fog_types::common::BlockRange; use mc_fog_uri::FogIngestUri; use mc_util_grpc::{BasicCredentials, ConnectionUriGrpcioChannel}; use mc_util_uri::ConnectionUri; -use protobuf::RepeatedField; use retry::{retry, Error as RetryError}; use std::{sync::Arc, time::Duration}; @@ -78,7 +75,7 @@ impl FogIngestGrpcClient { retry(self.get_retries(), || -> Result<_, Error> { Ok(self .ingest_api_client - .get_status_opt(&Empty::new(), self.creds.call_option()?)?) + .get_status_opt(&(), self.creds.call_option()?)?) }) } @@ -86,7 +83,7 @@ impl FogIngestGrpcClient { retry(self.get_retries(), || -> Result<_, Error> { Ok(self .ingest_api_client - .new_keys_opt(&Empty::default(), self.creds.call_option()?)?) + .new_keys_opt(&(), self.creds.call_option()?)?) }) } @@ -94,8 +91,9 @@ impl FogIngestGrpcClient { &self, pubkey_expiry_window: u64, ) -> ClientResult { - let mut req = SetPubkeyExpiryWindowRequest::new(); - req.set_pubkey_expiry_window(pubkey_expiry_window); + let req = SetPubkeyExpiryWindowRequest { + pubkey_expiry_window, + }; retry(self.get_retries(), || -> Result<_, Error> { Ok(self @@ -105,8 +103,9 @@ impl FogIngestGrpcClient { } pub fn set_peers(&self, peer_uris: &[String]) -> ClientResult { - let mut req = SetPeersRequest::new(); - req.set_ingest_peer_uris(RepeatedField::from_vec(peer_uris.to_vec())); + let req = SetPeersRequest { + ingest_peer_uris: peer_uris.to_vec(), + }; retry(self.get_retries(), || -> Result<_, Error> { Ok(self @@ -120,7 +119,7 @@ impl FogIngestGrpcClient { retry(self.get_retries(), || -> Result<_, Error> { Ok(self .ingest_api_client - .activate_opt(&Empty::default(), self.creds.call_option()?)?) + .activate_opt(&(), self.creds.call_option()?)?) }) } @@ -128,7 +127,7 @@ impl FogIngestGrpcClient { retry(self.get_retries(), || -> Result<_, Error> { Ok(self .ingest_api_client - .retire_opt(&Empty::default(), self.creds.call_option()?)?) + .retire_opt(&(), self.creds.call_option()?)?) }) } @@ -136,17 +135,18 @@ impl FogIngestGrpcClient { retry(self.get_retries(), || -> Result<_, Error> { Ok(self .ingest_api_client - .unretire_opt(&Empty::default(), self.creds.call_option()?)?) + .unretire_opt(&(), self.creds.call_option()?)?) }) } pub fn report_lost_ingress_key(&self, key: CompressedRistrettoPublic) -> ClientResult<()> { log::trace!(self.logger, "report_lost_ingress_key({})", key,); - let mut req = ReportLostIngressKeyRequest::new(); - req.set_key((&key).into()); + let req = ReportLostIngressKeyRequest { + key: Some((&key).into()), + }; - let _ = retry(self.get_retries(), || -> Result<_, Error> { + retry(self.get_retries(), || -> Result<_, Error> { Ok(self .ingest_api_client .report_lost_ingress_key_opt(&req, self.creds.call_option()?)?) @@ -159,11 +159,11 @@ impl FogIngestGrpcClient { let resp = retry(self.get_retries(), || -> Result<_, Error> { Ok(self .ingest_api_client - .get_status_opt(&Empty::new(), self.creds.call_option()?)?) + .get_status_opt(&(), self.creds.call_option()?)?) })?; Ok( - CompressedRistrettoPublic::try_from(resp.get_ingress_pubkey()) + CompressedRistrettoPublic::try_from(&resp.ingress_pubkey.unwrap_or_default()) .expect("Got back invalid compressed ristretto point"), ) } @@ -174,11 +174,11 @@ impl FogIngestGrpcClient { let resp = retry(self.get_retries(), || -> Result<_, Error> { Ok(self .ingest_api_client - .get_missed_block_ranges_opt(&Empty::default(), self.creds.call_option()?)?) + .get_missed_block_ranges_opt(&(), self.creds.call_option()?)?) })?; Ok(resp - .get_missed_block_ranges() + .missed_block_ranges .iter() .map(|range| BlockRange::new(range.start_block, range.end_block)) .collect()) @@ -186,8 +186,9 @@ impl FogIngestGrpcClient { pub fn sync_keys_from_remote(&self, peer_uri: String) -> ClientResult { log::trace!(self.logger, "sync_keys_from_remote()"); - let mut req = SyncKeysFromRemoteRequest::new(); - req.set_peer_uri(peer_uri); + let req = SyncKeysFromRemoteRequest { + peer_uri: peer_uri.clone(), + }; retry(self.get_retries(), || -> Result<_, Error> { Ok(self @@ -204,10 +205,12 @@ impl FogIngestGrpcClient { ) -> ClientResult> { log::trace!(self.logger, "get_ingress_key_records()"); - let mut req = GetIngressKeyRecordsRequest::new(); - req.set_start_block_at_least(start_block_at_least); - req.set_should_include_lost_keys(should_include_lost_keys); - req.set_should_include_retired_keys(should_include_retired_keys); + let req = GetIngressKeyRecordsRequest { + start_block_at_least, + should_include_lost_keys, + should_include_retired_keys, + ..Default::default() + }; let resp = retry(self.get_retries(), || -> Result<_, Error> { Ok(self @@ -215,7 +218,7 @@ impl FogIngestGrpcClient { .get_ingress_key_records_opt(&req, self.creds.call_option()?)?) })?; - Ok(resp.get_records().to_vec()) + Ok(resp.records.to_vec()) } // The retry crate works by taking an iterator over durations, and a closure diff --git a/fog/ingest/client/src/main.rs b/fog/ingest/client/src/main.rs index 1958536554..28d34c6e61 100644 --- a/fog/ingest/client/src/main.rs +++ b/fog/ingest/client/src/main.rs @@ -204,7 +204,7 @@ fn get_ingress_key_records( .iter() .map(|record| { json!({ - "ingress_public_key": hex::encode(record.get_ingress_public_key().get_data()), + "ingress_public_key": hex::encode(&record.ingress_public_key.as_ref().expect("Missing ingress public key").data), "start_block": record.start_block, "pubkey_expiry": record.pubkey_expiry, "retired": record.retired, @@ -224,10 +224,10 @@ fn ingest_summary_to_json(summary: &IngestSummary) -> String { "mode": format!("{:?}", summary.mode), "next_block_index": summary.next_block_index, "pubkey_expiry_window": summary.pubkey_expiry_window, - "ingress_pubkey": hex::encode(summary.get_ingress_pubkey().get_data()), - "egress_pubkey": hex::encode(summary.get_egress_pubkey()), + "ingress_pubkey": hex::encode(&summary.ingress_pubkey.as_ref().expect("Missing ingress public key").data), + "egress_pubkey": hex::encode(&summary.egress_pubkey), "kex_rng_version": summary.kex_rng_version, - "peers": summary.get_peers(), + "peers": summary.peers, "ingest_invocation_id": summary.ingest_invocation_id, })) .expect("could not pretty print") diff --git a/fog/ingest/server/Cargo.toml b/fog/ingest/server/Cargo.toml index 1e4748c65e..f00a1b9a6a 100644 --- a/fog/ingest/server/Cargo.toml +++ b/fog/ingest/server/Cargo.toml @@ -17,11 +17,10 @@ clap = { version = "4.5", features = ["derive", "env"] } dirs = "5.0" displaydoc = { version = "0.2", default-features = false } futures = "0.3" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } hex = "0.4" itertools = "0.12" lazy_static = "1.4" -protobuf = "2.27.1" retry = "2.0" serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } serde_json = "1.0" diff --git a/fog/ingest/server/src/attested_api_service.rs b/fog/ingest/server/src/attested_api_service.rs index 623c9ab0bd..7d864a7d4e 100644 --- a/fog/ingest/server/src/attested_api_service.rs +++ b/fog/ingest/server/src/attested_api_service.rs @@ -4,7 +4,7 @@ use crate::{controller::IngestController, error::IngestServiceError, SVC_COUNTERS}; use grpcio::{RpcContext, UnarySink}; -use mc_attest_api::{attest::AuthMessage, attest_grpc::AttestedApi}; +use mc_attest_api::attest::{AttestedApi, AuthMessage}; use mc_common::logger::{log, Logger}; use mc_fog_recovery_db_iface::{RecoveryDb, ReportDb}; use mc_util_grpc::{rpc_logger, rpc_permissions_error, send_result}; diff --git a/fog/ingest/server/src/connection.rs b/fog/ingest/server/src/connection.rs index 02b3d93de9..33b0d85241 100644 --- a/fog/ingest/server/src/connection.rs +++ b/fog/ingest/server/src/connection.rs @@ -8,7 +8,7 @@ use crate::{ }; use core::fmt::{Display, Formatter, Result as FmtResult}; use grpcio::{ChannelBuilder, Environment}; -use mc_attest_api::{attest::Message, attest_grpc::AttestedApiClient}; +use mc_attest_api::attest::{AttestedApiClient, Message}; use mc_attest_core::EvidenceKind; use mc_attest_enclave_api::PeerSession; use mc_common::{ @@ -19,8 +19,7 @@ use mc_connection::{AttestedConnection, Connection}; use mc_crypto_keys::CompressedRistrettoPublic; use mc_fog_api::{ ingest_common::{IngestSummary, SetPeersRequest}, - ingest_peer::GetPrivateKeyRequest, - ingest_peer_grpc::AccountIngestPeerApiClient, + ingest_peer::{AccountIngestPeerApiClient, GetPrivateKeyRequest}, }; use mc_fog_ingest_enclave_api::IngestEnclaveProxy; use mc_fog_uri::IngestPeerUri; @@ -181,17 +180,16 @@ impl IngestConnection for PeerConnection { trace_time!(self.logger, "PeerConnection::get_status"); // This call is not attested - let request = Default::default(); - Ok(self.ingest_peer_api_client.get_status(&request)?) + Ok(self.ingest_peer_api_client.get_status(&())?) } fn set_peers(&mut self, peers: BTreeSet) -> Result { trace_time!(self.logger, "PeerConnection::set_peers"); // This call is not attested - let mut request = SetPeersRequest::new(); - request.ingest_peer_uris = - protobuf::RepeatedField::from_vec(peers.iter().map(|x| x.to_string()).collect()); + let request = SetPeersRequest { + ingest_peer_uris: peers.iter().map(|x| x.to_string()).collect(), + }; Ok(self.ingest_peer_api_client.set_peers(&request)?) } @@ -204,8 +202,9 @@ impl IngestConnection for PeerConnection { match self.channel_id.clone() { Some(peer_session) => { - let mut request = GetPrivateKeyRequest::new(); - request.set_channel_id(peer_session.into()); + let request = GetPrivateKeyRequest { + channel_id: peer_session.into(), + }; let message = self.attested_call(|this| { this.ingest_peer_api_client diff --git a/fog/ingest/server/src/controller.rs b/fog/ingest/server/src/controller.rs index 98ac925b28..61f5e0b2ae 100644 --- a/fog/ingest/server/src/controller.rs +++ b/fog/ingest/server/src/controller.rs @@ -204,7 +204,8 @@ where // Attempt to restore state from state file if provided // NotFound is not an error, but otherwise it is an error. if let Some(ref file_data) = state_file_data { - let summary = file_data.get_summary(); + let default_summary = Default::default(); + let summary = file_data.summary.as_ref().unwrap_or(&default_summary); let mut retry_seconds = 1; loop { match result.restore_state_from_summary(summary) { @@ -723,7 +724,7 @@ where for conn in peer_connections.iter_mut() { match conn.get_status() { Ok(summary) => { - match summary.mode { + match summary.mode() { IngestControllerMode::Active => { let uri = conn.uri(); log::error!( @@ -1016,8 +1017,8 @@ where .enclave .get_kex_rng_pubkey() .expect("Failed to get kex rng pubkey"); - result.set_ingress_pubkey((&ingress_pubkey).into()); - result.set_egress_pubkey(kex_rng_pubkey.public_key); + result.ingress_pubkey = Some((&ingress_pubkey).into()); + result.egress_pubkey = kex_rng_pubkey.public_key; result.kex_rng_version = kex_rng_pubkey.version; result } @@ -1046,9 +1047,13 @@ where let new_peers = state_data.get_sorted_peers()?; let ingress_pubkey = CompressedRistrettoPublic::from(&self.enclave.get_ingress_pubkey()?); - if state_data.mode != IngestControllerMode::Idle { - let state_data_ingress_pubkey = - CompressedRistrettoPublic::try_from(state_data.get_ingress_pubkey())?; + if state_data.mode() != IngestControllerMode::Idle { + let state_data_ingress_pubkey = CompressedRistrettoPublic::try_from( + state_data + .ingress_pubkey + .as_ref() + .unwrap_or(&Default::default()), + )?; if state_data_ingress_pubkey != ingress_pubkey { return Err(RestoreStateError::IngressKeyMismatch( ingress_pubkey, @@ -1118,7 +1123,7 @@ where .set_next_block_index(state_data.next_block_index) .expect("Modification should have been allowed, this is a logic error"); - match state_data.mode { + match state_data.mode() { IngestControllerMode::Idle => {} IngestControllerMode::Active => { state.set_active(); @@ -1282,9 +1287,13 @@ where let (summary, sealed_key) = loop { let summary = self.get_ingest_summary_inner(state); - let ingress_pubkey = - CompressedRistrettoPublic::try_from(summary.get_ingress_pubkey()) - .expect("could not interpret ingress pubkey"); + let ingress_pubkey = CompressedRistrettoPublic::try_from( + summary + .ingress_pubkey + .as_ref() + .unwrap_or(&Default::default()), + ) + .expect("could not interpret ingress pubkey"); let mut last_sealed = self.last_sealed_key.lock().expect("mutex poisoned"); { @@ -1303,9 +1312,10 @@ where *last_sealed = None; }; - let mut state_file_data = IngestStateFile::new(); - state_file_data.set_summary(summary); - state_file_data.set_sealed_ingress_key(sealed_key); + let state_file_data = IngestStateFile { + summary: Some(summary), + sealed_ingress_key: sealed_key, + }; log::debug!(self.logger, "Writing state file to {:?}", state_file); state_file @@ -1436,7 +1446,7 @@ where None => conn.get_status()?, }; - match summary.mode { + match summary.mode() { IngestControllerMode::Active => { if log_if_wrong { log::error!( @@ -1460,7 +1470,12 @@ where .cloned() .unwrap_or_else(|| self.get_state().get_peers()); - let peer_pubkey = CompressedRistrettoPublic::try_from(summary.get_ingress_pubkey())?; + let peer_pubkey = CompressedRistrettoPublic::try_from( + summary + .ingress_pubkey + .as_ref() + .unwrap_or(&Default::default()), + )?; if peer_pubkey != our_pubkey { if log_if_wrong { log::warn!( @@ -1475,8 +1490,12 @@ where if update_if_wrong { match conn.set_ingress_private_key(&our_pubkey) { Ok(summary) => { - let peer_pubkey = - CompressedRistrettoPublic::try_from(summary.get_ingress_pubkey())?; + let peer_pubkey = CompressedRistrettoPublic::try_from( + summary + .ingress_pubkey + .as_ref() + .unwrap_or(&Default::default()), + )?; if peer_pubkey != our_pubkey { let uri = conn.uri(); log::error!(self.logger, "Tried to send our ingress key to peer {}, but despite successful status the key is still wrong! Expected: {}, Found: {}", uri, our_pubkey, peer_pubkey); diff --git a/fog/ingest/server/src/controller_state.rs b/fog/ingest/server/src/controller_state.rs index 8992ae8b5d..f2cad1dbd8 100644 --- a/fog/ingest/server/src/controller_state.rs +++ b/fog/ingest/server/src/controller_state.rs @@ -229,13 +229,13 @@ impl IngestControllerState { /// Get an ingest summary protobuf object containing the data from self pub fn get_ingest_summary(&self) -> IngestSummary { - let mut result = IngestSummary::new(); + let mut result = IngestSummary::default(); match self.mode { IngestMode::Idle => { - result.mode = IngestControllerMode::Idle; + result.mode = IngestControllerMode::Idle.into(); } IngestMode::Active => { - result.mode = IngestControllerMode::Active; + result.mode = IngestControllerMode::Active.into(); } }; @@ -244,8 +244,7 @@ impl IngestControllerState { if let Some(iid) = self.ingest_invocation_id { result.ingest_invocation_id = *iid; } - result.peers = - protobuf::RepeatedField::from_vec(self.peers.iter().map(|x| x.to_string()).collect()); + result.peers = self.peers.iter().map(|x| x.to_string()).collect(); result } diff --git a/fog/ingest/server/src/ingest_peer_service.rs b/fog/ingest/server/src/ingest_peer_service.rs index 646a8cdc37..dd0a045bbc 100644 --- a/fog/ingest/server/src/ingest_peer_service.rs +++ b/fog/ingest/server/src/ingest_peer_service.rs @@ -10,7 +10,6 @@ use mc_common::logger::{log, Logger}; use mc_fog_api::{ ingest_common::{IngestSummary, SetPeersRequest}, ingest_peer::*, - Empty, }; use mc_fog_ingest_enclave_api::Error as EnclaveError; use mc_fog_recovery_db_iface::{RecoveryDb, ReportDb}; @@ -74,7 +73,7 @@ where ) -> Result { log::debug!(&self.logger, "Now getting private key",); - let peer_session = PeerSession::from(request.get_channel_id()); + let peer_session = PeerSession::from(request.channel_id); let (private_key, _) = self .controller @@ -109,11 +108,11 @@ where } impl - mc_fog_api::ingest_peer_grpc::AccountIngestPeerApi for IngestPeerService + mc_fog_api::ingest_peer::AccountIngestPeerApi for IngestPeerService where IngestServiceError: From<::Error>, { - fn get_status(&mut self, ctx: RpcContext, _request: Empty, sink: UnarySink) { + fn get_status(&mut self, ctx: RpcContext, _request: (), sink: UnarySink) { let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { send_result(ctx, sink, self.get_status_impl(), logger) diff --git a/fog/ingest/server/src/ingest_service.rs b/fog/ingest/server/src/ingest_service.rs index c53ddcc737..8575d77780 100644 --- a/fog/ingest/server/src/ingest_service.rs +++ b/fog/ingest/server/src/ingest_service.rs @@ -12,10 +12,9 @@ use mc_api::external; use mc_common::logger::Logger; use mc_crypto_keys::CompressedRistrettoPublic; use mc_fog_api::{ + account_ingest::*, fog_common::BlockRange, - ingest::*, ingest_common::{IngestSummary, SetPeersRequest}, - Empty, }; use mc_fog_block_provider::BlockProvider; use mc_fog_ingest_enclave_api::Error as EnclaveError; @@ -25,7 +24,6 @@ use mc_util_grpc::{ rpc_database_err, rpc_internal_error, rpc_invalid_arg_error, rpc_logger, rpc_permissions_error, rpc_precondition_error, rpc_unavailable_error, send_result, }; -use protobuf::RepeatedField; use std::{str::FromStr, sync::Arc}; /// Implements the ingest grpc api @@ -106,7 +104,7 @@ where } /// Logic of proto api - pub fn activate_impl(&mut self, _: Empty, logger: &Logger) -> Result { + pub fn activate_impl(&mut self, _: (), logger: &Logger) -> Result { self.controller .activate( self.block_provider @@ -136,14 +134,14 @@ where } /// Logic of proto api - pub fn retire_impl(&mut self, _: Empty, logger: &Logger) -> Result { + pub fn retire_impl(&mut self, _: (), logger: &Logger) -> Result { self.controller .retire() .map_err(|err| rpc_database_err(err, logger)) } /// Logic of proto api - pub fn unretire_impl(&mut self, _: Empty, logger: &Logger) -> Result { + pub fn unretire_impl(&mut self, _: (), logger: &Logger) -> Result { self.controller .unretire() .map_err(|err| rpc_database_err(err, logger)) @@ -154,9 +152,8 @@ where &mut self, request: ReportLostIngressKeyRequest, logger: &Logger, - ) -> Result { - let key: CompressedRistrettoPublic = request - .get_key() + ) -> Result<(), RpcStatus> { + let key: CompressedRistrettoPublic = (&request.key.unwrap_or_default()) .try_into() .map_err(|err| rpc_invalid_arg_error("lost_ingress_key", err, logger))?; @@ -164,7 +161,7 @@ where .report_lost_ingress_key(key) .map_err(|err| rpc_database_err(err, logger))?; - Ok(Empty::new()) + Ok(()) } /// Gets all the known missed block ranges @@ -177,20 +174,15 @@ where .get_missed_block_ranges() .map_err(|err| rpc_database_err(err, logger))?; - let mut response = GetMissedBlockRangesResponse::new(); - response.set_missed_block_ranges(RepeatedField::from_vec( - ranges + Ok(GetMissedBlockRangesResponse { + missed_block_ranges: ranges .iter() - .map(|range| { - let mut proto_range = BlockRange::new(); - proto_range.set_start_block(range.start_block); - proto_range.set_end_block(range.end_block); - proto_range + .map(|range| BlockRange { + start_block: range.start_block, + end_block: range.end_block, }) .collect(), - )); - - Ok(response) + }) } /// Retrieves a private key from a remote encalve and then sets it as the @@ -200,7 +192,7 @@ where request: SyncKeysFromRemoteRequest, logger: &Logger, ) -> Result { - let peer_uri = IngestPeerUri::from_str(request.get_peer_uri()) + let peer_uri = IngestPeerUri::from_str(&request.peer_uri) .map_err(|err| rpc_invalid_arg_error("invalid peer uri", err, logger))?; self.controller @@ -234,47 +226,35 @@ where ) .map_err(|err| rpc_precondition_error("get_ingress_key_records", err, logger))?; - let mut response = GetIngressKeyRecordsResponse::new(); - response.set_records(RepeatedField::from_vec( - ingress_key_records + Ok(GetIngressKeyRecordsResponse { + records: ingress_key_records .iter() - .map(|record| { - let mut proto_ingress_public_key_record = IngressPublicKeyRecord::new(); - - let ingress_public_key = external::CompressedRistretto::from(&record.key); - proto_ingress_public_key_record.set_ingress_public_key(ingress_public_key); - - proto_ingress_public_key_record.set_start_block(record.status.start_block); - proto_ingress_public_key_record.set_pubkey_expiry(record.status.pubkey_expiry); - proto_ingress_public_key_record.set_retired(record.status.retired); - proto_ingress_public_key_record.set_lost(record.status.lost); - - if let Some(last_scanned_block) = record.last_scanned_block { - proto_ingress_public_key_record.set_last_scanned_block(last_scanned_block); - } - - proto_ingress_public_key_record + .map(|record| IngressPublicKeyRecord { + ingress_public_key: Some(external::CompressedRistretto::from(&record.key)), + start_block: record.status.start_block, + pubkey_expiry: record.status.pubkey_expiry, + retired: record.status.retired, + lost: record.status.lost, + last_scanned_block: record.last_scanned_block.unwrap_or_default(), }) .collect(), - )); - - Ok(response) + }) } } impl - mc_fog_api::ingest_grpc::AccountIngestApi for IngestService + mc_fog_api::account_ingest::AccountIngestApi for IngestService where Error: From<::Error>, { - fn get_status(&mut self, ctx: RpcContext, _request: Empty, sink: UnarySink) { + fn get_status(&mut self, ctx: RpcContext, _request: (), sink: UnarySink) { let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { send_result(ctx, sink, self.get_status_impl(), logger) }) } - fn new_keys(&mut self, ctx: RpcContext, _request: Empty, sink: UnarySink) { + fn new_keys(&mut self, ctx: RpcContext, _request: (), sink: UnarySink) { let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { send_result(ctx, sink, self.new_keys_impl(logger), logger) @@ -310,21 +290,21 @@ where }) } - fn activate(&mut self, ctx: RpcContext, request: Empty, sink: UnarySink) { + fn activate(&mut self, ctx: RpcContext, request: (), sink: UnarySink) { let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { send_result(ctx, sink, self.activate_impl(request, logger), logger) }) } - fn retire(&mut self, ctx: RpcContext, request: Empty, sink: UnarySink) { + fn retire(&mut self, ctx: RpcContext, request: (), sink: UnarySink) { let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { send_result(ctx, sink, self.retire_impl(request, logger), logger) }) } - fn unretire(&mut self, ctx: RpcContext, request: Empty, sink: UnarySink) { + fn unretire(&mut self, ctx: RpcContext, request: (), sink: UnarySink) { let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { send_result(ctx, sink, self.unretire_impl(request, logger), logger) @@ -335,7 +315,7 @@ where &mut self, ctx: RpcContext, request: ReportLostIngressKeyRequest, - sink: UnarySink, + sink: UnarySink<()>, ) { let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { @@ -351,7 +331,7 @@ where fn get_missed_block_ranges( &mut self, ctx: RpcContext, - _request: Empty, + _request: (), sink: UnarySink, ) { let _timer = SVC_COUNTERS.req(&ctx); diff --git a/fog/ingest/server/src/server.rs b/fog/ingest/server/src/server.rs index 40c04d321b..85c4e5c342 100644 --- a/fog/ingest/server/src/server.rs +++ b/fog/ingest/server/src/server.rs @@ -12,14 +12,15 @@ use crate::{ worker::{IngestWorker, PeerCheckupWorker, ReportCacheWorker}, }; use futures::executor::block_on; -use mc_attest_api::attest_grpc::create_attested_api; +use mc_attest_api::attest::create_attested_api; use mc_common::{ logger::{log, Logger}, ResponderId, }; use mc_fog_api::{ + account_ingest, ingest_common::{IngestControllerMode, IngestSummary}, - ingest_grpc, ingest_peer_grpc, + ingest_peer, }; use mc_fog_block_provider::BlockProvider; use mc_fog_recovery_db_iface::{RecoveryDb, ReportDb}; @@ -188,7 +189,7 @@ where fn start_ingest_rpc_server(&mut self) -> Result<(), IngestServiceError> { log::info!(self.logger, "Starting RPC server."); // Package it into grpc service - let ingest_service = ingest_grpc::create_account_ingest_api(IngestService::new( + let ingest_service = account_ingest::create_account_ingest_api(IngestService::new( self.controller.clone(), self.block_provider.clone(), self.logger.clone(), @@ -232,7 +233,7 @@ where fn start_peer_rpc_server(&mut self) -> Result<(), IngestServiceError> { log::info!(self.logger, "Starting Peer RPC server."); - let ingest_peer_service = ingest_peer_grpc::create_account_ingest_peer_api( + let ingest_peer_service = ingest_peer::create_account_ingest_peer_api( IngestPeerService::new(self.controller.clone(), self.logger.clone()), ); @@ -342,13 +343,13 @@ where /// Ask if the server is active /// This is a convenience wrapper used in tests pub fn is_active(&self) -> bool { - self.get_ingest_summary().mode == IngestControllerMode::Active + self.get_ingest_summary().mode() == IngestControllerMode::Active } /// Ask if the server is idle. /// This is a convenience wrapper used in tests. pub fn is_idle(&self) -> bool { - self.get_ingest_summary().mode == IngestControllerMode::Idle + self.get_ingest_summary().mode() == IngestControllerMode::Idle } /// Set new keys. diff --git a/fog/ingest/server/src/state_file.rs b/fog/ingest/server/src/state_file.rs index d378068778..551dd6abef 100644 --- a/fog/ingest/server/src/state_file.rs +++ b/fog/ingest/server/src/state_file.rs @@ -3,7 +3,8 @@ //! State we want to keep between invocations of the ingest server. use mc_fog_api::ingest_common::IngestStateFile; -use protobuf::Message; +use mc_util_serial::prost; +use prost::Message; use std::{ fs, io::{Error, ErrorKind, Result, Write}, @@ -26,7 +27,7 @@ impl StateFile { /// Read the data from the state file on disk pub fn read(&self) -> Result { let file_data = fs::read(&self.file_path)?; - let state_data = IngestStateFile::parse_from_bytes(&file_data).map_err(|e| { + let state_data = IngestStateFile::decode(file_data.as_slice()).map_err(|e| { Error::new( ErrorKind::Other, format!("Failed parsing state file {:?}: {}", self.file_path, e), @@ -47,12 +48,7 @@ impl StateFile { /// Unfortunately there's no way to do 4 in the rust stdlib, so we would /// need to use nix or something. https://github.com/rust-lang/rust/issues/32255#issuecomment-308296338 pub fn write(&self, state_data: &IngestStateFile) -> Result<()> { - let proto_data = state_data.write_to_bytes().map_err(|e| { - Error::new( - ErrorKind::Other, - format!("failed serializing state data: {e}"), - ) - })?; + let proto_data = state_data.encode_to_vec(); let mut file = fs::File::create(&self.file_path)?; file.write_all(&proto_data)?; file.sync_all() diff --git a/fog/ingest/server/test-utils/src/lib.rs b/fog/ingest/server/test-utils/src/lib.rs index eaa3f60c2b..43eab9de56 100644 --- a/fog/ingest/server/test-utils/src/lib.rs +++ b/fog/ingest/server/test-utils/src/lib.rs @@ -56,7 +56,9 @@ impl TestIngestNode { /// Helper to fetch and parse the ingress pubkey for this node. pub fn get_ingress_key(&self) -> CompressedRistrettoPublic { self.get_ingest_summary() - .get_ingress_pubkey() + .ingress_pubkey + .as_ref() + .unwrap() .try_into() .unwrap() } diff --git a/fog/ingest/server/tests/peer_key_sharing.rs b/fog/ingest/server/tests/peer_key_sharing.rs index a84ae7b0e7..e42718beef 100644 --- a/fog/ingest/server/tests/peer_key_sharing.rs +++ b/fog/ingest/server/tests/peer_key_sharing.rs @@ -90,11 +90,13 @@ fn test_ingest_pool_integration(db_test_context: Arc, let primary_pubkey = primary_ingest_client .get_status() .unwrap() - .take_ingress_pubkey(); + .ingress_pubkey + .unwrap(); let mut backup_pubkey = backup_ingest_client .get_status() .unwrap() - .take_ingress_pubkey(); + .ingress_pubkey + .unwrap(); for _ in 0..30 { if primary_pubkey == backup_pubkey { @@ -106,7 +108,8 @@ fn test_ingest_pool_integration(db_test_context: Arc, backup_pubkey = backup_ingest_client .get_status() .unwrap() - .take_ingress_pubkey(); + .ingress_pubkey + .unwrap(); } assert_eq!(primary_pubkey, backup_pubkey); @@ -121,7 +124,8 @@ fn test_ingest_pool_integration(db_test_context: Arc, backup_pubkey = backup_ingest_client .get_status() .unwrap() - .take_ingress_pubkey(); + .ingress_pubkey + .unwrap(); if primary_pubkey != backup_pubkey { break; } @@ -143,7 +147,8 @@ fn test_ingest_pool_integration(db_test_context: Arc, backup_pubkey = backup_ingest_client .get_status() .unwrap() - .take_ingress_pubkey(); + .ingress_pubkey + .unwrap(); } // Lets confirm that new_keys doesn't work on the primary @@ -155,7 +160,8 @@ fn test_ingest_pool_integration(db_test_context: Arc, let final_primary_key = primary_ingest_client .get_status() .unwrap() - .take_ingress_pubkey(); + .ingress_pubkey + .unwrap(); assert_eq!( primary_pubkey, final_primary_key, "active server's pubkey should not have changed" diff --git a/fog/ingest/server/tests/three_node_cluster.rs b/fog/ingest/server/tests/three_node_cluster.rs index 3fe1abd7e6..0578b18a28 100644 --- a/fog/ingest/server/tests/three_node_cluster.rs +++ b/fog/ingest/server/tests/three_node_cluster.rs @@ -227,7 +227,7 @@ fn three_node_cluster_fencing(logger: Logger) { // There should be a block written only by the node that won the race. let active_summary = active_summary.unwrap(); - let active_iid = IngestInvocationId::from(active_summary.get_ingest_invocation_id()); + let active_iid = IngestInvocationId::from(active_summary.ingest_invocation_id); let num_blocks = helper.ledger.num_blocks().unwrap(); @@ -308,9 +308,9 @@ fn three_node_cluster_fencing(logger: Logger) { assert!(node.is_active()); let node_summary = node.get_ingest_summary(); - assert_eq!(node_summary.get_next_block_index(), num_blocks); + assert_eq!(node_summary.next_block_index, num_blocks); - IngestInvocationId::from(node_summary.get_ingest_invocation_id()) + IngestInvocationId::from(node_summary.ingest_invocation_id) }; let invocation_id = helper diff --git a/fog/ledger/connection/Cargo.toml b/fog/ledger/connection/Cargo.toml index fae557bbd6..eb3534b612 100644 --- a/fog/ledger/connection/Cargo.toml +++ b/fog/ledger/connection/Cargo.toml @@ -33,9 +33,9 @@ aes-gcm = "0.10.3" der = "0.7.8" displaydoc = { version = "0.2", default-features = false } futures = "0.3" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } mc-attestation-verifier = "0.4.3" -protobuf = "2.27.1" +prost = { version = "0.11", default-features = false, features = ["prost-derive"] } retry = "2.0" sha2 = { version = "0.10", default-features = false } diff --git a/fog/ledger/connection/src/block.rs b/fog/ledger/connection/src/block.rs index a3a5d21b32..954758e0e0 100644 --- a/fog/ledger/connection/src/block.rs +++ b/fog/ledger/connection/src/block.rs @@ -3,10 +3,9 @@ use super::Error; use grpcio::{ChannelBuilder, Environment}; use mc_common::{logger::Logger, trace_time}; -use mc_fog_api::{fog_common::BlockRange, ledger, ledger_grpc, ledger_grpc::FogBlockApiClient}; +use mc_fog_api::{fog_common::BlockRange, fog_ledger, fog_ledger::FogBlockApiClient}; use mc_fog_uri::{ConnectionUri, FogLedgerUri}; use mc_util_grpc::{BasicCredentials, ConnectionUriGrpcioChannel, GrpcRetryConfig}; -use protobuf::RepeatedField; use std::sync::Arc; /// A unattested connection to the Fog Block service. @@ -29,7 +28,7 @@ impl FogBlockGrpcClient { let creds = BasicCredentials::new(&uri.username(), &uri.password()); let ch = ChannelBuilder::default_channel_builder(grpc_env).connect_to_uri(&uri, &logger); - let blocks_client = ledger_grpc::FogBlockApiClient::new(ch); + let blocks_client = FogBlockApiClient::new(ch); Self { uri, @@ -44,11 +43,12 @@ impl FogBlockGrpcClient { pub fn get_missed_block_ranges( &mut self, missed_block_ranges: Vec, - ) -> Result { + ) -> Result { trace_time!(self.logger, "FogBlockGrpcClient::get_missed_block_ranges"); - let mut request = ledger::BlockRequest::new(); - request.ranges = RepeatedField::from_vec(missed_block_ranges); + let request = fog_ledger::BlockRequest { + ranges: missed_block_ranges, + }; self.grpc_retry_config .retry(|| { diff --git a/fog/ledger/connection/src/error.rs b/fog/ledger/connection/src/error.rs index 3b2e11d2df..bc18febfcf 100644 --- a/fog/ledger/connection/src/error.rs +++ b/fog/ledger/connection/src/error.rs @@ -1,7 +1,7 @@ // Copyright (c) 2018-2022 The MobileCoin Foundation use displaydoc::Display; -use protobuf::error::ProtobufError; +use prost::DecodeError; use retry::Error as RetryError; use mc_api::ConversionError; @@ -15,7 +15,7 @@ pub enum Error { /// Enclave Connection Error ({0}): {1} Connection(FogLedgerUri, RetryError), /// Protobuf Error: {0} - Protobuf(ProtobufError), + Protobuf(DecodeError), /// Deserialization failed DeserializationFailed, /// Mobilecoin API Conversion Error: {0} @@ -24,8 +24,8 @@ pub enum Error { Grpc(FogLedgerUri, RetryError), } -impl From for Error { - fn from(err: ProtobufError) -> Self { +impl From for Error { + fn from(err: DecodeError) -> Self { Error::Protobuf(err) } } diff --git a/fog/ledger/connection/src/key_image.rs b/fog/ledger/connection/src/key_image.rs index 67b0678d15..65e89865e6 100644 --- a/fog/ledger/connection/src/key_image.rs +++ b/fog/ledger/connection/src/key_image.rs @@ -9,7 +9,7 @@ use mc_common::{ logger::{o, Logger}, trace_time, }; -use mc_fog_api::{ledger::KeyImageResultCode, ledger_grpc::FogKeyImageApiClient}; +use mc_fog_api::fog_ledger::{FogKeyImageApiClient, KeyImageResultCode}; use mc_fog_enclave_connection::EnclaveConnection; use mc_fog_types::ledger::{ CheckKeyImagesRequest, CheckKeyImagesResponse, KeyImageQuery, KeyImageResult, diff --git a/fog/ledger/connection/src/merkle_proof.rs b/fog/ledger/connection/src/merkle_proof.rs index 280c5d5de0..e9606e0840 100644 --- a/fog/ledger/connection/src/merkle_proof.rs +++ b/fog/ledger/connection/src/merkle_proof.rs @@ -8,7 +8,7 @@ use mc_common::{ logger::{o, Logger}, trace_time, }; -use mc_fog_api::ledger_grpc::FogMerkleProofApiClient; +use mc_fog_api::fog_ledger::FogMerkleProofApiClient; use mc_fog_enclave_connection::EnclaveConnection; use mc_fog_types::ledger::{GetOutputsRequest, GetOutputsResponse, OutputResult}; use mc_fog_uri::FogLedgerUri; @@ -103,11 +103,12 @@ impl OutputResultExtension for OutputResult { /// Map the protobuf OutputResult type to a more idiomatic rust Result type fn status(&self) -> Result, OutputError> { // Rust does not allow the left side of match expression to a be `Foo as u32`. - const OUTPUT_RESULT_CODE_EXISTS: u32 = mc_fog_api::ledger::OutputResultCode::Exists as u32; + const OUTPUT_RESULT_CODE_EXISTS: u32 = + mc_fog_api::fog_ledger::OutputResultCode::Exists as u32; const OUTPUT_RESULT_CODE_DOES_NOT_EXIST: u32 = - mc_fog_api::ledger::OutputResultCode::DoesNotExist as u32; + mc_fog_api::fog_ledger::OutputResultCode::DoesNotExist as u32; const OUTPUT_RESULT_CODE_DATABASE_ERROR: u32 = - mc_fog_api::ledger::OutputResultCode::OutputDatabaseError as u32; + mc_fog_api::fog_ledger::OutputResultCode::OutputDatabaseError as u32; match self.result_code { OUTPUT_RESULT_CODE_EXISTS => Ok(Some((self.output.clone(), self.proof.clone()))), diff --git a/fog/ledger/connection/src/router_client.rs b/fog/ledger/connection/src/router_client.rs index 93bebd289e..d9c0db89b6 100644 --- a/fog/ledger/connection/src/router_client.rs +++ b/fog/ledger/connection/src/router_client.rs @@ -18,8 +18,7 @@ use mc_crypto_keys::X25519; use mc_crypto_noise::CipherError; use mc_fog_api::{ attest::{AuthMessage, Message}, - ledger::{LedgerRequest, LedgerResponse}, - ledger_grpc::LedgerApiClient, + fog_ledger::{ledger_request, ledger_response, LedgerApiClient, LedgerRequest, LedgerResponse}, }; use mc_fog_types::ledger::{CheckKeyImagesRequest, CheckKeyImagesResponse, KeyImageQuery}; use mc_fog_uri::FogLedgerUri; @@ -105,18 +104,25 @@ impl LedgerGrpcClient { let (initiator, auth_request_output) = initiator.try_next(&mut csprng, init_input)?; let attested_message: AuthMessage = auth_request_output.into(); - let mut request = LedgerRequest::new(); - request.set_auth(attested_message); + let request = LedgerRequest { + request_data: Some(ledger_request::RequestData::Auth(attested_message)), + }; self.request_sender .send((request.clone(), grpcio::WriteFlags::default())) .await?; - let mut response = self + let response = self .response_receiver .try_next() .await? .ok_or(Error::ResponseNotReceived)?; - let auth_response_msg = response.take_auth(); + let auth_response_msg = if let Some(ledger_response::ResponseData::Auth(auth_response)) = + response.response_data + { + auth_response + } else { + Default::default() + }; let epoch_time = SystemTimeProvider .since_epoch() @@ -174,29 +180,35 @@ impl LedgerGrpcClient { .as_mut() .expect("no enclave_connection even though attest succeeded"); - let mut msg = Message::new(); - msg.set_channel_id(Vec::from(attest_cipher.binding())); - msg.set_aad(aad.clone()); - let plaintext_bytes = mc_util_serial::encode(&key_images_request); let request_ciphertext = attest_cipher.encrypt(&aad, &plaintext_bytes)?; - msg.set_data(request_ciphertext); - msg + Message { + channel_id: Vec::from(attest_cipher.binding()), + aad: aad.clone(), + data: request_ciphertext, + } + }; + let request = LedgerRequest { + request_data: Some(ledger_request::RequestData::CheckKeyImages(msg)), }; - let mut request = LedgerRequest::new(); - request.set_check_key_images(msg); self.request_sender .send((request.clone(), grpcio::WriteFlags::default())) .await?; - let message = self + let response = self .response_receiver .try_next() .await? - .ok_or(Error::ResponseNotReceived)? - .take_check_key_image_response(); + .ok_or(Error::ResponseNotReceived)?; + let message = if let Some(ledger_response::ResponseData::CheckKeyImageResponse(msg)) = + response.response_data + { + msg + } else { + Default::default() + }; { let attest_cipher = self @@ -204,7 +216,8 @@ impl LedgerGrpcClient { .as_mut() .expect("no enclave_connection even though attest succeeded"); - let plaintext_bytes = attest_cipher.decrypt(message.get_aad(), message.get_data())?; + let plaintext_bytes = + attest_cipher.decrypt(message.aad.as_slice(), message.data.as_slice())?; let plaintext_response: CheckKeyImagesResponse = mc_util_serial::decode(&plaintext_bytes)?; Ok(plaintext_response) diff --git a/fog/ledger/connection/src/untrusted.rs b/fog/ledger/connection/src/untrusted.rs index fa23788b9c..92beb58c31 100644 --- a/fog/ledger/connection/src/untrusted.rs +++ b/fog/ledger/connection/src/untrusted.rs @@ -5,7 +5,7 @@ use grpcio::{ChannelBuilder, Environment}; use mc_blockchain_types::BlockIndex; use mc_common::{logger::Logger, trace_time}; use mc_crypto_keys::CompressedRistrettoPublic; -use mc_fog_api::{fog_common::BlockRange, ledger, ledger_grpc}; +use mc_fog_api::{fog_common::BlockRange, fog_ledger}; use mc_fog_uri::FogLedgerUri; use mc_util_grpc::{BasicCredentials, ConnectionUriGrpcioChannel, GrpcRetryConfig}; use mc_util_uri::ConnectionUri; @@ -14,8 +14,8 @@ use std::{ops::Range, sync::Arc}; /// A non-attested connection to untrusted fog ledger endpoints pub struct FogUntrustedLedgerGrpcClient { uri: FogLedgerUri, - blocks_client: ledger_grpc::FogBlockApiClient, - tx_out_client: ledger_grpc::FogUntrustedTxOutApiClient, + blocks_client: fog_ledger::FogBlockApiClient, + tx_out_client: fog_ledger::FogUntrustedTxOutApiClient, creds: BasicCredentials, grpc_retry_config: GrpcRetryConfig, #[allow(dead_code)] @@ -34,9 +34,9 @@ impl FogUntrustedLedgerGrpcClient { let ch = ChannelBuilder::default_channel_builder(grpc_env).connect_to_uri(&uri, &logger); - let blocks_client = ledger_grpc::FogBlockApiClient::new(ch.clone()); + let blocks_client = fog_ledger::FogBlockApiClient::new(ch.clone()); - let tx_out_client = ledger_grpc::FogUntrustedTxOutApiClient::new(ch); + let tx_out_client = fog_ledger::FogUntrustedTxOutApiClient::new(ch); Self { uri, @@ -55,18 +55,18 @@ impl FogUntrustedLedgerGrpcClient { pub fn get_blocks<'a>( &self, block_ranges: impl IntoIterator>, - ) -> Result { + ) -> Result { trace_time!(self.logger, "FogUntrustedLedgerGrpcClient::get_blocks"); - let mut request = ledger::BlockRequest::new(); - for iter_range in block_ranges.into_iter() { - request.ranges.push({ - let mut range = BlockRange::new(); - range.start_block = iter_range.start; - range.end_block = iter_range.end; - range - }); - } + let request = fog_ledger::BlockRequest { + ranges: block_ranges + .into_iter() + .map(|range| BlockRange { + start_block: range.start, + end_block: range.end, + }) + .collect(), + }; self.grpc_retry_config .retry(|| { @@ -85,14 +85,15 @@ impl FogUntrustedLedgerGrpcClient { pub fn get_tx_outs( &self, tx_out_pubkeys: impl IntoIterator, - ) -> Result { + ) -> Result { trace_time!(self.logger, "FogUntrustedLedgerGrpcClient::get_tx_outs"); - let mut request = ledger::TxOutRequest::new(); - for pubkey in tx_out_pubkeys.into_iter() { - // Convert to external::CompressedRistretto - request.tx_out_pubkeys.push((&pubkey).into()); - } + let request = fog_ledger::TxOutRequest { + tx_out_pubkeys: tx_out_pubkeys + .into_iter() + .map(|pubkey| (&pubkey).into()) + .collect(), + }; self.grpc_retry_config .retry(|| { diff --git a/fog/ledger/server/Cargo.toml b/fog/ledger/server/Cargo.toml index 7b0552e475..fc3353b33f 100644 --- a/fog/ledger/server/Cargo.toml +++ b/fog/ledger/server/Cargo.toml @@ -54,7 +54,7 @@ mc-fog-uri = { path = "../../uri" } clap = { version = "4.5", features = ["derive", "env"] } displaydoc = { version = "0.2", default-features = false } futures = "0.3" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } itertools = "0.12" lazy_static = "1.4" mc-attestation-verifier = "0.4.3" diff --git a/fog/ledger/server/src/block_service.rs b/fog/ledger/server/src/block_service.rs index 3d5cb7bde6..6c67ee2b1f 100644 --- a/fog/ledger/server/src/block_service.rs +++ b/fog/ledger/server/src/block_service.rs @@ -3,11 +3,7 @@ use crate::SVC_COUNTERS; use grpcio::{RpcContext, RpcStatus, UnarySink}; use mc_common::logger::Logger; -use mc_fog_api::{ - external, - ledger::{BlockData, BlockRequest, BlockResponse}, - ledger_grpc::FogBlockApi, -}; +use mc_fog_api::fog_ledger::{BlockData, BlockRequest, BlockResponse, FogBlockApi}; use mc_fog_block_provider::{BlockProvider, BlocksDataResponse}; use mc_util_grpc::{ check_request_chain_id, rpc_database_err, rpc_logger, send_result, Authenticator, @@ -55,27 +51,27 @@ impl BlockService { .get_blocks_data(block_indices.as_slice()) .map_err(|err| rpc_database_err(err, &self.logger))?; - let mut response = BlockResponse::new(); - response.num_blocks = latest_block.index + 1; - response.global_txo_count = latest_block.cumulative_txo_count; - - response.blocks = results - .into_iter() - .flatten() - .map(|b| { - let mut result = BlockData::new(); - for output in b.block_data.contents().outputs.iter() { - result.outputs.push(external::TxOut::from(output)); - } - result.index = b.block_data.block().index; - result.global_txo_count = b.block_data.block().cumulative_txo_count; - result.timestamp = b.block_timestamp; - result.timestamp_result_code = b.block_timestamp_result_code as u32; - result - }) - .collect(); - - Ok(response) + Ok(BlockResponse { + num_blocks: latest_block.index + 1, + global_txo_count: latest_block.cumulative_txo_count, + blocks: results + .into_iter() + .flatten() + .map(|b| BlockData { + outputs: b + .block_data + .contents() + .outputs + .iter() + .map(Into::into) + .collect(), + global_txo_count: b.block_data.block().cumulative_txo_count, + timestamp: b.block_timestamp, + timestamp_result_code: b.block_timestamp_result_code as u32, + index: b.block_data.block().index, + }) + .collect(), + }) } } diff --git a/fog/ledger/server/src/key_image_service.rs b/fog/ledger/server/src/key_image_service.rs index aeb161e445..f0778a09e8 100644 --- a/fog/ledger/server/src/key_image_service.rs +++ b/fog/ledger/server/src/key_image_service.rs @@ -4,11 +4,9 @@ use grpcio::RpcStatus; use mc_attest_api::{attest, attest::AuthMessage}; use mc_blockchain_types::MAX_BLOCK_VERSION; use mc_common::logger::{log, Logger}; -use mc_fog_api::{ - ledger::{ - MultiKeyImageStoreRequest, MultiKeyImageStoreResponse, MultiKeyImageStoreResponseStatus, - }, - ledger_grpc::KeyImageStoreApi, +use mc_fog_api::fog_ledger::{ + KeyImageStoreApi, MultiKeyImageStoreRequest, MultiKeyImageStoreResponse, + MultiKeyImageStoreResponseStatus, }; use mc_fog_ledger_enclave::LedgerEnclaveProxy; use mc_fog_ledger_enclave_api::{Error as EnclaveError, UntrustedKeyImageQueryResponse}; @@ -53,16 +51,14 @@ impl KeyImageService { pub fn auth_store( &mut self, - mut req: AuthMessage, + req: AuthMessage, logger: &Logger, ) -> Result { // TODO: Use the prost message directly, once available - match self.enclave.frontend_accept(req.take_data().into()) { - Ok((response, _)) => { - let mut result = attest::AuthMessage::new(); - result.set_data(response.into()); - Ok(result) - } + match self.enclave.frontend_accept(req.data.into()) { + Ok((response, _)) => Ok(attest::AuthMessage { + data: response.into(), + }), Err(client_error) => { // There's no requirement on the remote party to trigger this, so it's debug. log::debug!( @@ -129,11 +125,13 @@ impl KeyImageService { fog_ledger_store_uri: KeyImageStoreUri, queries: Vec, ) -> MultiKeyImageStoreResponse { - let mut response = MultiKeyImageStoreResponse::new(); - // The router needs our own URI, in case auth fails / hasn't been started yet. - response.set_store_uri(fog_ledger_store_uri.url().to_string()); - // Default status of AUTHENTICATION_ERROR in case of empty queries - response.set_status(MultiKeyImageStoreResponseStatus::AUTHENTICATION_ERROR); + let mut response = MultiKeyImageStoreResponse { + // The router needs our own URI, in case auth fails / hasn't been started yet. + store_uri: fog_ledger_store_uri.url().to_string(), + // Default status of AUTHENTICATION_ERROR in case of empty queries + status: MultiKeyImageStoreResponseStatus::AuthenticationError.into(), + ..Default::default() + }; for query in queries.into_iter() { // Only one of the query messages in the multi-store query is intended for this @@ -142,19 +140,19 @@ impl KeyImageService { // for them. match self.check_key_image_store_auth(query) { Ok(attested_message) => { - response.set_query_response(attested_message); - response.set_status(MultiKeyImageStoreResponseStatus::SUCCESS); + response.query_response = Some(attested_message); + response.set_status(MultiKeyImageStoreResponseStatus::Success); } Err(EnclaveError::ProstDecode) => { - response.set_status(MultiKeyImageStoreResponseStatus::INVALID_ARGUMENT); + response.set_status(MultiKeyImageStoreResponseStatus::InvalidArgument); } Err(EnclaveError::Attest(_)) => { - response.set_status(MultiKeyImageStoreResponseStatus::AUTHENTICATION_ERROR); + response.set_status(MultiKeyImageStoreResponseStatus::AuthenticationError); // All other conditions are early exit but we expect several of these continue; } Err(_) => { - response.set_status(MultiKeyImageStoreResponseStatus::UNKNOWN); + response.set_status(MultiKeyImageStoreResponseStatus::Unknown); } } @@ -213,7 +211,7 @@ impl KeyImageStoreApi for KeyImageService { let start_time = Instant::now(); let response = - self.process_queries(self.client_listen_uri.clone(), req.queries.into_vec()); + self.process_queries(self.client_listen_uri.clone(), req.queries.to_vec()); let status_str = format!("{:?}", response.status); let subdomain = self.client_listen_uri.subdomain().unwrap_or_default(); diff --git a/fog/ledger/server/src/key_image_store_server.rs b/fog/ledger/server/src/key_image_store_server.rs index a69045a464..de9cb87401 100644 --- a/fog/ledger/server/src/key_image_store_server.rs +++ b/fog/ledger/server/src/key_image_store_server.rs @@ -9,7 +9,7 @@ use mc_common::{ logger::{log, Logger}, time::TimeProvider, }; -use mc_fog_api::ledger_grpc; +use mc_fog_api::fog_ledger; use mc_fog_block_provider::BlockProvider; use mc_fog_ledger_enclave::LedgerEnclaveProxy; use mc_fog_uri::{ConnectionUri, KeyImageStoreUri}; @@ -135,7 +135,7 @@ where // Build our store server. // Init ledger store service. let ledger_store_service = - ledger_grpc::create_key_image_store_api(key_image_service.clone()); + fog_ledger::create_key_image_store_api(key_image_service.clone()); log::debug!(logger, "Constructed Key Image Store GRPC Service"); // Package service into grpc server diff --git a/fog/ledger/server/src/merkle_proof_service.rs b/fog/ledger/server/src/merkle_proof_service.rs index 791cd6542b..7a7f3ebb0f 100644 --- a/fog/ledger/server/src/merkle_proof_service.rs +++ b/fog/ledger/server/src/merkle_proof_service.rs @@ -6,7 +6,7 @@ use mc_attest_api::attest::{AuthMessage, Message}; use mc_attest_enclave_api::ClientSession; use mc_blockchain_types::MAX_BLOCK_VERSION; use mc_common::logger::{log, Logger}; -use mc_fog_api::{ledger::OutputResultCode, ledger_grpc::FogMerkleProofApi}; +use mc_fog_api::fog_ledger::{FogMerkleProofApi, OutputResultCode}; use mc_fog_block_provider::{BlockProvider, Error as BlockProviderError}; use mc_fog_ledger_enclave::{GetOutputsResponse, LedgerEnclaveProxy, OutputContext, OutputResult}; use mc_fog_ledger_enclave_api::Error as EnclaveError; diff --git a/fog/ledger/server/src/router_admin_service.rs b/fog/ledger/server/src/router_admin_service.rs index e962751252..1d353f7225 100644 --- a/fog/ledger/server/src/router_admin_service.rs +++ b/fog/ledger/server/src/router_admin_service.rs @@ -6,12 +6,12 @@ use itertools::Itertools; use mc_common::logger::{log, Logger}; use mc_fog_api::{ fog_common::AddShardRequest, - ledger_grpc::{KeyImageStoreApiClient, LedgerRouterAdminApi}, + fog_ledger::{KeyImageStoreApiClient, LedgerRouterAdminApi}, }; use mc_fog_uri::KeyImageStoreUri; use mc_util_grpc::{ rpc_invalid_arg_error, rpc_logger, rpc_precondition_error, send_result, - ConnectionUriGrpcioChannel, Empty, + ConnectionUriGrpcioChannel, }; use std::{ collections::HashMap, @@ -36,7 +36,7 @@ impl LedgerRouterAdminService { } } - fn add_shard_impl(&mut self, shard_uri: &str, logger: &Logger) -> Result { + fn add_shard_impl(&mut self, shard_uri: &str, logger: &Logger) -> Result<(), RpcStatus> { let key_image_store_uri = KeyImageStoreUri::from_str(shard_uri).map_err(|_| { rpc_invalid_arg_error( "add_shard", @@ -65,19 +65,19 @@ impl LedgerRouterAdminService { ); shard_clients.insert(key_image_store_uri, Arc::new(key_image_store_client)); - Ok(Empty::new()) + Ok(()) } } impl LedgerRouterAdminApi for LedgerRouterAdminService { - fn add_shard(&mut self, ctx: RpcContext, request: AddShardRequest, sink: UnarySink) { + fn add_shard(&mut self, ctx: RpcContext, request: AddShardRequest, sink: UnarySink<()>) { log::info!(self.logger, "Request received in add_shard fn"); let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { send_result( ctx, sink, - self.add_shard_impl(request.get_shard_uri(), logger), + self.add_shard_impl(&request.shard_uri, logger), logger, ); }); diff --git a/fog/ledger/server/src/router_handlers.rs b/fog/ledger/server/src/router_handlers.rs index 1c0de47a17..b601ed3152 100644 --- a/fog/ledger/server/src/router_handlers.rs +++ b/fog/ledger/server/src/router_handlers.rs @@ -13,12 +13,9 @@ use mc_common::{ logger::{log, Logger}, ResponderId, }; -use mc_fog_api::{ - ledger::{ - LedgerRequest, LedgerRequest_oneof_request_data, LedgerResponse, MultiKeyImageStoreRequest, - MultiKeyImageStoreResponse, MultiKeyImageStoreResponseStatus, - }, - ledger_grpc::KeyImageStoreApiClient, +use mc_fog_api::fog_ledger::{ + ledger_request, ledger_response, KeyImageStoreApiClient, LedgerRequest, LedgerResponse, + MultiKeyImageStoreRequest, MultiKeyImageStoreResponse, MultiKeyImageStoreResponseStatus, }; use mc_fog_ledger_enclave::LedgerEnclaveProxy; use mc_fog_uri::{ConnectionUri, KeyImageStoreUri}; @@ -84,10 +81,10 @@ where { let tracer = tracer!(); match request.request_data { - Some(LedgerRequest_oneof_request_data::auth(request)) => { + Some(ledger_request::RequestData::Auth(request)) => { tracer.in_span("auth", |_cx| handle_auth_request(enclave, request, logger)) } - Some(LedgerRequest_oneof_request_data::check_key_images(request)) => { + Some(ledger_request::RequestData::CheckKeyImages(request)) => { handle_query_request( request, enclave, @@ -149,14 +146,17 @@ pub fn process_shard_responses( let mut store_uris_for_authentication = Vec::new(); let mut new_query_responses = Vec::new(); - for (shard_client, mut response) in clients_and_responses { - let store_uri = KeyImageStoreUri::from_str(response.get_store_uri())?; - match response.get_status() { - MultiKeyImageStoreResponseStatus::SUCCESS => { + for (shard_client, response) in clients_and_responses { + let store_uri = KeyImageStoreUri::from_str(&response.store_uri)?; + match response.status() { + MultiKeyImageStoreResponseStatus::Success => { let store_responder_id = store_uri.host_and_port_responder_id()?; - new_query_responses.push((store_responder_id, response.take_query_response())); + new_query_responses.push(( + store_responder_id, + response.query_response.unwrap_or_default(), + )); } - MultiKeyImageStoreResponseStatus::AUTHENTICATION_ERROR => { + MultiKeyImageStoreResponseStatus::AuthenticationError => { // We did not receive a query response for this shard.Therefore, we need to: // (a) retry the query // (b) authenticate with the Ledger Store that returned the decryption_error @@ -164,7 +164,7 @@ pub fn process_shard_responses( store_uris_for_authentication.push(store_uri); } // This call will be retried as part of the larger retry logic - MultiKeyImageStoreResponseStatus::NOT_READY => { + MultiKeyImageStoreResponseStatus::NotReady => { log::debug!( logger, "Shard {} status NotReady", @@ -172,7 +172,7 @@ pub fn process_shard_responses( ); } // This is a Protobuf decode error - we should never see this - MultiKeyImageStoreResponseStatus::INVALID_ARGUMENT => { + MultiKeyImageStoreResponseStatus::InvalidArgument => { log::error!( logger, "Received a response with status 'INVALID_ARGUMENT' from store {}", @@ -180,7 +180,7 @@ pub fn process_shard_responses( ); } // This is an unexpected error - we should never see this - MultiKeyImageStoreResponseStatus::UNKNOWN => { + MultiKeyImageStoreResponseStatus::Unknown => { log::error!( logger, "Received a response with status 'UNKNOWN' from store {}", @@ -210,9 +210,11 @@ where router_server_err_to_rpc_status("Auth: e client accept", err.into(), logger) })?; - let mut response = LedgerResponse::new(); - response.mut_auth().set_data(client_auth_response.into()); - Ok(response) + Ok(LedgerResponse { + response_data: Some(ledger_response::ResponseData::Auth( + client_auth_response.into(), + )), + }) } /// Handles a client's query request. @@ -336,9 +338,11 @@ where }) })?; - let mut response = LedgerResponse::new(); - response.set_check_key_image_response(query_response.into()); - Ok(response) + Ok(LedgerResponse { + response_data: Some(ledger_response::ResponseData::CheckKeyImageResponse( + query_response.into(), + )), + }) } /// Sends a client's query request to all of the Fog Ledger shards. diff --git a/fog/ledger/server/src/router_server.rs b/fog/ledger/server/src/router_server.rs index a9a366a1df..07643860d2 100644 --- a/fog/ledger/server/src/router_server.rs +++ b/fog/ledger/server/src/router_server.rs @@ -10,7 +10,7 @@ use mc_common::{ logger::{log, Logger}, time::SystemTimeProvider, }; -use mc_fog_api::ledger_grpc; +use mc_fog_api::fog_ledger; use mc_fog_block_provider::BlockProvider; use mc_fog_ledger_enclave::LedgerEnclaveProxy; use mc_fog_uri::{ConnectionUri, FogLedgerUri}; @@ -57,7 +57,7 @@ where .build(), ); for shard_uri in config.shard_uris.clone() { - let ledger_store_grpc_client = ledger_grpc::KeyImageStoreApiClient::new( + let ledger_store_grpc_client = fog_ledger::KeyImageStoreApiClient::new( ChannelBuilder::default_channel_builder(grpc_env.clone()) .keepalive_permit_without_calls(false) .connect_to_uri(&shard_uri, &logger), @@ -95,10 +95,10 @@ where logger.clone(), ); - let ledger_router_service = ledger_grpc::create_ledger_api(ledger_service.clone()); + let ledger_router_service = fog_ledger::create_ledger_api(ledger_service.clone()); log::debug!(logger, "Constructed Ledger Router GRPC Service"); - let unary_key_image_service = ledger_grpc::create_fog_key_image_api(ledger_service); + let unary_key_image_service = fog_ledger::create_fog_key_image_api(ledger_service); // Init ledger router admin service. let admin_service = @@ -108,7 +108,7 @@ where // Non-routed servers and services // Init merkle proof service let merkle_proof_service = - ledger_grpc::create_fog_merkle_proof_api(MerkleProofService::new( + fog_ledger::create_fog_merkle_proof_api(MerkleProofService::new( config.chain_id.clone(), block_provider.clone(), enclave.clone(), @@ -117,14 +117,14 @@ where )); // Init untrusted tx out service let untrusted_tx_out_service = - ledger_grpc::create_fog_untrusted_tx_out_api(UntrustedTxOutService::new( + fog_ledger::create_fog_untrusted_tx_out_api(UntrustedTxOutService::new( config.chain_id.clone(), block_provider.clone(), client_authenticator.clone(), logger.clone(), )); // Init block service - let block_service = ledger_grpc::create_fog_block_api(BlockService::new( + let block_service = fog_ledger::create_fog_block_api(BlockService::new( config.chain_id.clone(), block_provider, client_authenticator, @@ -182,7 +182,7 @@ where let config_json = serde_json::to_string(&self.config).expect("failed to serialize config to JSON"); let get_config_json = Arc::new(move || Ok(config_json.clone())); - let admin_service = ledger_grpc::create_ledger_router_admin_api(self.admin_service.clone()); + let admin_service = fog_ledger::create_ledger_router_admin_api(self.admin_service.clone()); // Prevent from being dropped self.admin_server = AdminServer::start( diff --git a/fog/ledger/server/src/router_service.rs b/fog/ledger/server/src/router_service.rs index 1d364c69bc..6602919f35 100644 --- a/fog/ledger/server/src/router_service.rs +++ b/fog/ledger/server/src/router_service.rs @@ -8,9 +8,9 @@ use futures::{FutureExt, TryFutureExt}; use grpcio::{DuplexSink, RequestStream, RpcContext, UnarySink}; use mc_attest_api::attest::{AuthMessage, Message}; use mc_common::logger::{log, Logger}; -use mc_fog_api::{ - ledger::{LedgerRequest, LedgerResponse}, - ledger_grpc::{self, FogKeyImageApi, KeyImageStoreApiClient, LedgerApi}, +use mc_fog_api::fog_ledger::{ + self, ledger_response, FogKeyImageApi, KeyImageStoreApiClient, LedgerApi, LedgerRequest, + LedgerResponse, }; use mc_fog_ledger_enclave::LedgerEnclaveProxy; use mc_fog_uri::KeyImageStoreUri; @@ -29,7 +29,7 @@ where E: LedgerEnclaveProxy, { enclave: E, - shards: Arc>>>, + shards: Arc>>>, query_retries: usize, logger: Logger, } @@ -39,7 +39,7 @@ impl LedgerRouterService { /// fulfill gRPC requests. pub fn new( enclave: E, - shards: Arc>>>, + shards: Arc>>>, query_retries: usize, logger: Logger, ) -> Self { @@ -116,10 +116,11 @@ where .await; match result { - Ok(mut response) => { - if response.has_check_key_image_response() { - sink.success(response.take_check_key_image_response()).await - } else { + Ok(response) => match response.response_data { + Some(ledger_response::ResponseData::CheckKeyImageResponse(key_images)) => { + sink.success(key_images).await + } + _ => { let error = rpc_internal_error( "Inavlid LedgerRequest response", "Cannot provide a check key image response to the client's key image request." @@ -128,7 +129,7 @@ where ); sink.fail(error).await } - } + }, Err(rpc_status) => sink.fail(rpc_status).await, } } @@ -163,10 +164,9 @@ impl FogKeyImageApi for LedgerRouterService { let logger = logger.clone(); let result = handle_auth_request(self.enclave.clone(), request, logger.clone()); let future = match result { - Ok(mut response) => { - if response.has_auth() { - sink.success(response.take_auth()) - } else { + Ok(response) => match response.response_data { + Some(ledger_response::ResponseData::Auth(auth)) => sink.success(auth), + _ => { let error = rpc_internal_error( "Inavlid LedgerRequest response", "Response to client's auth request did not contain an auth response." @@ -175,7 +175,7 @@ impl FogKeyImageApi for LedgerRouterService { ); sink.fail(error) } - } + }, Err(rpc_status) => sink.fail(rpc_status), } .map_err(move |err| log::error!(&logger, "failed to reply: {}", err)) diff --git a/fog/ledger/server/src/untrusted_tx_out_service.rs b/fog/ledger/server/src/untrusted_tx_out_service.rs index efdb9813e2..ff24f39282 100644 --- a/fog/ledger/server/src/untrusted_tx_out_service.rs +++ b/fog/ledger/server/src/untrusted_tx_out_service.rs @@ -4,10 +4,7 @@ use crate::SVC_COUNTERS; use grpcio::{RpcContext, RpcStatus, UnarySink}; use mc_common::logger::Logger; use mc_crypto_keys::CompressedRistrettoPublic; -use mc_fog_api::{ - ledger::{TxOutRequest, TxOutResponse}, - ledger_grpc::FogUntrustedTxOutApi, -}; +use mc_fog_api::fog_ledger::{FogUntrustedTxOutApi, TxOutRequest, TxOutResponse}; use mc_fog_block_provider::{BlockProvider, TxOutInfoByPublicKeyResponse}; use mc_util_grpc::{ check_request_chain_id, rpc_internal_error, rpc_invalid_arg_error, rpc_logger, send_result, @@ -58,13 +55,11 @@ impl UntrustedTxOutService { rpc_internal_error("get_tX_out_info_by_public_key", err, &self.logger) })?; - let mut response = TxOutResponse::new(); - - response.num_blocks = latest_block.index + 1; - response.global_txo_count = latest_block.cumulative_txo_count; - response.results = results.into(); - - Ok(response) + Ok(TxOutResponse { + num_blocks: latest_block.index + 1, + global_txo_count: latest_block.cumulative_txo_count, + results, + }) } } diff --git a/fog/ledger/server/tests/router_connection.rs b/fog/ledger/server/tests/router_connection.rs index e6a0f81b88..46e3725c20 100644 --- a/fog/ledger/server/tests/router_connection.rs +++ b/fog/ledger/server/tests/router_connection.rs @@ -12,7 +12,7 @@ use mc_common::{ time::SystemTimeProvider, }; use mc_crypto_keys::{CompressedRistrettoPublic, Ed25519Pair}; -use mc_fog_api::ledger::TxOutResultCode; +use mc_fog_api::fog_ledger::TxOutResultCode; use mc_fog_block_provider::LocalBlockProvider; use mc_fog_ledger_connection::{ Error, FogKeyImageGrpcClient, FogMerkleProofGrpcClient, FogUntrustedLedgerGrpcClient, @@ -784,12 +784,12 @@ fn fog_ledger_untrusted_tx_out_api_test(logger: Logger) { &result.results[0].tx_out_pubkey.clone().unwrap().data[..], &[0u8; 32] ); - assert_eq!(result.results[0].result_code, TxOutResultCode::NotFound); + assert_eq!(result.results[0].result_code(), TxOutResultCode::NotFound); assert_eq!( &result.results[1].tx_out_pubkey.clone().unwrap().data[..], &real_tx_out0.public_key.as_bytes()[..] ); - assert_eq!(result.results[1].result_code, TxOutResultCode::Found); + assert_eq!(result.results[1].result_code(), TxOutResultCode::Found); assert_eq!(result.results[1].tx_out_global_index, 0); assert_eq!(result.results[1].block_index, 0); assert_eq!( diff --git a/fog/load_testing/Cargo.toml b/fog/load_testing/Cargo.toml index 26c0b041bb..b0e2584698 100644 --- a/fog/load_testing/Cargo.toml +++ b/fog/load_testing/Cargo.toml @@ -14,7 +14,7 @@ path = "src/bin/ingest.rs" [dependencies] # third party clap = { version = "4.5", features = ["derive", "env"] } -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } retry = "2.0" tempfile = "3.10" diff --git a/fog/load_testing/src/bin/ingest.rs b/fog/load_testing/src/bin/ingest.rs index 37bcd96161..32dc0627ea 100644 --- a/fog/load_testing/src/bin/ingest.rs +++ b/fog/load_testing/src/bin/ingest.rs @@ -28,7 +28,7 @@ use mc_fog_uri::{ConnectionUri, FogIngestUri, IngestPeerUri}; use mc_ledger_db::{test_utils::initialize_ledger, Ledger, LedgerDB}; use mc_rand::McRng; use mc_util_from_random::FromRandom; -use mc_util_grpc::{admin_grpc::AdminApiClient, ConnectionUriGrpcioChannel, Empty}; +use mc_util_grpc::{admin::AdminApiClient, ConnectionUriGrpcioChannel}; use mc_util_uri::AdminUri; use mc_watcher::watcher_db::WatcherDB; use retry::{delay, retry, OperationResult}; @@ -259,7 +259,7 @@ fn load_test(config: &TestConfig, test_params: TestParams, logger: Logger) -> Te let info = retry(delay::Fixed::from_millis(5000).map(delay::jitter), || { ingest_server.assert_not_stopped(); - match admin_client.get_info(&Empty::default()) { + match admin_client.get_info(&()) { Ok(info) => OperationResult::Ok(info), Err(GrpcioError::RpcFailure(err)) => { log::info!(&logger, "Waiting for ingest server to become available"); diff --git a/fog/overseer/server/Cargo.toml b/fog/overseer/server/Cargo.toml index 52d61871f6..d31dd67e2b 100644 --- a/fog/overseer/server/Cargo.toml +++ b/fog/overseer/server/Cargo.toml @@ -15,7 +15,7 @@ path = "src/bin/main.rs" # third-party clap = { version = "4.5", features = ["derive", "env"] } displaydoc = { version = "0.2", default-features = false } -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } lazy_static = "1.4" prometheus = "0.13.3" retry = "2.0" diff --git a/fog/overseer/server/src/metrics/mod.rs b/fog/overseer/server/src/metrics/mod.rs index c90349305d..855ef80057 100644 --- a/fog/overseer/server/src/metrics/mod.rs +++ b/fog/overseer/server/src/metrics/mod.rs @@ -32,9 +32,17 @@ pub fn set_metrics(logger: &Logger, ingest_summaries: &[IngestSummary]) { } fn get_ingress_key_count(ingest_summaries: &[IngestSummary]) -> i64 { + let default_pubkey = Default::default(); let ingress_key_count = ingest_summaries .iter() - .map(|ingest_summary| ingest_summary.get_ingress_pubkey().get_data()) + .map(|ingest_summary| { + ingest_summary + .ingress_pubkey + .as_ref() + .unwrap_or(&default_pubkey) + .data + .as_slice() + }) .collect::>() .len(); @@ -44,7 +52,7 @@ fn get_ingress_key_count(ingest_summaries: &[IngestSummary]) -> i64 { fn get_egress_key_count(ingest_summaries: &[IngestSummary]) -> i64 { let egress_key_count = ingest_summaries .iter() - .map(|ingest_summary| ingest_summary.get_egress_pubkey()) + .map(|ingest_summary| ingest_summary.egress_pubkey.as_slice()) .collect::>() .len(); @@ -54,7 +62,7 @@ fn get_egress_key_count(ingest_summaries: &[IngestSummary]) -> i64 { fn get_active_node_count(ingest_summaries: &[IngestSummary]) -> i64 { ingest_summaries .iter() - .filter(|ingest_summary| ingest_summary.get_mode() == IngestControllerMode::Active) + .filter(|ingest_summary| ingest_summary.mode() == IngestControllerMode::Active) .count() .try_into() .unwrap() diff --git a/fog/overseer/server/src/worker.rs b/fog/overseer/server/src/worker.rs index 919e5f797f..e493e7a3d9 100644 --- a/fog/overseer/server/src/worker.rs +++ b/fog/overseer/server/src/worker.rs @@ -192,7 +192,7 @@ where ingest_summary_node_mappings .iter() .filter(|ingest_summary_node_mapping| { - ingest_summary_node_mapping.ingest_summary.mode + ingest_summary_node_mapping.ingest_summary.mode() == IngestControllerMode::Active }) .collect(); @@ -219,18 +219,21 @@ where "There is one active node in the Fog Ingest cluster. Active ingress key: {:?}", active_ingest_summary_node_mappings[0] .ingest_summary - .get_ingress_pubkey() + .ingress_pubkey ); continue; } _ => { + let default_pubkey = Default::default(); let active_node_ingress_pubkeys: Vec<&external::CompressedRistretto> = active_ingest_summary_node_mappings .iter() .map(|active_ingest_summary_node_mapping| { active_ingest_summary_node_mapping .ingest_summary - .get_ingress_pubkey() + .ingress_pubkey + .as_ref() + .unwrap_or(&default_pubkey) }) .collect(); let error_message = @@ -401,7 +404,9 @@ where let node_ingress_key = match CompressedRistrettoPublic::try_from( ingest_summary_node_mapping .ingest_summary - .get_ingress_pubkey(), + .ingress_pubkey + .as_ref() + .unwrap_or(&Default::default()), ) { Ok(key) => key, Err(_) => continue, diff --git a/fog/report/api/Cargo.toml b/fog/report/api/Cargo.toml index 6c3f706f6a..67a15d8c4e 100644 --- a/fog/report/api/Cargo.toml +++ b/fog/report/api/Cargo.toml @@ -10,8 +10,8 @@ rust-version = { workspace = true } [dependencies] futures = "0.3" -grpcio = "0.13" -protobuf = "2.27.1" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } +prost = { version = "0.11", default-features = false, features = ["prost-derive"] } mc-api = { path = "../../../api" } mc-attest-api = { path = "../../../attest/api" } diff --git a/fog/report/api/src/lib.rs b/fog/report/api/src/lib.rs index fba7ee6ed5..bba90060e0 100644 --- a/fog/report/api/src/lib.rs +++ b/fog/report/api/src/lib.rs @@ -1,95 +1,87 @@ // Copyright (c) 2018-2022 The MobileCoin Foundation -// workaround for #![allow(box_pointers)] in protobuf generated files. -#![allow(renamed_and_removed_lints)] - mod autogenerated_code { // Expose proto data types from included third-party/external proto files. pub use mc_api::{blockchain, external}; - pub use protobuf::well_known_types::Empty; - - // Needed due to how to the auto-generated code references the Empty message. - pub mod empty { - pub use protobuf::well_known_types::Empty; + // Include sthe auto-generated code. + pub mod fog_report { + include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/report.rs")); } - - // Include the auto-generated code. - include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/mod.rs")); } -use crate::report::Report_oneof_attestation_evidence; +use crate::fog_report::report::AttestationEvidence as ProtoAttestationEvidence; pub use autogenerated_code::*; use mc_attest_verifier_types::{prost, VerificationReport}; use mc_fog_report_types::AttestationEvidence; // These are needed for tests -impl Eq for report::Report {} -impl Eq for report::ReportResponse {} +impl Eq for fog_report::Report {} +impl Eq for fog_report::ReportResponse {} -impl From for AttestationEvidence { - fn from(value: Report_oneof_attestation_evidence) -> Self { +impl From for AttestationEvidence { + fn from(value: ProtoAttestationEvidence) -> Self { match value { - Report_oneof_attestation_evidence::dcap_evidence(evidence) => { + ProtoAttestationEvidence::DcapEvidence(evidence) => { prost::DcapEvidence::from(&evidence).into() } - Report_oneof_attestation_evidence::verification_report(report) => { + ProtoAttestationEvidence::VerificationReport(report) => { VerificationReport::from(&report).into() } } } } -impl From<&AttestationEvidence> for Report_oneof_attestation_evidence { +impl From<&AttestationEvidence> for ProtoAttestationEvidence { fn from(value: &AttestationEvidence) -> Self { match value { AttestationEvidence::DcapEvidence(evidence) => { - Report_oneof_attestation_evidence::dcap_evidence(evidence.into()) + ProtoAttestationEvidence::DcapEvidence(evidence.into()) } AttestationEvidence::VerificationReport(report) => { - Report_oneof_attestation_evidence::verification_report(report.into()) + ProtoAttestationEvidence::VerificationReport(report.into()) } } } } -impl From for mc_fog_report_types::Report { - fn from(mut src: report::Report) -> mc_fog_report_types::Report { +impl From for mc_fog_report_types::Report { + fn from(src: fog_report::Report) -> mc_fog_report_types::Report { mc_fog_report_types::Report { - fog_report_id: src.take_fog_report_id(), + fog_report_id: src.fog_report_id, attestation_evidence: src.attestation_evidence.map(|x| x.into()), pubkey_expiry: src.pubkey_expiry, } } } -impl From for report::Report { - fn from(src: mc_fog_report_types::Report) -> report::Report { - let mut result = report::Report::new(); - result.set_fog_report_id(src.fog_report_id); - result.attestation_evidence = src.attestation_evidence.as_ref().map(|x| x.into()); - result.set_pubkey_expiry(src.pubkey_expiry); - result +impl From for fog_report::Report { + fn from(src: mc_fog_report_types::Report) -> fog_report::Report { + Self { + fog_report_id: src.fog_report_id, + attestation_evidence: src.attestation_evidence.as_ref().map(|x| x.into()), + pubkey_expiry: src.pubkey_expiry, + } } } -impl From for mc_fog_report_types::ReportResponse { - fn from(src: report::ReportResponse) -> Self { +impl From for mc_fog_report_types::ReportResponse { + fn from(src: fog_report::ReportResponse) -> Self { Self { // Note: this is out of order because get_chain is a borrow, but the // iter below is a partial move. - chain: src.get_chain().into(), + chain: src.chain, reports: src.reports.into_iter().map(|x| x.into()).collect(), signature: src.signature, } } } -impl From for report::ReportResponse { +impl From for fog_report::ReportResponse { fn from(src: mc_fog_report_types::ReportResponse) -> Self { - let mut result = report::ReportResponse::new(); - result.set_signature(src.signature); - result.set_chain(src.chain.into()); - result.set_reports(src.reports.into_iter().map(|x| x.into()).collect()); - result + Self { + reports: src.reports.into_iter().map(|x| x.into()).collect(), + chain: src.chain, + signature: src.signature, + } } } diff --git a/fog/report/api/test-utils/Cargo.toml b/fog/report/api/test-utils/Cargo.toml index 4456534453..e38d59cddc 100644 --- a/fog/report/api/test-utils/Cargo.toml +++ b/fog/report/api/test-utils/Cargo.toml @@ -10,4 +10,3 @@ rust-version = { workspace = true } [dependencies] mc-util-serial = { path = "../../../../util/serial" } prost = { version = "0.11", default-features = false, features = ["prost-derive"] } -protobuf = "2.22.1" diff --git a/fog/report/api/test-utils/src/lib.rs b/fog/report/api/test-utils/src/lib.rs index 8844441903..5f91fb4909 100644 --- a/fog/report/api/test-utils/src/lib.rs +++ b/fog/report/api/test-utils/src/lib.rs @@ -1,53 +1,26 @@ // Copyright (c) 2018-2022 The MobileCoin Foundation use prost::Message as ProstMessage; -use protobuf::Message as ProtobufMessage; -/// Take a ProstMessage value, and a ProtobufMessage type. +/// Take two ProstMessage values . /// -/// Try to encode the prost message, decode as protobuf, re-encode that, and -/// decode as prost again, and check that you got the original value back. -/// This ensures that the fields in the manually written, prosty rust structure, -/// are at least a subset of the fields in the .proto file, so no data loss -/// occurs if the client decodes using that .proto file. -/// -/// We could have another version of this function that tests that the -/// ProtobufMessage round-trips through the prosty structure. That would ensure -/// that the struct and the .proto are identical. I haven't found that necessary -/// yet but maybe I'm wrong. It would have caught a subtle bug where we were -/// using external.TxOut instead of transaction.TxOut in the fog view proto. -pub fn round_trip_message( +/// Try to encode the first prost message, decode as the second prost message, +/// re-encode that, and decode as first prost again, and check that you got the +/// original value back. This ensures that the fields in the manually written, +/// prosty rust structure, are at least a subset of the fields in the .proto +/// file, so no data loss occurs if the client decodes using that .proto file. +pub fn round_trip_message( prost_val: &SRC, ) { let prost_bytes = mc_util_serial::encode(prost_val); let dest_val = - DEST::parse_from_bytes(&prost_bytes).expect("Parsing protobuf from prost bytes failed"); + DEST::decode(prost_bytes.as_slice()).expect("Parsing protobuf from prost bytes failed"); - let protobuf_bytes = dest_val - .write_to_bytes() - .expect("Writing protobuf to bytes failed"); + let protobuf_bytes = dest_val.encode_to_vec(); let final_val: SRC = mc_util_serial::decode(&protobuf_bytes) .expect("Parsing prost back from protobuf bytes failed"); assert_eq!(*prost_val, final_val); } - -pub fn round_trip_protobuf_object( - protobuf_val: &SRC, -) { - let protobuf_bytes = protobuf_val - .write_to_bytes() - .expect("Writing protobuf to bytes failed"); - - let prost_val: DEST = - mc_util_serial::decode(&protobuf_bytes).expect("Parsing prost from protobuf bytes failed"); - - let prost_bytes = mc_util_serial::encode(&prost_val); - - let final_val = - SRC::parse_from_bytes(&prost_bytes).expect("Parsing protobuf back from prost bytes failed"); - - assert_eq!(*protobuf_val, final_val); -} diff --git a/fog/report/api/tests/fog_types.rs b/fog/report/api/tests/fog_types.rs index 2f6210aeef..a99cb5867d 100644 --- a/fog/report/api/tests/fog_types.rs +++ b/fog/report/api/tests/fog_types.rs @@ -7,21 +7,20 @@ use mc_fog_report_api::{ DcapEvidence as ProtobufDcapEvidence, EnclaveReportDataContents as ProtobufEnclaveReportDataContents, }, - report::{Report as ProtobufReport, ReportResponse as ProtobufReportResponse}, + fog_report::{report, Report as ProtobufReport, ReportResponse as ProtobufReportResponse}, }; -use mc_fog_report_api_test_utils::{round_trip_message, round_trip_protobuf_object}; +use mc_fog_report_api_test_utils::round_trip_message; use mc_fog_report_types::{ AttestationEvidence as ProstAttestationEvidence, Report as ProstReport, ReportResponse as ProstReportResponse, }; -use protobuf::{Message as ProtobufMessage, RepeatedField}; // Round trip a structure through protobuf type, once using serialization to // bytes and deserialization, and once using the From conversions. fn round_trip_prosty(prost_val: SRC) where SRC: ProstMessage + Eq + Default + Clone + From, - DEST: ProtobufMessage + From, + DEST: ProstMessage + Default + From, { round_trip_message::(&prost_val); @@ -33,10 +32,10 @@ where // bytes and deserialization, and once using the From conversions. fn round_trip_protobuf(protobuf_val: SRC) where - SRC: ProtobufMessage + Eq + Clone + From, + SRC: ProstMessage + Default + Eq + Clone + From, DEST: ProstMessage + Default + From, { - round_trip_protobuf_object::(&protobuf_val); + round_trip_message::(&protobuf_val); let protobuf_val2 = SRC::from(DEST::from(protobuf_val.clone())); assert!(protobuf_val == protobuf_val2); @@ -83,29 +82,42 @@ fn prost_test_cases() -> Vec { } fn protobuf_dcap_evidence(name: &str) -> ProtobufDcapEvidence { - let mut report_data = ProtobufEnclaveReportDataContents::new(); - report_data.set_nonce(format!("{name} protobuf nonce").into_bytes()); - report_data.set_key(format!("{name} protobuf key").into_bytes()); - report_data.set_custom_identity(format!("{name} protobuf custom_identity").into_bytes()); - let mut dcap_evidence = ProtobufDcapEvidence::new(); - dcap_evidence.set_report_data(report_data); - - dcap_evidence + let report_data = ProtobufEnclaveReportDataContents { + nonce: format!("{name} protobuf nonce").into_bytes(), + key: format!("{name} protobuf key").into_bytes(), + custom_identity: format!("{name} protobuf custom_identity").into_bytes(), + }; + + ProtobufDcapEvidence { + report_data: Some(report_data), + ..Default::default() + } } // Make some prost test cases fn protobuf_test_cases() -> Vec { - let mut rep1 = ProtobufReport::new(); - rep1.set_dcap_evidence(protobuf_dcap_evidence("asdf")); - rep1.set_pubkey_expiry(199); + let rep1 = ProtobufReport { + attestation_evidence: Some(report::AttestationEvidence::DcapEvidence( + protobuf_dcap_evidence("foo"), + )), + pubkey_expiry: 199, + ..Default::default() + }; - let mut rep2 = ProtobufReport::new(); - rep2.set_fog_report_id("non".to_string()); - rep2.set_dcap_evidence(protobuf_dcap_evidence("jkl")); - rep2.set_pubkey_expiry(11); + let rep2 = ProtobufReport { + attestation_evidence: Some(report::AttestationEvidence::DcapEvidence( + protobuf_dcap_evidence("non"), + )), + pubkey_expiry: 11, + ..Default::default() + }; - let mut rep3 = ProtobufReport::new(); - rep3.set_dcap_evidence(protobuf_dcap_evidence(";;;")); + let rep3 = ProtobufReport { + attestation_evidence: Some(report::AttestationEvidence::DcapEvidence( + protobuf_dcap_evidence(";;;"), + )), + ..Default::default() + }; vec![rep1, rep2, rep3] } @@ -139,9 +151,10 @@ fn round_trip_prost_report_response() { #[test] fn round_trip_protobuf_report_response() { - let mut case = ProtobufReportResponse::new(); - case.set_reports(RepeatedField::from_vec(protobuf_test_cases())); - case.set_chain(make_chain().into()); - case.set_signature(b"report signature".to_vec()); + let case = ProtobufReportResponse { + reports: protobuf_test_cases(), + chain: make_chain(), + signature: b"report signature".to_vec(), + }; round_trip_protobuf::(case); } diff --git a/fog/report/cli/Cargo.toml b/fog/report/cli/Cargo.toml index 43f839ba85..dfa3b7d2a4 100644 --- a/fog/report/cli/Cargo.toml +++ b/fog/report/cli/Cargo.toml @@ -27,5 +27,5 @@ mc-util-uri = { path = "../../../util/uri" } base64 = "0.21" clap = { version = "4.5", features = ["derive", "env"] } -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } hex = "0.4" diff --git a/fog/report/connection/Cargo.toml b/fog/report/connection/Cargo.toml index 93026f9c05..0325e88a36 100644 --- a/fog/report/connection/Cargo.toml +++ b/fog/report/connection/Cargo.toml @@ -17,4 +17,4 @@ mc-util-serial = { path = "../../../util/serial" } mc-util-uri = { path = "../../../util/uri" } displaydoc = "0.2" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } diff --git a/fog/report/connection/src/lib.rs b/fog/report/connection/src/lib.rs index ef527af91f..2ed18b0857 100644 --- a/fog/report/connection/src/lib.rs +++ b/fog/report/connection/src/lib.rs @@ -10,7 +10,7 @@ use displaydoc::Display; use grpcio::{CallOption, ChannelBuilder, Environment, MetadataBuilder}; use mc_common::logger::{log, o, Logger}; -use mc_fog_report_api::{report::ReportRequest, report_grpc}; +use mc_fog_report_api::{fog_report, fog_report::ReportRequest}; use mc_fog_report_types::ReportResponse; use mc_util_grpc::{ConnectionUriGrpcioChannel, CHAIN_ID_GRPC_HEADER}; use mc_util_uri::FogUri; @@ -83,7 +83,7 @@ impl GrpcFogReportConnection { // Build channel to this URI let ch = ChannelBuilder::default_channel_builder(self.env.clone()).connect_to_uri(uri, &logger); - let report_grpc_client = report_grpc::ReportApiClient::new(ch); + let report_grpc_client = fog_report::ReportApiClient::new(ch); // Request reports let mut metadata_builder = MetadataBuilder::new(); @@ -93,13 +93,13 @@ impl GrpcFogReportConnection { .expect("Could not add chain-id header"); } - let req = ReportRequest::new(); + let req = ReportRequest::default(); let resp = report_grpc_client.get_reports_opt( &req, CallOption::default().headers(metadata_builder.build()), )?; - if resp.reports.len() == 0 { + if resp.reports.is_empty() { log::warn!( self.logger, "Report server at {} has no available reports", diff --git a/fog/report/server/Cargo.toml b/fog/report/server/Cargo.toml index 00fa9c2cc9..adc8527728 100644 --- a/fog/report/server/Cargo.toml +++ b/fog/report/server/Cargo.toml @@ -33,7 +33,7 @@ mc-util-uri = { path = "../../../util/uri" } clap = { version = "4.5", features = ["derive", "env"] } displaydoc = "0.2" futures = "0.3" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } lazy_static = "1.4" pem = "3.0" prost = "0.11" diff --git a/fog/report/server/src/server.rs b/fog/report/server/src/server.rs index e2db2be0cf..7c80c68229 100644 --- a/fog/report/server/src/server.rs +++ b/fog/report/server/src/server.rs @@ -6,7 +6,7 @@ use crate::{config::Materials, service::Service}; use futures::executor::block_on; use grpcio::{Server as GrpcioServer, ServerBuilder}; use mc_common::logger::{log, Logger}; -use mc_fog_api::report_grpc; +use mc_fog_api::fog_report; use mc_fog_recovery_db_iface::ReportDb; use mc_util_grpc::{ConnectionUriGrpcioServer, HealthService}; use mc_util_uri::{ConnectionUri, FogUri}; @@ -35,7 +35,7 @@ impl Server { ); let report_service = - report_grpc::create_report_api(Service::new(chain_id, db, materials, logger.clone())); + fog_report::create_report_api(Service::new(chain_id, db, materials, logger.clone())); log::debug!(logger, "Constructed Report GRPC Service"); // Health check service diff --git a/fog/report/server/src/service.rs b/fog/report/server/src/service.rs index 741f0e2ef0..7d6a98a6ce 100644 --- a/fog/report/server/src/service.rs +++ b/fog/report/server/src/service.rs @@ -7,9 +7,8 @@ use displaydoc::Display; use grpcio::{RpcContext, RpcStatus, UnarySink}; use mc_common::logger::{self, log, Logger}; use mc_crypto_keys::SignatureError; -use mc_fog_api::{ - report::{ReportRequest as ProtobufReportRequest, ReportResponse as ProtobufReportResponse}, - report_grpc::ReportApi, +use mc_fog_api::fog_report::{ + ReportApi, ReportRequest as ProtobufReportRequest, ReportResponse as ProtobufReportResponse, }; use mc_fog_recovery_db_iface::{RecoveryDbError, ReportDb}; use mc_fog_report_types::{Report, ReportResponse}; diff --git a/fog/report/server/tests/grpc_apis.rs b/fog/report/server/tests/grpc_apis.rs index 664577ed0b..b3fbcc4862 100644 --- a/fog/report/server/tests/grpc_apis.rs +++ b/fog/report/server/tests/grpc_apis.rs @@ -6,7 +6,7 @@ use grpcio::ChannelBuilder; use mc_attest_verifier_types::prost; use mc_common::logger::{test_with_logger, Logger}; use mc_crypto_keys::{CompressedRistrettoPublic, RistrettoPublic}; -use mc_fog_api::{report::ReportRequest as ProtobufReportRequest, report_grpc}; +use mc_fog_api::{fog_report, fog_report::ReportRequest as ProtobufReportRequest}; use mc_fog_recovery_db_iface::{RecoveryDb, ReportData, ReportDb}; use mc_fog_report_server::{Materials, Server}; use mc_fog_sql_recovery_db::test_utils::SqlRecoveryDbTestContext; @@ -44,11 +44,11 @@ fn report_server_grpc_tests(logger: Logger) { let report_client = { let ch = ChannelBuilder::default_channel_builder(env).connect_to_uri(&client_uri, &logger); - report_grpc::ReportApiClient::new(ch) + fog_report::ReportApiClient::new(ch) }; // Request reports - let req = ProtobufReportRequest::new(); + let req = ProtobufReportRequest::default(); let resp = report_client.get_reports(&req).unwrap(); assert_eq!(resp.reports.len(), 0); @@ -94,15 +94,17 @@ fn report_server_grpc_tests(logger: Logger) { db.set_report(&ingress_key, report_id1, &report1).unwrap(); // Request reports - let req = ProtobufReportRequest::new(); + let req = ProtobufReportRequest::default(); let resp = report_client.get_reports(&req).unwrap(); assert_eq!(resp.reports.len(), 1); - assert_eq!( - prost::DcapEvidence::from(resp.reports[0].get_dcap_evidence()), - dcap_evidence_0 - ); - assert_eq!(resp.reports[0].get_pubkey_expiry(), report1.pubkey_expiry); + match resp.reports[0].attestation_evidence.as_ref().unwrap() { + fog_report::report::AttestationEvidence::DcapEvidence(dcap_evidence) => { + assert_eq!(prost::DcapEvidence::from(dcap_evidence), dcap_evidence_0); + } + _ => panic!("Unexpected attestation evidence type"), + } + assert_eq!(resp.reports[0].pubkey_expiry, report1.pubkey_expiry); // Update report let updated_report1 = ReportData { @@ -116,18 +118,17 @@ fn report_server_grpc_tests(logger: Logger) { .unwrap(); // Request reports - let req = ProtobufReportRequest::new(); + let req = ProtobufReportRequest::default(); let resp = report_client.get_reports(&req).unwrap(); assert_eq!(resp.reports.len(), 1); - assert_eq!( - prost::DcapEvidence::from(resp.reports[0].get_dcap_evidence()), - dcap_evidence_1 - ); - assert_eq!( - resp.reports[0].get_pubkey_expiry(), - updated_report1.pubkey_expiry - ); + match resp.reports[0].attestation_evidence.as_ref().unwrap() { + fog_report::report::AttestationEvidence::DcapEvidence(dcap_evidence) => { + assert_eq!(prost::DcapEvidence::from(dcap_evidence), dcap_evidence_1); + } + _ => panic!("Unexpected attestation evidence type"), + } + assert_eq!(resp.reports[0].pubkey_expiry, updated_report1.pubkey_expiry); // Add second report (DB contains report_bytes1 for report_id1) let report2 = ReportData { @@ -140,37 +141,40 @@ fn report_server_grpc_tests(logger: Logger) { db.set_report(&ingress_key, report_id2, &report2).unwrap(); // Request reports - let req = ProtobufReportRequest::new(); + let req = ProtobufReportRequest::default(); let resp = report_client.get_reports(&req).unwrap(); assert_eq!(resp.reports.len(), 2); - assert_eq!( - prost::DcapEvidence::from(resp.reports[0].get_dcap_evidence()), - dcap_evidence_1 - ); - assert_eq!( - resp.reports[0].get_pubkey_expiry(), - updated_report1.pubkey_expiry - ); - - assert_eq!( - prost::DcapEvidence::from(resp.reports[1].get_dcap_evidence()), - dcap_evidence_0 - ); - assert_eq!(resp.reports[1].get_pubkey_expiry(), report2.pubkey_expiry); + match resp.reports[0].attestation_evidence.as_ref().unwrap() { + fog_report::report::AttestationEvidence::DcapEvidence(dcap_evidence) => { + assert_eq!(prost::DcapEvidence::from(dcap_evidence), dcap_evidence_1); + } + _ => panic!("Unexpected attestation evidence type"), + } + assert_eq!(resp.reports[0].pubkey_expiry, updated_report1.pubkey_expiry); + + match resp.reports[1].attestation_evidence.as_ref().unwrap() { + fog_report::report::AttestationEvidence::DcapEvidence(dcap_evidence) => { + assert_eq!(prost::DcapEvidence::from(dcap_evidence), dcap_evidence_0); + } + _ => panic!("Unexpected attestation evidence type"), + } + assert_eq!(resp.reports[1].pubkey_expiry, report2.pubkey_expiry); // Remove (nil) report db.remove_report(report_id1).unwrap(); // Request reports - let req = ProtobufReportRequest::new(); + let req = ProtobufReportRequest::default(); let resp = report_client.get_reports(&req).unwrap(); assert_eq!(resp.reports.len(), 1); - assert_eq!( - prost::DcapEvidence::from(resp.reports[0].get_dcap_evidence()), - dcap_evidence_0 - ); - assert_eq!(resp.reports[0].get_pubkey_expiry(), report2.pubkey_expiry); + match resp.reports[0].attestation_evidence.as_ref().unwrap() { + fog_report::report::AttestationEvidence::DcapEvidence(dcap_evidence) => { + assert_eq!(prost::DcapEvidence::from(dcap_evidence), dcap_evidence_0); + } + _ => panic!("Unexpected attestation evidence type"), + } + assert_eq!(resp.reports[0].pubkey_expiry, report2.pubkey_expiry); } diff --git a/fog/sample-paykit/Cargo.toml b/fog/sample-paykit/Cargo.toml index 70591324cd..d244a4f4fd 100644 --- a/fog/sample-paykit/Cargo.toml +++ b/fog/sample-paykit/Cargo.toml @@ -55,10 +55,10 @@ mc-fog-view-protocol = { path = "../view/protocol" } clap = { version = "4.5", features = ["derive", "env"] } displaydoc = { version = "0.2", default-features = false } futures = "0.3" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } link-cplusplus = "1.0" # This is needed to support building on darwin which only has libc++ and not libstdc++ mc-attestation-verifier = "0.4.3" -protobuf = "2.27.1" +prost = { version = "0.11", default-features = false, features = ["prost-derive"] } rand = "0.8" serde_json = { version = "1.0", default-features = false, features = ["alloc"] } diff --git a/fog/sample-paykit/src/bin/sample_paykit_remote_wallet.rs b/fog/sample-paykit/src/bin/sample_paykit_remote_wallet.rs index f00f28a2f7..679cc17a69 100644 --- a/fog/sample-paykit/src/bin/sample_paykit_remote_wallet.rs +++ b/fog/sample-paykit/src/bin/sample_paykit_remote_wallet.rs @@ -9,12 +9,10 @@ use grpcio::{RpcContext, RpcStatus, UnarySink}; use mc_account_keys::AccountKey; use mc_common::logger::{create_root_logger, log, Logger}; use mc_fog_sample_paykit::{ - empty::Empty, remote_wallet::{ - BalanceCheckResponse, DebugRequest, DebugResponse, FollowupBalanceCheckRequest, - FreshBalanceCheckRequest, StopRequest, + create_remote_wallet_api, BalanceCheckResponse, DebugRequest, DebugResponse, + FollowupBalanceCheckRequest, FreshBalanceCheckRequest, RemoteWalletApi, StopRequest, }, - remote_wallet_grpc::{create_remote_wallet_api, RemoteWalletApi}, Client, ClientBuilder, }; use mc_fog_uri::{FogLedgerUri, FogViewUri}; @@ -97,7 +95,7 @@ impl RemoteWalletService { // Figure out the view/ledger URIs and adapt the scheme to match what the Rust // clients expect. - let fog_uri = request.get_fog_uri(); + let fog_uri = &request.fog_uri; let (fog_view_uri, fog_ledger_uri) = if fog_uri.starts_with("fog://") { ( FogViewUri::from_str(&fog_uri.replace("fog://", "fog-view://")) @@ -123,7 +121,7 @@ impl RemoteWalletService { }; // Get chain id if any. (Empty string is ignored and this is proto default) - let chain_id = request.get_chain_id(); + let chain_id = &request.chain_id; // Create client and perform balance check. let mut client = ClientBuilder::new( @@ -151,7 +149,6 @@ impl RemoteWalletService { client_id: client_id as u32, balance, block_count: block_count.into(), - ..Default::default() }; log::info!(self.logger, "Fresh balance check: {:?}", response); Ok(response) @@ -174,7 +171,6 @@ impl RemoteWalletService { client_id: request.client_id, balance, block_count: block_count.into(), - ..Default::default() }; log::info!(self.logger, "Followup balance check: {:?}", response); Ok(response) @@ -194,10 +190,7 @@ impl RemoteWalletService { Some(Some(client)) => { let debug_info = client.debug_balance(); - let response = DebugResponse { - debug_info, - ..Default::default() - }; + let response = DebugResponse { debug_info }; log::info!(self.logger, "Debug info: {:?}", response); Ok(response) } @@ -240,7 +233,7 @@ impl RemoteWalletApi for RemoteWalletService { ) } - fn stop(&mut self, ctx: RpcContext, request: StopRequest, sink: UnarySink) { + fn stop(&mut self, ctx: RpcContext, request: StopRequest, sink: UnarySink<()>) { let mut state = self.state.lock().expect("mutex poisoned"); if request.client_id as usize >= state.clients.len() { send_result( @@ -255,7 +248,7 @@ impl RemoteWalletApi for RemoteWalletService { ) } else { state.clients[request.client_id as usize] = None; - send_result(ctx, sink, Ok(Empty::default()), &self.logger) + send_result(ctx, sink, Ok(()), &self.logger) } } @@ -263,11 +256,11 @@ impl RemoteWalletApi for RemoteWalletService { send_result(ctx, sink, self.debug_impl(request), &self.logger) } - fn reset(&mut self, ctx: RpcContext, _request: Empty, sink: UnarySink) { + fn reset(&mut self, ctx: RpcContext, _request: (), sink: UnarySink<()>) { let mut state = self.state.lock().expect("mutex poisoned"); state.clients.clear(); - send_result(ctx, sink, Ok(Empty::default()), &self.logger) + send_result(ctx, sink, Ok(()), &self.logger) } } diff --git a/fog/sample-paykit/src/cached_tx_data/mod.rs b/fog/sample-paykit/src/cached_tx_data/mod.rs index 6a43070dfa..64084384a0 100644 --- a/fog/sample-paykit/src/cached_tx_data/mod.rs +++ b/fog/sample-paykit/src/cached_tx_data/mod.rs @@ -13,7 +13,7 @@ use mc_account_keys::{ use mc_blockchain_types::BlockIndex; use mc_common::logger::{log, Logger}; use mc_crypto_keys::RistrettoPublic; -use mc_fog_api::{fog_common, ledger}; +use mc_fog_api::{fog_common, fog_ledger}; use mc_fog_ledger_connection::{ Error as LedgerConnectionError, FogBlockGrpcClient, FogKeyImageGrpcClient, KeyImageResultExtension, @@ -495,7 +495,7 @@ impl CachedTxData { let updated_missed_block_ranges = CachedTxData::calculate_updated_missed_block_ranges( &self.missed_block_ranges, - &block_response.blocks.into_vec(), + &block_response.blocks.to_vec(), ); self.missed_block_ranges = updated_missed_block_ranges; } @@ -534,7 +534,7 @@ impl CachedTxData { /// retrieved in the BlockData object. fn calculate_updated_missed_block_ranges( missed_block_ranges: &[common::BlockRange], - block_data: &[ledger::BlockData], + block_data: &[fog_ledger::BlockData], ) -> Vec { // Transforms the missed BlockRanges into a set of missed block // indices. @@ -609,8 +609,11 @@ impl CachedTxData { missed_block_indices } - // Converts a ledger::BlockResponses to a Vec. - fn create_tx_out_records(&self, block_response: &ledger::BlockResponse) -> Vec { + // Converts a fog_ledger::BlockResponses to a Vec. + fn create_tx_out_records( + &self, + block_response: &fog_ledger::BlockResponse, + ) -> Vec { let mut tx_out_records: Vec = Vec::new(); for block_data in &block_response.blocks { @@ -1407,15 +1410,17 @@ mod tests { let missed_block_range = common::BlockRange::new(first_index, final_index + 1); let missed_block_ranges = vec![missed_block_range]; - let mut block_data = vec![]; - for index in first_index..final_index + 1 { - let mut block_datum = ledger::BlockData::new(); - block_datum.index = index; - block_data.push(block_datum); - } + let block_data = (first_index..final_index + 1) + .map(|index| fog_ledger::BlockData { + index, + ..Default::default() + }) + .collect::>(); - let updated_missed_block_ranges = - CachedTxData::calculate_updated_missed_block_ranges(&missed_block_ranges, &block_data); + let updated_missed_block_ranges = CachedTxData::calculate_updated_missed_block_ranges( + &missed_block_ranges, + block_data.as_slice(), + ); assert!(updated_missed_block_ranges.is_empty()) } @@ -1464,15 +1469,17 @@ mod tests { let missed_block_range = common::BlockRange::new(first_index, final_index + 1); let missed_block_ranges = vec![missed_block_range]; - let mut block_data = vec![]; - for index in first_index..final_index - 1 { - let mut block_datum = ledger::BlockData::new(); - block_datum.index = index; - block_data.push(block_datum); - } + let block_data = (first_index..final_index + 1) + .map(|index| fog_ledger::BlockData { + index, + ..Default::default() + }) + .collect::>(); - let updated_missed_block_ranges = - CachedTxData::calculate_updated_missed_block_ranges(&missed_block_ranges, &block_data); + let updated_missed_block_ranges = CachedTxData::calculate_updated_missed_block_ranges( + &missed_block_ranges, + block_data.as_slice(), + ); assert_eq!(updated_missed_block_ranges.len(), 1); let updated_missed_block_range = &updated_missed_block_ranges[0]; @@ -1490,13 +1497,14 @@ mod tests { missed_block_ranges.push(missed_block_range); } - let retrieved_block_indices = vec![5, 6, 7, 8, 35, 38, 39, 40, 1, 2]; - let mut block_data = vec![]; - for index in retrieved_block_indices { - let mut block_datum = ledger::BlockData::new(); - block_datum.index = index; - block_data.push(block_datum); - } + let retrieved_block_indices = [5, 6, 7, 8, 35, 38, 39, 40, 1, 2]; + let block_data = retrieved_block_indices + .iter() + .map(|index| fog_ledger::BlockData { + index: *index, + ..Default::default() + }) + .collect::>(); let updated_missed_block_ranges = CachedTxData::calculate_updated_missed_block_ranges(&missed_block_ranges, &block_data); @@ -1523,19 +1531,17 @@ mod tests { let final_index: u64 = 10; let missed_block_range = common::BlockRange::new(first_index, final_index + 1); let missed_block_ranges = vec![missed_block_range]; - let mut block_data = vec![]; let first_unretrieved_index = 3; let second_unretrieved_index = 7; - for index in first_index..final_index + 1 { - if index == first_unretrieved_index || index == second_unretrieved_index { - continue; - } - let mut block_datum = ledger::BlockData::new(); - block_datum.index = index; - block_data.push(block_datum); - } + let block_data = (first_index..final_index + 1) + .filter(|i| *i != first_unretrieved_index && *i != second_unretrieved_index) + .map(|index| fog_ledger::BlockData { + index, + ..Default::default() + }) + .collect::>(); let updated_missed_block_ranges = CachedTxData::calculate_updated_missed_block_ranges(&missed_block_ranges, &block_data); diff --git a/fog/sample-paykit/src/client.rs b/fog/sample-paykit/src/client.rs index 4e534a0a9f..64231f06a0 100644 --- a/fog/sample-paykit/src/client.rs +++ b/fog/sample-paykit/src/client.rs @@ -9,6 +9,7 @@ use crate::{ }; use core::{result::Result as StdResult, str::FromStr}; use mc_account_keys::{AccountKey, PublicAddress}; +use mc_api::printable::printable_wrapper; use mc_attestation_verifier::TrustedIdentity; use mc_blockchain_types::{BlockIndex, BlockVersion}; use mc_common::logger::{log, Logger}; @@ -18,7 +19,7 @@ use mc_connection::{ }; use mc_crypto_keys::CompressedRistrettoPublic; use mc_crypto_ring_signature_signer::{LocalRingSigner, OneTimeKeyDeriveData, RingSigner}; -use mc_fog_api::ledger::TxOutResultCode; +use mc_fog_api::fog_ledger::TxOutResultCode; use mc_fog_ledger_connection::{ FogBlockGrpcClient, FogKeyImageGrpcClient, FogMerkleProofGrpcClient, FogUntrustedLedgerGrpcClient, OutputResultExtension, @@ -972,8 +973,11 @@ impl Client { pub fn get_b58_address(&self) -> String { let public_address = self.account_key.default_subaddress(); - let mut wrapper = mc_api::printable::PrintableWrapper::new(); - wrapper.set_public_address((&public_address).into()); + let wrapper = mc_api::printable::PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress( + (&public_address).into(), + )), + }; wrapper.b58_encode().unwrap() } diff --git a/fog/sample-paykit/src/lib.rs b/fog/sample-paykit/src/lib.rs index 5e371e1984..09f7b1d83e 100644 --- a/fog/sample-paykit/src/lib.rs +++ b/fog/sample-paykit/src/lib.rs @@ -3,20 +3,10 @@ //! MobileCoin Client SDK for Rust #![deny(missing_docs)] #![allow(clippy::result_large_err)] -// workaround for #![allow(box_pointers)] in protobuf generated files. -#![allow(renamed_and_removed_lints)] mod autogenerated_code { - /// Expose proto data types from included third-party/external proto files. - pub use protobuf::well_known_types::Empty; - - /// Needed due to how to the auto-generated code references the Empty - /// message. - pub mod empty { - pub use protobuf::well_known_types::Empty; - } - // Include the auto-generated code. + #![allow(missing_docs)] include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/mod.rs")); } pub use autogenerated_code::*; diff --git a/fog/test-client/Cargo.toml b/fog/test-client/Cargo.toml index cda0d934b4..ba7c6b7796 100644 --- a/fog/test-client/Cargo.toml +++ b/fog/test-client/Cargo.toml @@ -35,7 +35,7 @@ mc-fog-uri = { path = "../uri" } # third-party clap = { version = "4.5", features = ["derive", "env"] } displaydoc = "0.2" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } hex_fmt = "0.3" lazy_static = "1.4" maplit = "1.0" diff --git a/fog/types/src/ingest_common.rs b/fog/types/src/ingest_common.rs index cb47a32629..9dc37ba3db 100644 --- a/fog/types/src/ingest_common.rs +++ b/fog/types/src/ingest_common.rs @@ -8,9 +8,6 @@ use serde::{Deserialize, Serialize}; /// Mirrors the proto definition of IngestSummary. We have to define this /// "native" Rust type to be able to add traits like Serialize to this data. -/// -/// TODO: Once protobuf v3 becomes stable, use its JSON conversion feature -/// where this struct is needed, and delete this struct. #[derive(Deserialize, Serialize)] pub struct IngestSummary { /// The current mode of the server diff --git a/fog/view/connection/Cargo.toml b/fog/view/connection/Cargo.toml index 1efa5c7572..ac2cec3feb 100644 --- a/fog/view/connection/Cargo.toml +++ b/fog/view/connection/Cargo.toml @@ -33,7 +33,7 @@ mc-fog-view-protocol = { path = "../protocol" } aes-gcm = "0.10.3" der = "0.7.8" futures = "0.3" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } mc-attestation-verifier = "0.4.3" retry = "2.0" sha2 = { version = "0.10", default-features = false } diff --git a/fog/view/connection/src/fog_view_router_client.rs b/fog/view/connection/src/fog_view_router_client.rs index c99718f4c3..ace5b5788e 100644 --- a/fog/view/connection/src/fog_view_router_client.rs +++ b/fog/view/connection/src/fog_view_router_client.rs @@ -18,9 +18,9 @@ use mc_common::{ }; use mc_crypto_keys::X25519; use mc_crypto_noise::CipherError; -use mc_fog_api::{ - view::{FogViewRouterRequest, FogViewRouterResponse}, - view_grpc::FogViewRouterApiClient, +use mc_fog_api::fog_view::{ + fog_view_router_request, fog_view_router_response, FogViewRouterApiClient, + FogViewRouterRequest, FogViewRouterResponse, }; use mc_fog_types::view::{QueryRequest, QueryRequestAAD, QueryResponse}; use mc_fog_uri::{ConnectionUri, FogViewRouterUri}; @@ -103,18 +103,26 @@ impl FogViewRouterGrpcClient { let (initiator, auth_request_output) = initiator.try_next(&mut csprng, init_input)?; let attested_message: AuthMessage = auth_request_output.into(); - let mut request = FogViewRouterRequest::new(); - request.set_auth(attested_message); + let request = FogViewRouterRequest { + request_data: Some(fog_view_router_request::RequestData::Auth(attested_message)), + }; self.request_sender .send((request, grpcio::WriteFlags::default())) .await?; - let mut response = self + let response = self .response_receiver .try_next() .await? .ok_or(Error::ResponseNotReceived)?; - let auth_response_msg = response.take_auth(); + let auth_response_msg = + if let Some(fog_view_router_response::ResponseData::Auth(auth_msg)) = + response.response_data + { + auth_msg + } else { + Default::default() + }; let epoch_time = SystemTimeProvider .since_epoch() @@ -170,29 +178,35 @@ impl FogViewRouterGrpcClient { .as_mut() .expect("no enclave_connection even though attest succeeded"); - let mut msg = Message::new(); - msg.set_channel_id(Vec::from(attest_cipher.binding())); - msg.set_aad(aad.clone()); - let plaintext_bytes = mc_util_serial::encode(&plaintext_request); - let request_ciphertext = attest_cipher.encrypt(&aad, &plaintext_bytes)?; - msg.set_data(request_ciphertext); - msg + Message { + channel_id: Vec::from(attest_cipher.binding()), + aad, + data: request_ciphertext, + } + }; + let request = FogViewRouterRequest { + request_data: Some(fog_view_router_request::RequestData::Query(msg.clone())), }; - let mut request = FogViewRouterRequest::new(); - request.set_query(msg); self.request_sender .send((request, grpcio::WriteFlags::default())) .await?; - let message = self + let response = self .response_receiver .try_next() .await? - .ok_or(Error::ResponseNotReceived)? - .take_query(); + .ok_or(Error::ResponseNotReceived)?; + + let message = if let Some(fog_view_router_response::ResponseData::Query(msg)) = + response.response_data + { + msg + } else { + Default::default() + }; { let attest_cipher = self @@ -200,7 +214,8 @@ impl FogViewRouterGrpcClient { .as_mut() .expect("no enclave_connection even though attest succeeded"); - let plaintext_bytes = attest_cipher.decrypt(message.get_aad(), message.get_data())?; + let plaintext_bytes = + attest_cipher.decrypt(message.aad.as_slice(), message.data.as_slice())?; let plaintext_response: QueryResponse = mc_util_serial::decode(&plaintext_bytes)?; Ok(plaintext_response) } diff --git a/fog/view/connection/src/lib.rs b/fog/view/connection/src/lib.rs index 00f0b24f34..b764954548 100644 --- a/fog/view/connection/src/lib.rs +++ b/fog/view/connection/src/lib.rs @@ -13,7 +13,7 @@ use mc_common::{ logger::{log, o, Logger}, trace_time, }; -use mc_fog_api::view_grpc; +use mc_fog_api::fog_view; use mc_fog_enclave_connection::{EnclaveConnection, Error as EnclaveConnectionError}; use mc_fog_types::view::{QueryRequest, QueryRequestAAD, QueryResponse}; use mc_fog_uri::FogViewUri; @@ -26,7 +26,7 @@ use std::{fmt::Display, sync::Arc}; /// A high-level object mediating requests to the fog view service pub struct FogViewGrpcClient { /// The attested connection - conn: EnclaveConnection, + conn: EnclaveConnection, /// The grpc retry config grpc_retry_config: GrpcRetryConfig, /// The uri we connected to @@ -57,7 +57,7 @@ impl FogViewGrpcClient { let ch = ChannelBuilder::default_channel_builder(env).connect_to_uri(&uri, &logger); - let grpc_client = view_grpc::FogViewApiClient::new(ch); + let grpc_client = fog_view::FogViewApiClient::new(ch); Self { conn: EnclaveConnection::new( diff --git a/fog/view/load-test/Cargo.toml b/fog/view/load-test/Cargo.toml index f1cdf839d4..f424333b59 100644 --- a/fog/view/load-test/Cargo.toml +++ b/fog/view/load-test/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" # third party clap = { version = "4.5", features = ["derive", "env"] } ctrlc = "3.4" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } rand = "0.8" # mobilecoin diff --git a/fog/view/server/Cargo.toml b/fog/view/server/Cargo.toml index e2ba54fd33..92f9f21cdf 100644 --- a/fog/view/server/Cargo.toml +++ b/fog/view/server/Cargo.toml @@ -24,7 +24,7 @@ path = "src/bin/router.rs" clap = { version = "4.5", features = ["derive", "env"] } displaydoc = { version = "0.2", default-features = false } futures = "0.3" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } lazy_static = "1.4" prometheus = "0.13" diff --git a/fog/view/server/src/bin/router.rs b/fog/view/server/src/bin/router.rs index 1d87a6d937..b063a82d88 100644 --- a/fog/view/server/src/bin/router.rs +++ b/fog/view/server/src/bin/router.rs @@ -4,7 +4,7 @@ //! MobileCoin Fog View Router target use grpcio::ChannelBuilder; use mc_common::{logger::log, time::SystemTimeProvider}; -use mc_fog_api::view_grpc::FogViewStoreApiClient; +use mc_fog_api::fog_view::FogViewStoreApiClient; use mc_fog_view_enclave::{SgxViewEnclave, ENCLAVE_FILE}; use mc_fog_view_server::{ config::FogViewRouterConfig, diff --git a/fog/view/server/src/fog_view_router_server.rs b/fog/view/server/src/fog_view_router_server.rs index 712606a05e..f6aeaa459e 100644 --- a/fog/view/server/src/fog_view_router_server.rs +++ b/fog/view/server/src/fog_view_router_server.rs @@ -15,7 +15,7 @@ use mc_common::{ logger::{log, Logger}, time::TimeProvider, }; -use mc_fog_api::view_grpc; +use mc_fog_api::fog_view; use mc_fog_types::common::BlockRange; use mc_fog_uri::{ConnectionUri, FogViewStoreUri}; use mc_fog_view_enclave::ViewEnclaveProxy; @@ -46,7 +46,7 @@ pub struct Shard { pub uri: FogViewStoreUri, /// The gRPC client that is used to communicate with the shard. - pub grpc_client: Arc, + pub grpc_client: Arc, /// The `BlockRange` that this shard is responsible for providing. pub block_range: BlockRange, @@ -55,7 +55,7 @@ pub struct Shard { impl Shard { pub fn new( uri: FogViewStoreUri, - grpc_client: Arc, + grpc_client: Arc, block_range: BlockRange, ) -> Self { Self { @@ -107,7 +107,7 @@ where let router_server = match config.client_listen_uri { RouterClientListenUri::Streaming(ref streaming_uri) => { let fog_view_router_service = - view_grpc::create_fog_view_router_api(FogViewRouterService::new( + fog_view::create_fog_view_router_api(FogViewRouterService::new( enclave.clone(), shards, config.chain_id.clone(), @@ -129,7 +129,7 @@ where } RouterClientListenUri::Unary(ref unary_uri) => { let fog_view_router_service = - view_grpc::create_fog_view_api(FogViewRouterService::new( + fog_view::create_fog_view_api(FogViewRouterService::new( enclave.clone(), shards, config.chain_id.clone(), @@ -191,7 +191,7 @@ where let config_json = serde_json::to_string(&self.config).expect("failed to serialize config to JSON"); let get_config_json = Arc::new(move || Ok(config_json.clone())); - let admin_service = view_grpc::create_fog_view_router_admin_api(self.admin_service.clone()); + let admin_service = fog_view::create_fog_view_router_admin_api(self.admin_service.clone()); // Prevent from getting dropped self.admin_server = AdminServer::start( None, diff --git a/fog/view/server/src/fog_view_router_service.rs b/fog/view/server/src/fog_view_router_service.rs index c5646594ec..d6a34dfd6b 100644 --- a/fog/view/server/src/fog_view_router_service.rs +++ b/fog/view/server/src/fog_view_router_service.rs @@ -5,9 +5,9 @@ use futures::{executor::block_on, FutureExt, TryFutureExt}; use grpcio::{DuplexSink, RequestStream, RpcContext, UnarySink}; use mc_attest_api::attest; use mc_common::logger::{log, Logger}; -use mc_fog_api::{ - view::{FogViewRouterRequest, FogViewRouterResponse}, - view_grpc::{FogViewApi, FogViewRouterApi}, +use mc_fog_api::fog_view::{ + fog_view_router_response, FogViewApi, FogViewRouterApi, FogViewRouterRequest, + FogViewRouterResponse, }; use mc_fog_view_enclave_api::ViewEnclaveProxy; use mc_util_grpc::{check_request_chain_id, rpc_logger, send_result, Authenticator}; @@ -108,8 +108,10 @@ where request, self.logger.clone(), ) - .map(|mut response| response.take_auth()); - + .map(|response| match response.response_data { + Some(fog_view_router_response::ResponseData::Auth(auth)) => auth, + _ => Default::default(), + }); send_result(ctx, sink, result, logger); }) } @@ -139,7 +141,10 @@ where self.logger.clone(), &tracer, )) - .map(|mut response| response.take_query()); + .map(|response| match response.response_data { + Some(fog_view_router_response::ResponseData::Query(query)) => query, + _ => Default::default(), + }); send_result(ctx, sink, result, logger) }) diff --git a/fog/view/server/src/fog_view_service.rs b/fog/view/server/src/fog_view_service.rs index fab8a137d9..0aa8abab1f 100644 --- a/fog/view/server/src/fog_view_service.rs +++ b/fog/view/server/src/fog_view_service.rs @@ -6,10 +6,10 @@ use mc_attest_api::attest; use mc_common::logger::{log, Logger}; use mc_fog_api::{ fog_common::BlockRange, - view::{ - MultiViewStoreQueryRequest, MultiViewStoreQueryResponse, MultiViewStoreQueryResponseStatus, + fog_view::{ + FogViewStoreApi, MultiViewStoreQueryRequest, MultiViewStoreQueryResponse, + MultiViewStoreQueryResponseStatus, }, - view_grpc::FogViewStoreApi, }; use mc_fog_recovery_db_iface::RecoveryDb; use mc_fog_types::view::QueryRequestAAD; @@ -82,16 +82,14 @@ where fn auth_impl( &mut self, - mut request: attest::AuthMessage, + request: attest::AuthMessage, logger: &Logger, ) -> Result { // TODO: Use the prost message directly, once available - match self.enclave.frontend_accept(request.take_data().into()) { - Ok((response, _)) => { - let mut result = attest::AuthMessage::new(); - result.set_data(response.into()); - Ok(result) - } + match self.enclave.frontend_accept(request.data.into()) { + Ok((response, _)) => Ok(attest::AuthMessage { + data: response.into(), + }), Err(frontend_error) => { // This is debug because there's no requirement on the remote party to trigger // it. @@ -163,16 +161,17 @@ where tracer.in_span("query_impl", |_cx| { let untrusted_query_response = - self.create_untrusted_query_response(request.get_aad(), &tracer)?; + self.create_untrusted_query_response(request.aad.as_slice(), &tracer)?; let data = tracer.in_span("enclave_query", |_cx| { self.enclave .query(request.into(), untrusted_query_response) .map_err(|e| self.enclave_err_to_rpc_status("enclave request", e)) })?; - let mut resp = attest::Message::new(); - resp.set_data(data); - Ok(resp) + Ok(attest::Message { + data, + ..Default::default() + }) }) } @@ -184,7 +183,7 @@ where let tracer = tracer!(); tracer.in_span("query_nonce_impl", |_cx| { let untrusted_query_response = - self.create_untrusted_query_response(request.get_aad(), &tracer)?; + self.create_untrusted_query_response(request.aad.as_slice(), &tracer)?; let enclave_nonce_message = tracer.in_span("enclave_query_store", |_cx| { self.enclave .query_store(request.into(), untrusted_query_response) @@ -201,11 +200,11 @@ where queries: Vec, logger: &Logger, ) -> MultiViewStoreQueryResponse { - let mut response = MultiViewStoreQueryResponse::new(); + let mut response = MultiViewStoreQueryResponse::default(); let fog_view_store_uri_string = fog_view_store_uri.url().to_string(); - response.set_store_uri(fog_view_store_uri_string); + response.store_uri = fog_view_store_uri_string; let block_range = BlockRange::from(&self.sharding_strategy.get_block_range()); - response.set_block_range(block_range); + response.block_range = Some(block_range); for query in queries.into_iter() { let result = self.query_nonce_impl(query); // Only one of the query messages in an MVSQR is intended for this store @@ -221,17 +220,17 @@ where "process_queries setting state NOT_READY block count: {}", shared_state.processed_block_count ); - response.set_status(MultiViewStoreQueryResponseStatus::NOT_READY); + response.set_status(MultiViewStoreQueryResponseStatus::NotReady); } else { - response.set_query_response(attested_message); - response.set_status(MultiViewStoreQueryResponseStatus::SUCCESS); + response.query_response = Some(attested_message); + response.set_status(MultiViewStoreQueryResponseStatus::Success); } } return response; } } - response.set_status(MultiViewStoreQueryResponseStatus::AUTHENTICATION_ERROR); + response.set_status(MultiViewStoreQueryResponseStatus::AuthenticationError); response } @@ -288,8 +287,7 @@ where if let Err(err) = self.authenticator.authenticate_rpc(&ctx) { return send_result(ctx, sink, err.into(), logger); } - let response = - self.process_queries(self.uri.clone(), request.queries.into_vec(), logger); + let response = self.process_queries(self.uri.clone(), request.queries, logger); send_result(ctx, sink, Ok(response), logger) }); } diff --git a/fog/view/server/src/router_admin_service.rs b/fog/view/server/src/router_admin_service.rs index 26175a3b59..a1c3bb689b 100644 --- a/fog/view/server/src/router_admin_service.rs +++ b/fog/view/server/src/router_admin_service.rs @@ -9,12 +9,12 @@ use grpcio::{ChannelBuilder, RpcContext, RpcStatus, UnarySink}; use mc_common::logger::{log, Logger}; use mc_fog_api::{ fog_common::AddShardRequest, - view_grpc::{FogViewRouterAdminApi, FogViewStoreApiClient}, + fog_view::{FogViewRouterAdminApi, FogViewStoreApiClient}, }; use mc_fog_uri::FogViewStoreUri; use mc_util_grpc::{ rpc_invalid_arg_error, rpc_logger, rpc_precondition_error, send_result, - ConnectionUriGrpcioChannel, Empty, + ConnectionUriGrpcioChannel, }; use std::{ str::FromStr, @@ -32,7 +32,7 @@ impl FogViewRouterAdminService { Self { shards, logger } } - fn add_shard_impl(&mut self, shard_uri: &str, logger: &Logger) -> Result { + fn add_shard_impl(&mut self, shard_uri: &str, logger: &Logger) -> Result<(), RpcStatus> { let view_store_uri = FogViewStoreUri::from_str(shard_uri).map_err(|_| { rpc_invalid_arg_error( "add_shard", @@ -68,19 +68,19 @@ impl FogViewRouterAdminService { let shard = Shard::new(view_store_uri, Arc::new(view_store_client), block_range); shards.push(shard); - Ok(Empty::new()) + Ok(()) } } impl FogViewRouterAdminApi for FogViewRouterAdminService { - fn add_shard(&mut self, ctx: RpcContext, request: AddShardRequest, sink: UnarySink) { + fn add_shard(&mut self, ctx: RpcContext, request: AddShardRequest, sink: UnarySink<()>) { log::info!(self.logger, "Request received in add_shard fn"); let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { send_result( ctx, sink, - self.add_shard_impl(request.get_shard_uri(), logger), + self.add_shard_impl(&request.shard_uri, logger), logger, ); }); diff --git a/fog/view/server/src/router_request_handler.rs b/fog/view/server/src/router_request_handler.rs index 9a5c32305e..159480da1f 100644 --- a/fog/view/server/src/router_request_handler.rs +++ b/fog/view/server/src/router_request_handler.rs @@ -13,9 +13,9 @@ use grpcio::{ChannelBuilder, DuplexSink, RequestStream, RpcStatus, WriteFlags}; use mc_attest_api::attest; use mc_attest_enclave_api::SealedClientMessage; use mc_common::logger::{log, Logger}; -use mc_fog_api::{ - view::{FogViewRouterRequest, FogViewRouterResponse, MultiViewStoreQueryRequest}, - view_grpc::FogViewStoreApiClient, +use mc_fog_api::fog_view::{ + fog_view_router_request, fog_view_router_response, FogViewRouterRequest, FogViewRouterResponse, + FogViewStoreApiClient, MultiViewStoreQueryRequest, }; use mc_fog_types::view::MultiViewStoreQueryResponse; use mc_fog_uri::FogViewStoreUri; @@ -25,6 +25,7 @@ use mc_util_metrics::GrpcMethodName; use mc_util_telemetry::{create_context, tracer, BoxedTracer, FutureExt, Tracer}; use mc_util_uri::ConnectionUri; use std::{sync::Arc, time::Instant}; + const RETRY_COUNT: usize = 3; /// Handles a series of requests sent by the Fog Router client. @@ -61,7 +62,7 @@ where /// Handles a client's request by performing either an authentication or a /// query. pub async fn handle_request( - mut request: FogViewRouterRequest, + request: FogViewRouterRequest, shards: Vec, enclave: E, logger: Logger, @@ -70,21 +71,24 @@ where E: ViewEnclaveProxy, { let tracer = tracer!(); - if request.has_auth() { - tracer.in_span("router_auth", |_cx| { - handle_auth_request(enclave, request.take_auth(), logger) - }) - } else if request.has_query() { - handle_query_request(request.take_query(), enclave, shards, logger, &tracer) - .with_context(create_context(&tracer, "router_query")) - .await - } else { - let rpc_status = rpc_invalid_arg_error( - "Inavlid FogViewRouterRequest request", - "Neither the query nor auth fields were set".to_string(), - &logger, - ); - Err(rpc_status) + match request.request_data { + Some(fog_view_router_request::RequestData::Auth(auth)) => tracer + .in_span("router_auth", |_cx| { + handle_auth_request(enclave, auth, logger) + }), + Some(fog_view_router_request::RequestData::Query(query)) => { + handle_query_request(query, enclave, shards, logger, &tracer) + .with_context(create_context(&tracer, "router_query")) + .await + } + _ => { + let rpc_status = rpc_invalid_arg_error( + "Inavlid FogViewRouterRequest request", + "Neither the query nor auth fields were set".to_string(), + &logger, + ); + Err(rpc_status) + } } } @@ -102,9 +106,11 @@ where router_server_err_to_rpc_status("Auth: e client accept", err.into(), logger) })?; - let mut response = FogViewRouterResponse::new(); - response.mut_auth().set_data(client_auth_response.into()); - Ok(response) + Ok(FogViewRouterResponse { + response_data: Some(fog_view_router_response::ResponseData::Auth( + client_auth_response.into(), + )), + }) } /// Handles a client's query request. @@ -149,9 +155,11 @@ where }) })?; - let mut response = FogViewRouterResponse::new(); - response.set_query(query_response.into()); - Ok(response) + Ok(FogViewRouterResponse { + response_data: Some(fog_view_router_response::ResponseData::Query( + query_response.into(), + )), + }) } async fn get_query_responses( diff --git a/fog/view/server/src/server.rs b/fog/view/server/src/server.rs index c9b9f33e18..890538dea5 100644 --- a/fog/view/server/src/server.rs +++ b/fog/view/server/src/server.rs @@ -15,7 +15,7 @@ use mc_common::{ trace_time, }; use mc_crypto_keys::CompressedRistrettoPublic; -use mc_fog_api::view_grpc; +use mc_fog_api::fog_view; use mc_fog_recovery_db_iface::RecoveryDb; use mc_fog_types::ETxOutRecord; use mc_fog_uri::{ConnectionUri, FogViewStoreUri}; @@ -108,7 +108,7 @@ where let uri = FogViewStoreUri::try_from_responder_id(responder_id, use_tls) .expect("Could not create uri from responder id"); - let fog_view_service = view_grpc::create_fog_view_store_api(FogViewService::new( + let fog_view_service = fog_view::create_fog_view_store_api(FogViewService::new( enclave.clone(), Arc::new(recovery_db), db_poll_thread.get_shared_state(), diff --git a/fog/view/server/src/shard_responses_processor.rs b/fog/view/server/src/shard_responses_processor.rs index f80da31288..2697f91baa 100644 --- a/fog/view/server/src/shard_responses_processor.rs +++ b/fog/view/server/src/shard_responses_processor.rs @@ -97,8 +97,9 @@ mod tests { use super::*; use crate::sharding_strategy::{EpochShardingStrategy, ShardingStrategy}; use grpcio::ChannelBuilder; + use mc_attest_api::attest; use mc_common::logger::test_with_logger; - use mc_fog_api::view_grpc::FogViewStoreApiClient; + use mc_fog_api::fog_view::FogViewStoreApiClient; use mc_fog_types::common::BlockRange; use mc_fog_uri::FogViewStoreScheme; use mc_util_grpc::ConnectionUriGrpcioChannel; @@ -109,22 +110,21 @@ mod tests { shard_index: usize, block_range: BlockRange, ) -> MultiViewStoreQueryResponse { - let mut successful_response = mc_fog_api::view::MultiViewStoreQueryResponse::new(); - let client_auth_request = Vec::new(); - successful_response - .mut_query_response() - .set_data(client_auth_request); let view_uri_string = format!( "{}://node{}.test.mobilecoin.com:{}", FogViewStoreScheme::SCHEME_INSECURE, shard_index, FogViewStoreScheme::DEFAULT_INSECURE_PORT, ); - successful_response.set_store_uri(view_uri_string); - successful_response.set_block_range(mc_fog_api::fog_common::BlockRange::from(&block_range)); - successful_response - .set_status(mc_fog_api::view::MultiViewStoreQueryResponseStatus::SUCCESS); - + let successful_response = mc_fog_api::fog_view::MultiViewStoreQueryResponse { + query_response: Some(attest::NonceMessage { + data: vec![], + ..Default::default() + }), + store_uri: view_uri_string, + block_range: Some(mc_fog_api::fog_common::BlockRange::from(&block_range)), + status: mc_fog_api::fog_view::MultiViewStoreQueryResponseStatus::Success.into(), + }; successful_response .try_into() .expect("Couldn't convert MultiViewStoreQueryResponse proto to internal struct") @@ -133,18 +133,20 @@ mod tests { fn create_failed_mvq_response( shard_index: usize, block_range: BlockRange, - status: mc_fog_api::view::MultiViewStoreQueryResponseStatus, + status: mc_fog_api::fog_view::MultiViewStoreQueryResponseStatus, ) -> MultiViewStoreQueryResponse { - let mut failed_response = mc_fog_api::view::MultiViewStoreQueryResponse::new(); let view_uri_string = format!( "{}://node{}.test.mobilecoin.com:{}", FogViewStoreScheme::SCHEME_INSECURE, shard_index, FogViewStoreScheme::DEFAULT_INSECURE_PORT, ); - failed_response.set_store_uri(view_uri_string); - failed_response.set_block_range(mc_fog_api::fog_common::BlockRange::from(&block_range)); - failed_response.set_status(status); + let failed_response = mc_fog_api::fog_view::MultiViewStoreQueryResponse { + store_uri: view_uri_string, + block_range: Some(mc_fog_api::fog_common::BlockRange::from(&block_range)), + status: status.into(), + ..Default::default() + }; failed_response .try_into() @@ -234,7 +236,7 @@ mod tests { let failed_mvq_response = create_failed_mvq_response( shard_index, block_range, - mc_fog_api::view::MultiViewStoreQueryResponseStatus::AUTHENTICATION_ERROR, + mc_fog_api::fog_view::MultiViewStoreQueryResponseStatus::AuthenticationError, ); let shards_and_responses = vec![(shard, failed_mvq_response)]; @@ -255,7 +257,7 @@ mod tests { let failed_mvq_response = create_failed_mvq_response( shard_index, block_range, - mc_fog_api::view::MultiViewStoreQueryResponseStatus::AUTHENTICATION_ERROR, + mc_fog_api::fog_view::MultiViewStoreQueryResponseStatus::AuthenticationError, ); let shards_and_responses = vec![(shard, failed_mvq_response)]; @@ -276,7 +278,7 @@ mod tests { let failed_mvq_response = create_failed_mvq_response( shard_index, block_range, - mc_fog_api::view::MultiViewStoreQueryResponseStatus::AUTHENTICATION_ERROR, + mc_fog_api::fog_view::MultiViewStoreQueryResponseStatus::AuthenticationError, ); let shards_and_responses = vec![(shard, failed_mvq_response)]; @@ -297,7 +299,7 @@ mod tests { let failed_mvq_response = create_failed_mvq_response( shard_index, block_range, - mc_fog_api::view::MultiViewStoreQueryResponseStatus::NOT_READY, + mc_fog_api::fog_view::MultiViewStoreQueryResponseStatus::NotReady, ); let shards_and_responses = vec![(shard, failed_mvq_response)]; @@ -318,7 +320,7 @@ mod tests { let failed_mvq_response = create_failed_mvq_response( shard_index, block_range, - mc_fog_api::view::MultiViewStoreQueryResponseStatus::NOT_READY, + mc_fog_api::fog_view::MultiViewStoreQueryResponseStatus::NotReady, ); let shards_and_responses = vec![(shard, failed_mvq_response)]; @@ -339,7 +341,7 @@ mod tests { let failed_mvq_response = create_failed_mvq_response( shard_index, block_range, - mc_fog_api::view::MultiViewStoreQueryResponseStatus::NOT_READY, + mc_fog_api::fog_view::MultiViewStoreQueryResponseStatus::NotReady, ); let shards_and_responses = vec![(shard, failed_mvq_response)]; let result = process_shard_responses(shards_and_responses, logger); @@ -362,7 +364,7 @@ mod tests { let failed_mvq_response = create_failed_mvq_response( i, block_range, - mc_fog_api::view::MultiViewStoreQueryResponseStatus::AUTHENTICATION_ERROR, + mc_fog_api::fog_view::MultiViewStoreQueryResponseStatus::AuthenticationError, ); shards_and_clients.push((shard, failed_mvq_response)); } diff --git a/fog/view/server/test-utils/Cargo.toml b/fog/view/server/test-utils/Cargo.toml index 77ff12ade4..dcb4bb6937 100644 --- a/fog/view/server/test-utils/Cargo.toml +++ b/fog/view/server/test-utils/Cargo.toml @@ -28,6 +28,6 @@ mc-fog-view-protocol = { path = "../../protocol" } mc-fog-view-server = { path = "../." } # Third-party -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } mc-attestation-verifier = "0.4.3" portpicker = "0.1.1" diff --git a/fog/view/server/test-utils/src/lib.rs b/fog/view/server/test-utils/src/lib.rs index 1cfaff5836..b4f122f699 100644 --- a/fog/view/server/test-utils/src/lib.rs +++ b/fog/view/server/test-utils/src/lib.rs @@ -9,7 +9,7 @@ use mc_common::{ time::SystemTimeProvider, ResponderId, }; -use mc_fog_api::view_grpc::FogViewStoreApiClient; +use mc_fog_api::fog_view::FogViewStoreApiClient; use mc_fog_recovery_db_iface::{AddBlockDataStatus, IngestInvocationId, RecoveryDb}; use mc_fog_sql_recovery_db::{test_utils::SqlRecoveryDbTestContext, SqlRecoveryDb}; use mc_fog_test_infra::get_enclave_path; diff --git a/go-grpc-gateway/testing/Cargo.toml b/go-grpc-gateway/testing/Cargo.toml index 4c2f90a486..203b121b65 100644 --- a/go-grpc-gateway/testing/Cargo.toml +++ b/go-grpc-gateway/testing/Cargo.toml @@ -33,5 +33,5 @@ mc-fog-report-types = { path = "../../fog/report/types" } clap = { version = "4.5", features = ["derive", "env"] } displaydoc = "0.2" futures = "0.3" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } serde = { version = "1.0", features = ["derive"] } diff --git a/go-grpc-gateway/testing/src/server.rs b/go-grpc-gateway/testing/src/server.rs index c87dd1e58f..ef72819daf 100644 --- a/go-grpc-gateway/testing/src/server.rs +++ b/go-grpc-gateway/testing/src/server.rs @@ -2,7 +2,7 @@ use crate::service::Service; use futures::executor::block_on; use grpcio::{Server as GrpcioServer, ServerBuilder}; use mc_common::logger::{log, Logger}; -use mc_fog_report_api::report_grpc; +use mc_fog_report_api::fog_report; use mc_util_grpc::{ConnectionUriGrpcioServer, HealthService}; use mc_util_uri::{ConnectionUri, FogUri}; use std::sync::Arc; @@ -25,7 +25,7 @@ impl Server { let service = Service::new(chain_id, logger.clone()); - let report_service = report_grpc::create_report_api(service); + let report_service = fog_report::create_report_api(service); log::debug!(logger, "Constructed Report GRPC Service"); // Health check service diff --git a/go-grpc-gateway/testing/src/service.rs b/go-grpc-gateway/testing/src/service.rs index e66cc1b6e9..11bcacbb57 100644 --- a/go-grpc-gateway/testing/src/service.rs +++ b/go-grpc-gateway/testing/src/service.rs @@ -1,8 +1,7 @@ use grpcio::{RpcContext, RpcStatus, UnarySink}; use mc_common::logger::{self, Logger}; -use mc_fog_report_api::{ - report::{ReportRequest as ProtobufReportRequest, ReportResponse as ProtobufReportResponse}, - report_grpc::ReportApi, +use mc_fog_report_api::fog_report::{ + ReportApi, ReportRequest as ProtobufReportRequest, ReportResponse as ProtobufReportResponse, }; use mc_fog_report_server::SVC_COUNTERS; use mc_fog_report_types::ReportResponse; diff --git a/ledger/distribution/Cargo.toml b/ledger/distribution/Cargo.toml index 1f4f8e4a4f..ef889e3b3f 100644 --- a/ledger/distribution/Cargo.toml +++ b/ledger/distribution/Cargo.toml @@ -22,7 +22,7 @@ mc-util-telemetry = { path = "../../util/telemetry", features = ["jaeger"] } clap = { version = "4.5", features = ["derive", "env"] } dirs = "5.0" displaydoc = "0.2" -protobuf = "2.27.1" +prost = { version = "0.11", default-features = false } retry = "2.0" # TODO: Replace with https://github.com/awslabs/aws-sdk-rust when it is ready. rusoto_core = { version = "0.48.0", features = ["rustls"], default-features = false } diff --git a/ledger/distribution/src/main.rs b/ledger/distribution/src/main.rs index b14cb4bc49..06d71a2416 100644 --- a/ledger/distribution/src/main.rs +++ b/ledger/distribution/src/main.rs @@ -13,7 +13,7 @@ use mc_blockchain_types::{BlockData, BlockIndex}; use mc_common::logger::{create_app_logger, log, o, Logger}; use mc_ledger_db::{Ledger, LedgerDB}; use mc_util_telemetry::{mark_span_as_active, start_block_span, tracer, Tracer}; -use protobuf::Message; +use prost::Message; use retry::{delay, retry, OperationResult}; use rusoto_core::{request::BufferedHttpResponse, Region, RusotoError}; use rusoto_s3::{HeadObjectRequest, PutObjectRequest, S3Client, S3}; @@ -142,9 +142,7 @@ impl BlockHandler for S3BlockWriter { self.write_bytes_to_s3( dir.to_str().unwrap(), filename.to_str().unwrap(), - &archive_block - .write_to_bytes() - .expect("failed to serialize ArchiveBlock"), + &archive_block.encode_to_vec(), ); } @@ -178,9 +176,7 @@ impl BlockHandler for S3BlockWriter { self.write_bytes_to_s3( dir.to_str().unwrap(), filename.to_str().unwrap(), - &archive_blocks - .write_to_bytes() - .expect("failed to serialize ArchiveBlocks"), + &archive_blocks.encode_to_vec(), ); } @@ -252,9 +248,7 @@ impl BlockHandler for LocalBlockWriter { let archive_block = blockchain::ArchiveBlock::from(block_data); - let bytes = archive_block - .write_to_bytes() - .expect("failed to serialize ArchiveBlock"); + let bytes = archive_block.encode_to_vec(); let dest = self .path @@ -293,9 +287,7 @@ impl BlockHandler for LocalBlockWriter { let archive_blocks = blockchain::ArchiveBlocks::from(blocks_data); - let bytes = archive_blocks - .write_to_bytes() - .expect("failed to serialize ArchiveBlock"); + let bytes = archive_blocks.encode_to_vec(); let dest = self.path.as_path().join(merged_block_num_to_s3block_path( blocks_data.len() as u64, diff --git a/ledger/sync/Cargo.toml b/ledger/sync/Cargo.toml index ff1c4f36a1..808cbfdbac 100644 --- a/ledger/sync/Cargo.toml +++ b/ledger/sync/Cargo.toml @@ -32,10 +32,10 @@ mc-util-uri = { path = "../../util/uri" } crossbeam-channel = "0.5" displaydoc = "0.2" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } mc-attestation-verifier = "0.4.3" mockall = "0.12.1" -protobuf = "2.27.1" +prost = { version = "0.11", default-features = false, features = ["prost-derive"] } rand = "0.8" reqwest = { version = "0.11", default-features = false, features = ["blocking", "rustls-tls", "gzip"] } retry = "2.0" diff --git a/ledger/sync/src/reqwest_transactions_fetcher.rs b/ledger/sync/src/reqwest_transactions_fetcher.rs index 19558f1c34..5c513cf44e 100644 --- a/ledger/sync/src/reqwest_transactions_fetcher.rs +++ b/ledger/sync/src/reqwest_transactions_fetcher.rs @@ -13,7 +13,7 @@ use mc_common::{ lru::LruCache, ResponderId, }; -use protobuf::Message; +use prost::Message; use reqwest::Error as ReqwestError; use std::{ fs, @@ -167,7 +167,7 @@ impl ReqwestTransactionsFetcher { self.get_block_data_by_index(0, None) } - fn fetch_protobuf_object( + fn fetch_protobuf_object( &self, url: &Url, ) -> Result { @@ -187,7 +187,7 @@ impl ReqwestTransactionsFetcher { bytes }; - let obj = M::parse_from_bytes(&bytes).map_err(|err| { + let obj = M::decode(bytes.as_slice()).map_err(|err| { ReqwestTransactionsFetcherError::InvalidBlockReceived( url.to_string(), format!("protobuf parse failed: {err:?}"), diff --git a/light-client/cli/Cargo.toml b/light-client/cli/Cargo.toml index d96cbb77a6..f1ff554d60 100644 --- a/light-client/cli/Cargo.toml +++ b/light-client/cli/Cargo.toml @@ -24,8 +24,7 @@ mc-util-uri = { path = "../../util/uri" } clap = { version = "4.5", features = ["derive", "env"] } clio = { version = "0.3.5", features = ["clap-parse"] } -grpcio = "0.13.0" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } hex = "0.4" -protobuf = "2.27.1" rayon = "1.9" serde_json = "1.0" diff --git a/light-client/cli/src/bin/main.rs b/light-client/cli/src/bin/main.rs index b448268c16..e01a94ea14 100644 --- a/light-client/cli/src/bin/main.rs +++ b/light-client/cli/src/bin/main.rs @@ -10,7 +10,7 @@ use mc_common::{ ResponderId, }; use mc_consensus_api::{ - consensus_client_grpc::ConsensusClientApiClient, consensus_common_grpc::BlockchainApiClient, + consensus_client::ConsensusClientApiClient, consensus_common::BlockchainApiClient, }; use mc_ledger_sync::ReqwestTransactionsFetcher; use mc_light_client_verifier::{ @@ -18,8 +18,8 @@ use mc_light_client_verifier::{ TrustedValidatorSetConfig, }; use mc_util_grpc::ConnectionUriGrpcioChannel; +use mc_util_serial::Message; use mc_util_uri::ConsensusClientUri; -use protobuf::Message; use rayon::{iter::ParallelIterator, prelude::IntoParallelIterator}; use std::{collections::BTreeSet, fs, io::Write, path::PathBuf, str::FromStr, sync::Arc}; @@ -162,9 +162,11 @@ fn cmd_generate_config( let node_ids = node_configs .iter() .map(|node_config| HexKeyNodeID { - responder_id: ResponderId::from_str(node_config.get_peer_responder_id()).unwrap(), + responder_id: ResponderId::from_str(&node_config.peer_responder_id).unwrap(), public_key: node_config - .get_scp_message_signing_key() + .scp_message_signing_key + .as_ref() + .unwrap() .try_into() .unwrap(), }) @@ -233,9 +235,7 @@ fn cmd_fetch_blocks( let bytes = match out_file_format { FileFormat::ArchiveBlocksProtobuf => { let archive_blocks = ArchiveBlocks::from(&block_data[..]); - archive_blocks - .write_to_bytes() - .expect("failed serializing ArchiveBlocks") + archive_blocks.encode_to_vec() } FileFormat::JsonBlockDataBytesArray => { diff --git a/mobilecoind-dev-faucet/Cargo.toml b/mobilecoind-dev-faucet/Cargo.toml index f69e48e56b..48db68cdd8 100644 --- a/mobilecoind-dev-faucet/Cargo.toml +++ b/mobilecoind-dev-faucet/Cargo.toml @@ -30,7 +30,7 @@ mc-util-uri = { path = "../util/uri" } async-channel = { version = "2" } clap = { version = "4.5", features = ["derive", "env"] } displaydoc = "0.2" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } hex = "0.4" mc-attestation-verifier = "0.4.3" rand = "0.8" diff --git a/mobilecoind-dev-faucet/src/data_types.rs b/mobilecoind-dev-faucet/src/data_types.rs index 6e9011f37d..e12f1f413f 100644 --- a/mobilecoind-dev-faucet/src/data_types.rs +++ b/mobilecoind-dev-faucet/src/data_types.rs @@ -115,11 +115,19 @@ pub struct JsonReceiverTxReceipt { impl From<&api::ReceiverTxReceipt> for JsonReceiverTxReceipt { fn from(src: &api::ReceiverTxReceipt) -> Self { Self { - recipient: JsonPublicAddress::from(src.get_recipient()), - tx_public_key: hex::encode(src.get_tx_public_key().get_data()), - tx_out_hash: hex::encode(src.get_tx_out_hash()), - tombstone: src.get_tombstone(), - confirmation_number: hex::encode(src.get_confirmation_number()), + recipient: JsonPublicAddress::from( + src.recipient.as_ref().unwrap_or(&Default::default()), + ), + tx_public_key: hex::encode( + src.tx_public_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + tx_out_hash: hex::encode(src.tx_out_hash.as_slice()), + tombstone: src.tombstone, + confirmation_number: hex::encode(src.confirmation_number.as_slice()), } } } @@ -146,11 +154,23 @@ pub struct JsonPublicAddress { impl From<&PublicAddress> for JsonPublicAddress { fn from(src: &PublicAddress) -> Self { Self { - view_public_key: hex::encode(src.get_view_public_key().get_data()), - spend_public_key: hex::encode(src.get_spend_public_key().get_data()), - fog_report_url: src.get_fog_report_url().into(), - fog_report_id: src.get_fog_report_id().into(), - fog_authority_sig: hex::encode(src.get_fog_authority_sig()), + view_public_key: hex::encode( + src.view_public_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + spend_public_key: hex::encode( + src.spend_public_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + fog_report_url: src.fog_report_url.clone(), + fog_report_id: src.fog_report_id.clone(), + fog_authority_sig: hex::encode(src.fog_authority_sig.as_slice()), } } } @@ -179,11 +199,11 @@ pub struct JsonSubmitTxResponse { impl From> for JsonSubmitTxResponse { fn from(src: Result) -> Self { match src { - Ok(mut resp) => Self { + Ok(resp) => Self { success: true, err_str: String::default(), receiver_tx_receipt_list: resp - .take_receiver_tx_receipt_list() + .receiver_tx_receipt_list .iter() .map(JsonReceiverTxReceipt::from) .collect(), diff --git a/mobilecoind-dev-faucet/src/lib.rs b/mobilecoind-dev-faucet/src/lib.rs index b33c251b0e..c8be44c6d2 100644 --- a/mobilecoind-dev-faucet/src/lib.rs +++ b/mobilecoind-dev-faucet/src/lib.rs @@ -18,9 +18,9 @@ use worker::{GetUtxoError, UtxoRecord, Worker}; use clap::Parser; use grpcio::ChannelBuilder; use mc_account_keys::AccountKey; -use mc_api::printable::PrintableWrapper; +use mc_api::printable::{printable_wrapper, PrintableWrapper}; use mc_common::logger::{log, o, Logger}; -use mc_mobilecoind_api::{self as api, mobilecoind_api_grpc::MobilecoindApiClient, MobilecoindUri}; +use mc_mobilecoind_api::{self as api, mobilecoind_api::MobilecoindApiClient, MobilecoindUri}; use mc_transaction_core::{ring_signature::KeyImage, TokenId}; use mc_util_grpc::ConnectionUriGrpcioChannel; use mc_util_keyfile::read_keyfile; @@ -199,10 +199,12 @@ impl State { > { // Create a monitor using our account key let monitor_id = { - let mut req = api::AddMonitorRequest::new(); - req.set_account_key(account_key.into()); - req.set_num_subaddresses(2); - req.set_name("faucet".to_string()); + let req = api::AddMonitorRequest { + account_key: Some(account_key.into()), + num_subaddresses: 2, + name: "faucet".to_string(), + ..Default::default() + }; let resp = mobilecoind_api_client .add_monitor(&req) @@ -213,8 +215,10 @@ impl State { // Get the b58 public address for monitor let monitor_b58_address = { - let mut req = api::GetPublicAddressRequest::new(); - req.set_monitor_id(monitor_id.clone()); + let req = api::GetPublicAddressRequest { + monitor_id: monitor_id.clone(), + ..Default::default() + }; let resp = mobilecoind_api_client .get_public_address(&req) @@ -225,8 +229,10 @@ impl State { let monitor_printable_wrapper = PrintableWrapper::b58_decode(monitor_b58_address.clone()) .expect("Could not decode b58 address"); - assert!(monitor_printable_wrapper.has_public_address()); - let monitor_public_address = monitor_printable_wrapper.get_public_address(); + let monitor_public_address = match monitor_printable_wrapper.wrapper { + Some(printable_wrapper::Wrapper::PublicAddress(address)) => address, + _ => panic!("Printable Wrapper did not contain public address"), + }; // Get the network minimum fees and compute faucet amounts let minimum_fees = { @@ -236,7 +242,13 @@ impl State { .get_network_status(&Default::default()) .map_err(|err| format!("Failed getting network status: {err}"))?; - for (k, v) in resp.get_last_block_info().minimum_fees.iter() { + for (k, v) in resp + .last_block_info + .as_ref() + .unwrap_or(&Default::default()) + .minimum_fees + .iter() + { result.insert(k.into(), *v); } @@ -260,13 +272,14 @@ impl State { let printable_wrapper = PrintableWrapper::b58_decode(req.b58_address.clone()) .map_err(|err| format!("Could not decode b58 address: {err}"))?; - let public_address = if printable_wrapper.has_public_address() { - printable_wrapper.get_public_address() - } else { - return Err(format!( - "b58 address '{}' is not a public address", - req.b58_address - )); + let public_address = match printable_wrapper.wrapper { + Some(printable_wrapper::Wrapper::PublicAddress(address)) => address, + _ => { + return Err(format!( + "b58 address '{}' is not a public address", + req.b58_address + )) + } }; let token_id = TokenId::from(req.token_id.as_ref()); @@ -275,16 +288,25 @@ impl State { log::trace!( self.logger, "Got a UTXO: key_image = {:?}, value = {}", - KeyImage::try_from(utxo_record.utxo.get_key_image()).unwrap(), + KeyImage::try_from( + utxo_record + .utxo + .key_image + .as_ref() + .unwrap_or(&Default::default()) + ) + .unwrap(), utxo_record.utxo.value ); // Generate a Tx sending this specific TxOut, less fees - let mut req = api::GenerateTxFromTxOutListRequest::new(); - req.set_account_key((&self.account_key).into()); - req.set_input_list(vec![utxo_record.utxo].into()); - req.set_receiver(public_address.clone()); - req.set_token_id(*token_id); + let req = api::GenerateTxFromTxOutListRequest { + account_key: Some((&self.account_key).into()), + input_list: vec![utxo_record.utxo], + receiver: Some(public_address.clone()), + token_id: *token_id, + ..Default::default() + }; let resp = self .mobilecoind_api_client @@ -294,8 +316,9 @@ impl State { .map_err(|err| format!("Build Tx ended in error: {err}"))?; // Submit the tx proposal - let mut req = api::SubmitTxRequest::new(); - req.set_tx_proposal(resp.get_tx_proposal().clone()); + let req = api::SubmitTxRequest { + tx_proposal: resp.tx_proposal.clone(), + }; let resp = self .mobilecoind_api_client @@ -321,9 +344,11 @@ impl State { // Get up-to-date balances for all the tokens we are tracking let mut balances: HashMap = Default::default(); for (token_id, _) in self.faucet_payout_amounts.iter() { - let mut req = api::GetBalanceRequest::new(); - req.set_monitor_id(self.monitor_id.clone()); - req.set_token_id(**token_id); + let req = api::GetBalanceRequest { + monitor_id: self.monitor_id.clone(), + token_id: **token_id, + ..Default::default() + }; let resp = self .mobilecoind_api_client diff --git a/mobilecoind-dev-faucet/src/slam/mod.rs b/mobilecoind-dev-faucet/src/slam/mod.rs index 04e594065f..4c8ed48edd 100644 --- a/mobilecoind-dev-faucet/src/slam/mod.rs +++ b/mobilecoind-dev-faucet/src/slam/mod.rs @@ -4,7 +4,7 @@ use super::{GetUtxoError, UtxoRecord, Worker}; use displaydoc::Display; use mc_account_keys::{AccountKey, PublicAddress}; use mc_common::logger::{log, o, Logger}; -use mc_mobilecoind_api::{self as api, mobilecoind_api_grpc::MobilecoindApiClient}; +use mc_mobilecoind_api::{self as api, mobilecoind_api::MobilecoindApiClient}; use mc_util_uri::ConsensusClientUri; use std::{ sync::{ @@ -413,31 +413,30 @@ impl SlamState { recipient: &PublicAddress, ) -> api::SubmitTxResponse { // Construct sender receipt. - let mut sender_tx_receipt = api::SenderTxReceipt::new(); - sender_tx_receipt.set_key_image_list(tx.key_images().iter().map(Into::into).collect()); - sender_tx_receipt.set_tombstone(tx.prefix.tombstone_block); + let sender_tx_receipt = api::SenderTxReceipt { + key_image_list: tx.key_images().iter().map(Into::into).collect(), + tombstone: tx.prefix.tombstone_block, + }; // Construct receiver receipts. let receiver_tx_receipts = tx .prefix .outputs .iter() - .map(|tx_out| { - let mut receiver_tx_receipt = api::ReceiverTxReceipt::new(); - receiver_tx_receipt.set_recipient(recipient.into()); - receiver_tx_receipt.set_tx_public_key((&tx_out.public_key).into()); - receiver_tx_receipt.set_tx_out_hash(tx_out.hash().to_vec()); - receiver_tx_receipt.set_tombstone(tx.prefix.tombstone_block); - - receiver_tx_receipt + .map(|tx_out| api::ReceiverTxReceipt { + recipient: Some(recipient.into()), + tx_public_key: Some((&tx_out.public_key).into()), + tx_out_hash: tx_out.hash().to_vec(), + tombstone: tx.prefix.tombstone_block, + ..Default::default() }) .collect(); // Return response. - let mut response = api::SubmitTxResponse::new(); - response.set_sender_tx_receipt(sender_tx_receipt); - response.set_receiver_tx_receipt_list(receiver_tx_receipts); - response + api::SubmitTxResponse { + sender_tx_receipt: Some(sender_tx_receipt), + receiver_tx_receipt_list: receiver_tx_receipts, + } } /// Get at status report for the slam diff --git a/mobilecoind-dev-faucet/src/slam/prepared_utxo.rs b/mobilecoind-dev-faucet/src/slam/prepared_utxo.rs index 2a15d3cd79..4c79420031 100644 --- a/mobilecoind-dev-faucet/src/slam/prepared_utxo.rs +++ b/mobilecoind-dev-faucet/src/slam/prepared_utxo.rs @@ -6,7 +6,7 @@ use mc_api::ConversionError; use mc_common::logger::{log, Logger}; use mc_crypto_ring_signature_signer::{LocalRingSigner, OneTimeKeyDeriveData}; use mc_fog_report_resolver::FogResolver; -use mc_mobilecoind_api::{self as api, mobilecoind_api_grpc::MobilecoindApiClient}; +use mc_mobilecoind_api::{self as api, mobilecoind_api::MobilecoindApiClient}; use mc_transaction_builder::{EmptyMemoBuilder, InputCredentials, TransactionBuilder}; use mc_transaction_core::{ constants::RING_SIZE, @@ -75,13 +75,21 @@ impl PreparedUtxo { // The Tx builder sorts the ring anyways, so it doesn't matter if we always put // the real input first. let (ring, membership_proofs): (Vec, Vec) = proofs_resp - .get_output_list() + .output_list .iter() - .chain(mixins_resp.get_mixins().iter()) + .chain(mixins_resp.mixins.iter()) .map(|tx_out_with_proof| { Ok(( - tx_out_with_proof.get_output().try_into()?, - tx_out_with_proof.get_proof().try_into()?, + tx_out_with_proof + .output + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?, + tx_out_with_proof + .proof + .as_ref() + .unwrap_or(&Default::default()) + .try_into()?, )) }) .collect::, ConversionError>>() @@ -103,9 +111,15 @@ impl PreparedUtxo { mobilecoind_api_client: &MobilecoindApiClient, ) -> Result<(api::GetMembershipProofsResponse, api::GetMixinsResponse), String> { // Get a membership proof for this utxo - let mut req = api::GetMembershipProofsRequest::new(); - req.mut_outputs() - .push(utxo_record.utxo.get_tx_out().clone()); + let req = api::GetMembershipProofsRequest { + outputs: vec![utxo_record + .utxo + .tx_out + .as_ref() + .unwrap_or(&Default::default()) + .clone()], + ..Default::default() + }; let proofs_resp = mobilecoind_api_client .get_membership_proofs_async(&req) @@ -114,10 +128,15 @@ impl PreparedUtxo { .map_err(|err| format!("Request membership proofs ended in error: {err}"))?; // Get mixins for this utxo - let mut req = api::GetMixinsRequest::new(); - req.set_num_mixins(RING_SIZE as u64 - 1); - req.mut_excluded() - .push(utxo_record.utxo.get_tx_out().clone()); + let req = api::GetMixinsRequest { + num_mixins: RING_SIZE as u64 - 1, + excluded: vec![utxo_record + .utxo + .tx_out + .as_ref() + .unwrap_or(&Default::default()) + .clone()], + }; let mixins_resp = mobilecoind_api_client .get_mixins_async(&req) @@ -138,7 +157,11 @@ impl PreparedUtxo { ) -> Result { let mut rng = thread_rng(); // Get block version to target - let block_version = network_state.get_last_block_info().network_block_version; + let block_version = network_state + .last_block_info + .as_ref() + .unwrap_or(&Default::default()) + .network_block_version; let block_version = BlockVersion::try_from(block_version).map_err(|err| { format!("Got invalid block version {block_version} from network ({err})") })?; @@ -147,7 +170,9 @@ impl PreparedUtxo { let value = self.utxo_record.utxo.value; let token_id = self.utxo_record.utxo.token_id; let fee_value = *network_state - .get_last_block_info() + .last_block_info + .as_ref() + .unwrap_or(&Default::default()) .minimum_fees .get(&token_id) .ok_or_else(|| format!("Missing fee for token id: {token_id}"))?; diff --git a/mobilecoind-dev-faucet/src/worker.rs b/mobilecoind-dev-faucet/src/worker.rs index e49cb1f547..150fe26e43 100644 --- a/mobilecoind-dev-faucet/src/worker.rs +++ b/mobilecoind-dev-faucet/src/worker.rs @@ -21,8 +21,8 @@ #![allow(clippy::assertions_on_constants)] use api::{ - external::PublicAddress, mobilecoind_api_grpc::MobilecoindApiClient, SubmitTxResponse, - TxStatus, UnspentTxOut, + external::PublicAddress, mobilecoind_api::MobilecoindApiClient, SubmitTxResponse, TxStatus, + UnspentTxOut, }; use displaydoc::Display; use mc_common::logger::{log, o, Logger}; @@ -306,11 +306,16 @@ impl Worker { // Now wait for monitor state to at least pass this point loop { - let mut req = api::GetMonitorStatusRequest::new(); - req.set_monitor_id(monitor_id.clone()); + let req = api::GetMonitorStatusRequest { + monitor_id: monitor_id.clone(), + }; match client.get_monitor_status(&req) { Ok(resp) => { - let monitor_block_count = resp.get_status().next_block; + let monitor_block_count = resp + .status + .as_ref() + .unwrap_or(&Default::default()) + .next_block; if monitor_block_count >= block_count { log::info!( logger, @@ -570,10 +575,12 @@ impl WorkerTokenState { self.check_on_in_flight_txs(client, logger); // Now, get a fresh unspent tx out list associated to this token - let mut resp = { - let mut req = api::GetUnspentTxOutListRequest::new(); - req.token_id = *self.token_id; - req.monitor_id = monitor_id.to_vec(); + let resp = { + let req = api::GetUnspentTxOutListRequest { + token_id: *self.token_id, + monitor_id: monitor_id.to_vec(), + ..Default::default() + }; client.get_unspent_tx_out_list(&req).map_err(|err| { format!( @@ -602,7 +609,9 @@ impl WorkerTokenState { } let key_image: KeyImage = utxo - .get_key_image() + .key_image + .as_ref() + .unwrap_or(&Default::default()) .try_into() .map_err(|err| format!("invalid key image: {err}"))?; if let Entry::Vacant(e) = self.queued_utxo_trackers.entry(key_image) { @@ -641,7 +650,7 @@ impl WorkerTokenState { // "maybe_send_split_txs" and "maybe_send_defragmentation_tx" are expected // to handle that. let mut non_target_value_utxos: Vec<_> = resp - .take_output_list() + .output_list .into_iter() .filter(|utxo| utxo.token_id == self.token_id && utxo.value != self.target_value) .collect(); @@ -832,7 +841,13 @@ impl WorkerTokenState { // should back off and wait for it to clear and re-evaluate. let key_images: HashSet = top_utxos .iter() - .map(|utxo| utxo.get_key_image().try_into().unwrap()) + .map(|utxo| { + utxo.key_image + .as_ref() + .unwrap_or(&Default::default()) + .try_into() + .unwrap() + }) .collect(); if key_images .iter() @@ -850,9 +865,11 @@ impl WorkerTokenState { // We will repeat this outlay MAX_OUTPUTS - 1 times // (-1 is for a change output, which might be slightly larger than avg_value, or // less due to fees) - let mut outlay = api::Outlay::new(); - outlay.set_receiver(public_address.clone()); - outlay.set_value(avg_value); + let outlay = api::Outlay { + receiver: Some(public_address.clone()), + value: avg_value, + ..Default::default() + }; // Generate a Tx // Note: This will fail if MAX_INPUTS < MAX_OUTPUTS, but right now MAX_INPUTS = @@ -861,19 +878,22 @@ impl WorkerTokenState { MAX_INPUTS >= MAX_OUTPUTS, "MAX_INPUTS < MAX_OUTPUTS, this rebalancing code needs rework" ); - let mut req = api::GenerateTxRequest::new(); - req.set_sender_monitor_id(monitor_id.to_vec()); - req.set_token_id(*self.token_id); - req.set_input_list(top_utxos.iter().cloned().collect()); - req.set_outlay_list(vec![outlay; MAX_OUTPUTS_USIZE - 1].into()); - - let mut resp = client + let req = api::GenerateTxRequest { + sender_monitor_id: monitor_id.to_vec(), + token_id: *self.token_id, + input_list: top_utxos.to_vec(), + outlay_list: vec![outlay; MAX_OUTPUTS_USIZE - 1], + ..Default::default() + }; + + let resp = client .generate_tx(&req) .map_err(|err| format!("Failed to generate rebalancing tx: {err}"))?; // Submit the Tx - let mut req = api::SubmitTxRequest::new(); - req.set_tx_proposal(resp.take_tx_proposal()); + let req = api::SubmitTxRequest { + tx_proposal: resp.tx_proposal, + }; let submit_tx_response = client .submit_tx(&req) .map_err(|err| format!("Failed to submit rebalancing tx: {err}"))?; @@ -903,9 +923,11 @@ impl WorkerTokenState { // We will repeat this outlay MAX_OUTPUTS - 1 times // (-1 is for a change output) // for each split tx we submit. - let mut outlay = api::Outlay::new(); - outlay.set_receiver(public_address.clone()); - outlay.set_value(self.target_value); + let outlay = api::Outlay { + receiver: Some(public_address.clone()), + value: self.target_value, + ..Default::default() + }; // Try to split any top-value utxos that are not already in-flight. for utxo in top_utxos { @@ -914,7 +936,12 @@ impl WorkerTokenState { continue; } // If this utxo is already in-flight, skip it - let key_image: KeyImage = utxo.get_key_image().try_into().unwrap(); + let key_image: KeyImage = utxo + .key_image + .as_ref() + .unwrap_or(&Default::default()) + .try_into() + .unwrap(); if self.key_image_is_in_flight(&key_image) { continue; } @@ -926,19 +953,22 @@ impl WorkerTokenState { ) as usize; // Generate a Tx - let mut req = api::GenerateTxRequest::new(); - req.set_sender_monitor_id(monitor_id.to_vec()); - req.set_token_id(*self.token_id); - req.set_input_list(vec![utxo.clone()].into()); - req.set_outlay_list(vec![outlay.clone(); num_target_value_utxos].into()); - - let mut resp = client + let req = api::GenerateTxRequest { + sender_monitor_id: monitor_id.to_vec(), + token_id: *self.token_id, + input_list: vec![utxo.clone()], + outlay_list: vec![outlay.clone(); num_target_value_utxos], + ..Default::default() + }; + + let resp = client .generate_tx(&req) .map_err(|err| format!("Failed to generate split tx: {err}"))?; // Submit the Tx - let mut req = api::SubmitTxRequest::new(); - req.set_tx_proposal(resp.take_tx_proposal()); + let req = api::SubmitTxRequest { + tx_proposal: resp.tx_proposal, + }; let submit_tx_response = client .submit_tx(&req) .map_err(|err| format!("Failed to submit split tx: {err}"))?; @@ -989,7 +1019,12 @@ impl WorkerTokenState { let (key_images, selected_utxos): (HashSet, Vec<_>) = utxos .iter() .filter_map(|utxo| { - let key_image: KeyImage = utxo.get_key_image().try_into().unwrap(); + let key_image: KeyImage = utxo + .key_image + .as_ref() + .unwrap_or(&Default::default()) + .try_into() + .unwrap(); if self.key_image_is_in_flight(&key_image) { None } else { @@ -1026,24 +1061,29 @@ impl WorkerTokenState { ) as usize; // Generate an outlay - let mut outlay = api::Outlay::new(); - outlay.set_receiver(public_address.clone()); - outlay.set_value(self.target_value); + let outlay = api::Outlay { + receiver: Some(public_address.clone()), + value: self.target_value, + ..Default::default() + }; // Generate a Tx - let mut req = api::GenerateTxRequest::new(); - req.set_sender_monitor_id(monitor_id.to_vec()); - req.set_token_id(*self.token_id); - req.set_input_list(selected_utxos.iter().cloned().collect()); - req.set_outlay_list(vec![outlay; num_target_value_utxos].into()); + let req = api::GenerateTxRequest { + sender_monitor_id: monitor_id.to_vec(), + token_id: *self.token_id, + input_list: selected_utxos.to_vec(), + outlay_list: vec![outlay; num_target_value_utxos], + ..Default::default() + }; - let mut resp = client + let resp = client .generate_tx(&req) .map_err(|err| format!("Failed to generate split tx: {err}"))?; // Submit the Tx - let mut req = api::SubmitTxRequest::new(); - req.set_tx_proposal(resp.take_tx_proposal()); + let req = api::SubmitTxRequest { + tx_proposal: resp.tx_proposal, + }; let submit_tx_response = client .submit_tx(&req) .map_err(|err| format!("Failed to submit split tx: {err}"))?; @@ -1085,10 +1125,10 @@ fn is_tx_still_in_flight( ) -> bool { match client.get_tx_status_as_sender(tx) { Ok(resp) => { - if resp.status == TxStatus::Unknown { + if resp.status() == TxStatus::Unknown { return true; } - if resp.status != TxStatus::Verified { + if resp.status() != TxStatus::Verified { log::error!( logger, "{} Tx ended with status: {:?}", diff --git a/mobilecoind-json/Cargo.toml b/mobilecoind-json/Cargo.toml index 4bb0e84646..547b61ae59 100644 --- a/mobilecoind-json/Cargo.toml +++ b/mobilecoind-json/Cargo.toml @@ -19,9 +19,8 @@ mc-util-grpc = { path = "../util/grpc" } mc-util-serial = { path = "../util/serial", features = ["std"] } clap = { version = "4.5", features = ["derive", "env"] } -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } hex = "0.4" -protobuf = "2.27.1" rocket = { version = "0.5.0", features = ["json"] } serde = "1.0" serde_derive = "1.0" diff --git a/mobilecoind-json/src/bin/main.rs b/mobilecoind-json/src/bin/main.rs index c160251b85..4d741690a7 100644 --- a/mobilecoind-json/src/bin/main.rs +++ b/mobilecoind-json/src/bin/main.rs @@ -9,10 +9,9 @@ use clap::Parser; use grpcio::ChannelBuilder; use mc_api::external::{CompressedRistretto, PublicAddress, RistrettoPrivate}; use mc_common::logger::{create_app_logger, log, o}; -use mc_mobilecoind_api::{self as api, mobilecoind_api_grpc::MobilecoindApiClient, MobilecoindUri}; +use mc_mobilecoind_api::{self as api, mobilecoind_api::MobilecoindApiClient, MobilecoindUri}; use mc_mobilecoind_json::data_types::*; use mc_util_grpc::ConnectionUriGrpcioChannel; -use protobuf::RepeatedField; use rocket::{delete, get, post, routes, serde::json::Json}; use std::sync::Arc; @@ -49,12 +48,11 @@ fn set_password( state: &rocket::State, password: Json, ) -> Result, String> { - let mut req = api::SetDbPasswordRequest::new(); - req.set_password( - hex::decode(password.password.clone()) + let req = api::SetDbPasswordRequest { + password: hex::decode(password.password.clone()) .map_err(|err| format!("Failed decoding password hex: {err}"))?, - ); - let _resp = state + }; + state .mobilecoind_api_client .set_db_password(&req) .map_err(|err| format!("Failed setting password: {err}"))?; @@ -67,12 +65,11 @@ fn unlock_db( state: &rocket::State, password: Json, ) -> Result, String> { - let mut req = api::UnlockDbRequest::new(); - req.set_password( - hex::decode(password.password.clone()) + let req = api::UnlockDbRequest { + password: hex::decode(password.password.clone()) .map_err(|err| format!("Failed decoding password hex: {err}"))?, - ); - let _resp = state + }; + state .mobilecoind_api_client .unlock_db(&req) .map_err(|err| format!("Failed unlocking database: {err}"))?; @@ -84,7 +81,7 @@ fn unlock_db( fn version(state: &rocket::State) -> Result, String> { let resp = state .mobilecoind_api_client - .get_version(&api::Empty::new()) + .get_version(&()) .map_err(|err| format!("Failed getting version: {err}"))?; Ok(Json(JsonMobilecoindVersionResponse::from(&resp))) } @@ -94,7 +91,7 @@ fn version(state: &rocket::State) -> Result) -> Result, String> { let resp = state .mobilecoind_api_client - .generate_root_entropy(&api::Empty::new()) + .generate_root_entropy(&()) .map_err(|err| format!("Failed getting entropy: {err}"))?; Ok(Json(JsonRootEntropyResponse::from(&resp))) } @@ -107,8 +104,9 @@ fn account_key_from_root_entropy( let entropy = hex::decode(root_entropy).map_err(|err| format!("Failed to decode hex key: {err}"))?; - let mut req = api::GetAccountKeyFromRootEntropyRequest::new(); - req.set_root_entropy(entropy.to_vec()); + let req = api::GetAccountKeyFromRootEntropyRequest { + root_entropy: entropy.to_vec(), + }; let resp = state .mobilecoind_api_client @@ -123,7 +121,7 @@ fn account_key_from_root_entropy( fn mnemonic(state: &rocket::State) -> Result, String> { let resp = state .mobilecoind_api_client - .generate_mnemonic(&api::Empty::new()) + .generate_mnemonic(&()) .map_err(|err| format!("Failed getting entropy: {err}"))?; Ok(Json(JsonMnemonicResponse::from(&resp))) } @@ -133,8 +131,10 @@ fn account_key_from_mnemonic( state: &rocket::State, mnemonic: Json, ) -> Result, String> { - let mut req = api::GetAccountKeyFromMnemonicRequest::new(); - req.set_mnemonic(mnemonic.mnemonic.clone()); + let req = api::GetAccountKeyFromMnemonicRequest { + mnemonic: mnemonic.mnemonic.clone(), + ..Default::default() + }; let resp = state .mobilecoind_api_client @@ -151,25 +151,27 @@ fn add_monitor( state: &rocket::State, monitor: Json, ) -> Result, String> { - let mut account_key = api::external::AccountKey::new(); - let mut view_private_key = RistrettoPrivate::new(); - view_private_key.set_data( - hex::decode(&monitor.account_key.view_private_key) + let view_private_key = RistrettoPrivate { + data: hex::decode(&monitor.account_key.view_private_key) .map_err(|err| format!("Failed to decode hex key: {err}"))?, - ); - let mut spend_private_key = RistrettoPrivate::new(); - spend_private_key.set_data( - hex::decode(&monitor.account_key.spend_private_key) + }; + let spend_private_key = RistrettoPrivate { + data: hex::decode(&monitor.account_key.spend_private_key) .map_err(|err| format!("Failed to decode hex key: {err}"))?, - ); - account_key.set_view_private_key(view_private_key); - account_key.set_spend_private_key(spend_private_key); + }; + let account_key = api::external::AccountKey { + view_private_key: Some(view_private_key), + spend_private_key: Some(spend_private_key), + ..Default::default() + }; - let mut req = api::AddMonitorRequest::new(); - req.set_account_key(account_key); - req.set_first_subaddress(monitor.first_subaddress); - req.set_num_subaddresses(monitor.num_subaddresses); - req.set_first_block(0); + let req = api::AddMonitorRequest { + account_key: Some(account_key), + first_subaddress: monitor.first_subaddress, + num_subaddresses: monitor.num_subaddresses, + first_block: 0, + ..Default::default() + }; let monitor_response = state .mobilecoind_api_client @@ -185,10 +187,9 @@ fn remove_monitor(state: &rocket::State, monitor_hex: String) -> Result<( let monitor_id = hex::decode(monitor_hex).map_err(|err| format!("Failed to decode monitor hex: {err}"))?; - let mut req = api::RemoveMonitorRequest::new(); - req.set_monitor_id(monitor_id); + let req = api::RemoveMonitorRequest { monitor_id }; - let _resp = state + state .mobilecoind_api_client .remove_monitor(&req) .map_err(|err| format!("Failed removing monitor: {err}"))?; @@ -201,7 +202,7 @@ fn remove_monitor(state: &rocket::State, monitor_hex: String) -> Result<( fn monitors(state: &rocket::State) -> Result, String> { let resp = state .mobilecoind_api_client - .get_monitor_list(&api::Empty::new()) + .get_monitor_list(&()) .map_err(|err| format!("Failed getting monitor list: {err}"))?; Ok(Json(JsonMonitorListResponse::from(&resp))) } @@ -215,8 +216,7 @@ fn monitor_status( let monitor_id = hex::decode(monitor_hex).map_err(|err| format!("Failed to decode monitor hex: {err}"))?; - let mut req = api::GetMonitorStatusRequest::new(); - req.set_monitor_id(monitor_id); + let req = api::GetMonitorStatusRequest { monitor_id }; let resp = state .mobilecoind_api_client @@ -236,9 +236,11 @@ fn balance( let monitor_id = hex::decode(monitor_hex).map_err(|err| format!("Failed to decode monitor hex: {err}"))?; - let mut req = api::GetBalanceRequest::new(); - req.set_monitor_id(monitor_id); - req.set_subaddress_index(subaddress_index); + let req = api::GetBalanceRequest { + monitor_id, + subaddress_index, + ..Default::default() + }; let resp = state .mobilecoind_api_client @@ -257,9 +259,11 @@ fn utxos( let monitor_id = hex::decode(monitor_hex).map_err(|err| format!("Failed to decode monitor hex: {err}"))?; - let mut req = api::GetUnspentTxOutListRequest::new(); - req.set_monitor_id(monitor_id); - req.set_subaddress_index(subaddress_index); + let req = api::GetUnspentTxOutListRequest { + monitor_id, + subaddress_index, + ..Default::default() + }; let resp = state .mobilecoind_api_client @@ -280,9 +284,10 @@ fn public_address( hex::decode(monitor_hex).map_err(|err| format!("Failed to decode monitor hex: {err}"))?; // Get our public address. - let mut req = api::GetPublicAddressRequest::new(); - req.set_monitor_id(monitor_id); - req.set_subaddress_index(subaddress_index); + let req = api::GetPublicAddressRequest { + monitor_id, + subaddress_index, + }; let resp = state .mobilecoind_api_client @@ -302,14 +307,12 @@ fn create_request_code( .map_err(|err| format!("Failed to parse receiver's public address: {err}"))?; // Generate b58 code - let mut req = api::CreateRequestCodeRequest::new(); - req.set_receiver(receiver); - if let Some(value) = request.value { - req.set_value(u64::from(value)); - } - if let Some(memo) = request.memo.clone() { - req.set_memo(memo); - } + let req = api::CreateRequestCodeRequest { + receiver: Some(receiver), + value: request.value.map(Into::into).unwrap_or_default(), + memo: request.memo.as_ref().map(Into::into).unwrap_or_default(), + ..Default::default() + }; let resp = state .mobilecoind_api_client @@ -325,8 +328,9 @@ fn parse_request_code( state: &rocket::State, b58_code: String, ) -> Result, String> { - let mut req = api::ParseRequestCodeRequest::new(); - req.set_b58_code(b58_code); + let req = api::ParseRequestCodeRequest { + b58_code: b58_code.clone(), + }; let resp = state .mobilecoind_api_client .parse_request_code(&req) @@ -348,8 +352,9 @@ fn create_address_code( .map_err(|err| format!("Failed to parse receiver's public address: {err}"))?; // Generate b58 code - let mut req = api::CreateAddressCodeRequest::new(); - req.set_receiver(receiver); + let req = api::CreateAddressCodeRequest { + receiver: Some(receiver), + }; let resp = state .mobilecoind_api_client @@ -365,8 +370,9 @@ fn parse_address_code( state: &rocket::State, b58_code: String, ) -> Result, String> { - let mut req = api::ParseAddressCodeRequest::new(); - req.set_b58_code(b58_code); + let req = api::ParseAddressCodeRequest { + b58_code: b58_code.clone(), + }; let resp = state .mobilecoind_api_client .parse_address_code(&req) @@ -395,9 +401,11 @@ fn build_and_submit( let public_address = PublicAddress::try_from(&transfer.request_data.receiver)?; // Generate an outlay - let mut outlay = api::Outlay::new(); - outlay.set_receiver(public_address); - outlay.set_value(transfer.request_data.value.into()); + let outlay = api::Outlay { + receiver: Some(public_address), + value: transfer.request_data.value.into(), + ..Default::default() + }; // Get max_input_utxo_value. let max_input_utxo_value = transfer @@ -407,15 +415,19 @@ fn build_and_submit( .unwrap_or(0); // Send the payment request - let mut req = api::SendPaymentRequest::new(); - req.set_sender_monitor_id(monitor_id); - req.set_sender_subaddress(subaddress_index); - req.set_outlay_list(RepeatedField::from_vec(vec![outlay])); - req.set_max_input_utxo_value(max_input_utxo_value); - if let Some(subaddress) = transfer.change_subaddress.as_ref() { - req.set_override_change_subaddress(true); - req.set_change_subaddress(u64::from(subaddress)) - } + let req = api::SendPaymentRequest { + sender_monitor_id: monitor_id.clone(), + sender_subaddress: subaddress_index, + outlay_list: vec![outlay], + max_input_utxo_value, + change_subaddress: transfer + .change_subaddress + .as_ref() + .map(Into::into) + .unwrap_or_default(), + override_change_subaddress: transfer.change_subaddress.is_some(), + ..Default::default() + }; let resp = state .mobilecoind_api_client @@ -453,16 +465,20 @@ fn pay_address_code( .unwrap_or(0); // Send the pay address code request - let mut req = api::PayAddressCodeRequest::new(); - req.set_sender_monitor_id(monitor_id); - req.set_sender_subaddress(subaddress_index); - req.set_receiver_b58_code(transfer.receiver_b58_address_code.clone()); - req.set_amount(amount); - req.set_max_input_utxo_value(max_input_utxo_value); - if let Some(subaddress) = transfer.change_subaddress.as_ref() { - req.set_override_change_subaddress(true); - req.set_change_subaddress(u64::from(subaddress)) - } + let req = api::PayAddressCodeRequest { + sender_monitor_id: monitor_id.clone(), + sender_subaddress: subaddress_index, + receiver_b58_code: transfer.receiver_b58_address_code.clone(), + amount, + max_input_utxo_value, + change_subaddress: transfer + .change_subaddress + .as_ref() + .map(Into::into) + .unwrap_or_default(), + override_change_subaddress: transfer.change_subaddress.is_some(), + ..Default::default() + }; let resp = state .mobilecoind_api_client @@ -493,9 +509,11 @@ fn generate_request_code_transaction( let public_address = PublicAddress::try_from(&request.transfer.receiver)?; // Generate an outlay - let mut outlay = api::Outlay::new(); - outlay.set_receiver(public_address); - outlay.set_value(request.transfer.value.into()); + let outlay = api::Outlay { + receiver: Some(public_address), + value: request.transfer.value.into(), + ..Default::default() + }; let inputs: Vec = request .input_list @@ -507,11 +525,13 @@ fn generate_request_code_transaction( .collect::>()?; // Get a tx proposal - let mut req = api::GenerateTxRequest::new(); - req.set_sender_monitor_id(monitor_id); - req.set_change_subaddress(subaddress_index); - req.set_outlay_list(RepeatedField::from_vec(vec![outlay])); - req.set_input_list(RepeatedField::from_vec(inputs)); + let req = api::GenerateTxRequest { + sender_monitor_id: monitor_id.clone(), + change_subaddress: subaddress_index, + outlay_list: vec![outlay], + input_list: inputs, + ..Default::default() + }; let resp = state .mobilecoind_api_client @@ -528,11 +548,12 @@ fn submit_tx( proposal: Json, ) -> Result, String> { // Send the payment request - let mut req = api::SubmitTxRequest::new(); - req.set_tx_proposal( - api::TxProposal::try_from(&proposal.tx_proposal) - .map_err(|err| format!("Failed to convert tx proposal: {err}"))?, - ); + let req = api::SubmitTxRequest { + tx_proposal: Some( + api::TxProposal::try_from(&proposal.tx_proposal) + .map_err(|err| format!("Failed to convert tx proposal: {err}"))?, + ), + }; let resp = state .mobilecoind_api_client @@ -580,20 +601,22 @@ fn check_receiver_transfer_status( let monitor_id = hex::decode(monitor_hex).map_err(|err| format!("Failed to decode monitor hex: {err}"))?; - let mut receiver_receipt = api::ReceiverTxReceipt::new(); - let mut tx_public_key = CompressedRistretto::new(); - tx_public_key.set_data(hex::decode(&receipt.tx_public_key).map_err(|err| format!("{err}"))?); - receiver_receipt.set_tx_public_key(tx_public_key); - receiver_receipt - .set_tx_out_hash(hex::decode(&receipt.tx_out_hash).map_err(|err| format!("{err}"))?); - receiver_receipt.set_tombstone(receipt.tombstone); - receiver_receipt.set_confirmation_number( - hex::decode(&receipt.confirmation_number).map_err(|err| format!("{err}"))?, - ); + let tx_public_key = CompressedRistretto { + data: hex::decode(&receipt.tx_public_key).map_err(|err| format!("{err}"))?, + }; + let receiver_receipt = api::ReceiverTxReceipt { + tx_public_key: Some(tx_public_key), + tx_out_hash: hex::decode(&receipt.tx_out_hash).map_err(|err| format!("{err}"))?, + tombstone: receipt.tombstone, + confirmation_number: hex::decode(&receipt.confirmation_number) + .map_err(|err| format!("{err}"))?, + ..Default::default() + }; - let mut req = api::GetTxStatusAsReceiverRequest::new(); - req.set_receipt(receiver_receipt); - req.set_monitor_id(monitor_id); + let req = api::GetTxStatusAsReceiverRequest { + receipt: Some(receiver_receipt), + monitor_id, + }; let resp = state .mobilecoind_api_client @@ -608,7 +631,7 @@ fn check_receiver_transfer_status( fn ledger_info(state: &rocket::State) -> Result, String> { let resp = state .mobilecoind_api_client - .get_ledger_info(&api::Empty::new()) + .get_ledger_info(&()) .map_err(|err| format!("Failed getting ledger info: {err}"))?; Ok(Json(JsonLedgerInfoResponse::from(&resp))) @@ -620,8 +643,7 @@ fn block_info( state: &rocket::State, block_num: u64, ) -> Result, String> { - let mut req = api::GetBlockInfoRequest::new(); - req.set_block(block_num); + let req = api::GetBlockInfoRequest { block: block_num }; let resp = state .mobilecoind_api_client @@ -637,8 +659,7 @@ fn block_details( state: &rocket::State, block_num: u64, ) -> Result, String> { - let mut req = api::GetBlockRequest::new(); - req.set_block(block_num); + let req = api::GetBlockRequest { block: block_num }; let resp = state .mobilecoind_api_client @@ -657,9 +678,10 @@ fn processed_block( let monitor_id = hex::decode(monitor_hex).map_err(|err| format!("Failed to decode monitor hex: {err}"))?; - let mut req = api::GetProcessedBlockRequest::new(); - req.set_monitor_id(monitor_id); - req.set_block(block_num); + let req = api::GetProcessedBlockRequest { + monitor_id, + block: block_num, + }; let resp = state .mobilecoind_api_client @@ -678,11 +700,13 @@ fn tx_out_get_block_index_by_public_key( let tx_out_public_key = hex::decode(public_key_hex) .map_err(|err| format!("Failed to decode hex public key: {err}"))?; - let mut tx_out_public_key_proto = CompressedRistretto::new(); - tx_out_public_key_proto.set_data(tx_out_public_key); + let tx_out_public_key_proto = CompressedRistretto { + data: tx_out_public_key, + }; - let mut req = api::GetBlockIndexByTxPubKeyRequest::new(); - req.set_tx_public_key(tx_out_public_key_proto); + let req = api::GetBlockIndexByTxPubKeyRequest { + tx_public_key: Some(tx_out_public_key_proto), + }; let resp = state .mobilecoind_api_client @@ -706,8 +730,10 @@ fn get_proof_of_membership( .collect::, _>>()?; // Make gRPC request. - let mut get_membership_proofs_request = api::GetMembershipProofsRequest::new(); - get_membership_proofs_request.set_outputs(RepeatedField::from_vec(outputs)); + let get_membership_proofs_request = api::GetMembershipProofsRequest { + outputs, + ..Default::default() + }; let get_membership_proofs_response = state .mobilecoind_api_client @@ -717,11 +743,21 @@ fn get_proof_of_membership( // Return JSON response let (outputs, membership_proofs): (Vec, Vec) = get_membership_proofs_response - .get_output_list() + .output_list .iter() .map(|tx_out_with_proof| { - let tx_out = JsonTxOut::from(tx_out_with_proof.get_output()); - let proof = JsonTxOutMembershipProof::from(tx_out_with_proof.get_proof()); + let tx_out = JsonTxOut::from( + tx_out_with_proof + .output + .as_ref() + .unwrap_or(&Default::default()), + ); + let proof = JsonTxOutMembershipProof::from( + tx_out_with_proof + .proof + .as_ref() + .unwrap_or(&Default::default()), + ); (tx_out, proof) }) .unzip(); @@ -748,9 +784,10 @@ fn get_mixins( .collect::, _>>()?; // Make gRPC request - let mut get_mixins_request = api::GetMixinsRequest::new(); - get_mixins_request.set_num_mixins(num_mixins); - get_mixins_request.set_excluded(RepeatedField::from_vec(excluded)); + let get_mixins_request = api::GetMixinsRequest { + num_mixins, + excluded, + }; let get_mixins_response = state .mobilecoind_api_client @@ -759,11 +796,21 @@ fn get_mixins( let (mixins, membership_proofs): (Vec, Vec) = get_mixins_response - .get_mixins() + .mixins .iter() .map(|tx_out_with_proof| { - let tx_out = JsonTxOut::from(tx_out_with_proof.get_output()); - let proof = JsonTxOutMembershipProof::from(tx_out_with_proof.get_proof()); + let tx_out = JsonTxOut::from( + tx_out_with_proof + .output + .as_ref() + .unwrap_or(&Default::default()), + ); + let proof = JsonTxOutMembershipProof::from( + tx_out_with_proof + .proof + .as_ref() + .unwrap_or(&Default::default()), + ); (tx_out, proof) }) .unzip(); diff --git a/mobilecoind-json/src/data_types.rs b/mobilecoind-json/src/data_types.rs index bcd98287c5..6ec3704a80 100644 --- a/mobilecoind-json/src/data_types.rs +++ b/mobilecoind-json/src/data_types.rs @@ -4,12 +4,11 @@ use mc_api::external::{ CompressedRistretto, EncryptedFogHint, EncryptedMemo, InputRules, KeyImage, MaskedAmount, - PublicAddress, RingMLSAG, SignatureRctBulletproofs, Tx, TxIn, TxOutMembershipElement, + PublicAddress, RingMlsag, SignatureRctBulletproofs, Tx, TxIn, TxOutMembershipElement, TxOutMembershipHash, TxOutMembershipProof, TxPrefix, }; use mc_mobilecoind_api as api; use mc_util_serial::JsonU64; -use protobuf::RepeatedField; use serde_derive::{Deserialize, Serialize}; #[derive(Deserialize, Default, Debug)] @@ -66,10 +65,24 @@ pub struct JsonAccountKeyResponse { impl From<&api::GetAccountKeyResponse> for JsonAccountKeyResponse { fn from(src: &api::GetAccountKeyResponse) -> Self { + let default_account_key = Default::default(); + let account_key = src.account_key.as_ref().unwrap_or(&default_account_key); Self { - view_private_key: hex::encode(src.get_account_key().get_view_private_key().get_data()), + view_private_key: hex::encode( + account_key + .view_private_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), spend_private_key: hex::encode( - src.get_account_key().get_spend_private_key().get_data(), + account_key + .spend_private_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), ), } } @@ -105,7 +118,7 @@ pub struct JsonMonitorListResponse { impl From<&api::GetMonitorListResponse> for JsonMonitorListResponse { fn from(src: &api::GetMonitorListResponse) -> Self { Self { - monitor_ids: src.get_monitor_id_list().iter().map(hex::encode).collect(), + monitor_ids: src.monitor_id_list.iter().map(hex::encode).collect(), } } } @@ -120,13 +133,14 @@ pub struct JsonMonitorStatusResponse { impl From<&api::GetMonitorStatusResponse> for JsonMonitorStatusResponse { fn from(src: &api::GetMonitorStatusResponse) -> Self { - let status = src.get_status(); + let default_status = Default::default(); + let status = src.status.as_ref().unwrap_or(&default_status); Self { - first_subaddress: status.get_first_subaddress(), - num_subaddresses: status.get_num_subaddresses(), - first_block: status.get_first_block(), - next_block: status.get_next_block(), + first_subaddress: status.first_subaddress, + num_subaddresses: status.num_subaddresses, + first_block: status.first_block, + next_block: status.next_block, } } } @@ -158,13 +172,19 @@ pub struct JsonUnspentTxOut { impl From<&api::UnspentTxOut> for JsonUnspentTxOut { fn from(src: &api::UnspentTxOut) -> Self { Self { - tx_out: src.get_tx_out().into(), - subaddress_index: src.get_subaddress_index(), - key_image: hex::encode(src.get_key_image().get_data()), + tx_out: src.tx_out.as_ref().unwrap_or(&Default::default()).into(), + subaddress_index: src.subaddress_index, + key_image: hex::encode( + src.key_image + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), value: JsonU64(src.value), - attempted_spend_height: src.get_attempted_spend_height(), - attempted_spend_tombstone: src.get_attempted_spend_tombstone(), - monitor_id: hex::encode(src.get_monitor_id()), + attempted_spend_height: src.attempted_spend_height, + attempted_spend_tombstone: src.attempted_spend_tombstone, + monitor_id: hex::encode(src.monitor_id.as_slice()), } } } @@ -174,29 +194,24 @@ impl TryFrom<&JsonUnspentTxOut> for api::UnspentTxOut { type Error = String; fn try_from(src: &JsonUnspentTxOut) -> Result { - let mut key_image = KeyImage::new(); - key_image.set_data( - hex::decode(&src.key_image) - .map_err(|err| format!("Failed to decode key image hex: {err}"))?, - ); - // Reconstruct the public address as a protobuf - let mut utxo = api::UnspentTxOut::new(); - utxo.set_tx_out( - mc_api::external::TxOut::try_from(&src.tx_out) - .map_err(|err| format!("Failed to get TxOut: {err}"))?, - ); - utxo.set_subaddress_index(src.subaddress_index); - utxo.set_key_image(key_image); - utxo.set_value(src.value.into()); - utxo.set_attempted_spend_height(src.attempted_spend_height); - utxo.set_attempted_spend_tombstone(src.attempted_spend_tombstone); - utxo.set_monitor_id( - hex::decode(&src.monitor_id) + Ok(api::UnspentTxOut { + tx_out: Some( + mc_api::external::TxOut::try_from(&src.tx_out) + .map_err(|err| format!("Failed to get TxOut: {err}"))?, + ), + subaddress_index: src.subaddress_index, + key_image: Some(KeyImage { + data: hex::decode(&src.key_image) + .map_err(|err| format!("Failed to decode key image hex: {err}"))?, + }), + value: src.value.into(), + attempted_spend_height: src.attempted_spend_height, + attempted_spend_tombstone: src.attempted_spend_tombstone, + monitor_id: hex::decode(&src.monitor_id) .map_err(|err| format!("Failed to decode monitor id hex: {err}"))?, - ); - - Ok(utxo) + ..Default::default() + }) } } @@ -208,11 +223,7 @@ pub struct JsonUtxosResponse { impl From<&api::GetUnspentTxOutListResponse> for JsonUtxosResponse { fn from(src: &api::GetUnspentTxOutListResponse) -> Self { Self { - output_list: src - .get_output_list() - .iter() - .map(JsonUnspentTxOut::from) - .collect(), + output_list: src.output_list.iter().map(JsonUnspentTxOut::from).collect(), } } } @@ -232,7 +243,7 @@ pub struct JsonCreateRequestCodeResponse { impl From<&api::CreateRequestCodeResponse> for JsonCreateRequestCodeResponse { fn from(src: &api::CreateRequestCodeResponse) -> Self { Self { - b58_request_code: String::from(src.get_b58_code()), + b58_request_code: src.b58_code.clone(), } } } @@ -258,11 +269,23 @@ pub struct JsonPublicAddress { impl From<&PublicAddress> for JsonPublicAddress { fn from(src: &PublicAddress) -> Self { Self { - view_public_key: hex::encode(src.get_view_public_key().get_data()), - spend_public_key: hex::encode(src.get_spend_public_key().get_data()), - fog_report_url: String::from(src.get_fog_report_url()), - fog_report_id: String::from(src.get_fog_report_id()), - fog_authority_sig: hex::encode(src.get_fog_authority_sig()), + view_public_key: hex::encode( + src.view_public_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + spend_public_key: hex::encode( + src.spend_public_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + fog_report_url: src.fog_report_url.clone(), + fog_report_id: src.fog_report_id.clone(), + fog_authority_sig: hex::encode(src.fog_authority_sig.as_slice()), } } } @@ -290,14 +313,29 @@ pub struct JsonPublicAddressResponse { impl From<&api::GetPublicAddressResponse> for JsonPublicAddressResponse { fn from(src: &api::GetPublicAddressResponse) -> Self { - let public_address = src.get_public_address(); + let default_address = Default::default(); + let public_address = src.public_address.as_ref().unwrap_or(&default_address); Self { - view_public_key: hex::encode(public_address.get_view_public_key().get_data()), - spend_public_key: hex::encode(public_address.get_spend_public_key().get_data()), - fog_report_url: String::from(public_address.get_fog_report_url()), - fog_report_id: String::from(public_address.get_fog_report_id()), - fog_authority_sig: hex::encode(public_address.get_fog_authority_sig()), - b58_address_code: src.get_b58_code().to_string(), + view_public_key: hex::encode( + public_address + .view_public_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + spend_public_key: hex::encode( + public_address + .spend_public_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + fog_report_url: public_address.fog_report_url.clone(), + fog_report_id: public_address.fog_report_id.clone(), + fog_authority_sig: hex::encode(public_address.fog_authority_sig.as_slice()), + b58_address_code: src.b58_code.to_string(), } } } @@ -308,29 +346,24 @@ impl TryFrom<&JsonPublicAddress> for PublicAddress { fn try_from(src: &JsonPublicAddress) -> Result { // Decode the keys - let mut view_public_key = CompressedRistretto::new(); - view_public_key.set_data( - hex::decode(&src.view_public_key) + let view_public_key = CompressedRistretto { + data: hex::decode(&src.view_public_key) .map_err(|err| format!("Failed to decode view key hex: {err}"))?, - ); - let mut spend_public_key = CompressedRistretto::new(); - spend_public_key.set_data( - hex::decode(&src.spend_public_key) + }; + let spend_public_key = CompressedRistretto { + data: hex::decode(&src.spend_public_key) .map_err(|err| format!("Failed to decode spend key hex: {err}"))?, - ); + }; // Reconstruct the public address as a protobuf - let mut public_address = PublicAddress::new(); - public_address.set_view_public_key(view_public_key); - public_address.set_spend_public_key(spend_public_key); - public_address.set_fog_report_url(src.fog_report_url.clone()); - public_address.set_fog_report_id(src.fog_report_id.clone()); - public_address.set_fog_authority_sig( - hex::decode(&src.fog_authority_sig) + Ok(PublicAddress { + view_public_key: Some(view_public_key), + spend_public_key: Some(spend_public_key), + fog_report_url: src.fog_report_url.clone(), + fog_report_id: src.fog_report_id.clone(), + fog_authority_sig: hex::decode(&src.fog_authority_sig) .map_err(|err| format!("Failed to decode fog authority sig hex: {err}"))?, - ); - - Ok(public_address) + }) } } @@ -344,9 +377,9 @@ pub struct JsonParseRequestCodeResponse { impl From<&api::ParseRequestCodeResponse> for JsonParseRequestCodeResponse { fn from(src: &api::ParseRequestCodeResponse) -> Self { Self { - receiver: JsonPublicAddress::from(src.get_receiver()), - value: JsonU64(src.get_value()), - memo: src.get_memo().to_string(), + receiver: JsonPublicAddress::from(src.receiver.as_ref().unwrap_or(&Default::default())), + value: JsonU64(src.value), + memo: src.memo.to_string(), } } } @@ -364,7 +397,7 @@ pub struct JsonCreateAddressCodeResponse { impl From<&api::CreateAddressCodeResponse> for JsonCreateAddressCodeResponse { fn from(src: &api::CreateAddressCodeResponse) -> Self { Self { - b58_code: String::from(src.get_b58_code()), + b58_code: src.b58_code.clone(), } } } @@ -377,7 +410,7 @@ pub struct JsonParseAddressCodeResponse { impl From<&api::ParseAddressCodeResponse> for JsonParseAddressCodeResponse { fn from(src: &api::ParseAddressCodeResponse) -> Self { Self { - receiver: JsonPublicAddress::from(src.get_receiver()), + receiver: JsonPublicAddress::from(src.receiver.as_ref().unwrap_or(&Default::default())), } } } @@ -392,11 +425,11 @@ impl From<&api::SenderTxReceipt> for JsonSenderTxReceipt { fn from(src: &api::SenderTxReceipt) -> Self { Self { key_images: src - .get_key_image_list() + .key_image_list .iter() - .map(|key_image| hex::encode(key_image.get_data())) + .map(|key_image| hex::encode(key_image.data.as_slice())) .collect(), - tombstone: src.get_tombstone(), + tombstone: src.tombstone, } } } @@ -413,11 +446,19 @@ pub struct JsonReceiverTxReceipt { impl From<&api::ReceiverTxReceipt> for JsonReceiverTxReceipt { fn from(src: &api::ReceiverTxReceipt) -> Self { Self { - recipient: JsonPublicAddress::from(src.get_recipient()), - tx_public_key: hex::encode(src.get_tx_public_key().get_data()), - tx_out_hash: hex::encode(src.get_tx_out_hash()), - tombstone: src.get_tombstone(), - confirmation_number: hex::encode(src.get_confirmation_number()), + recipient: JsonPublicAddress::from( + src.recipient.as_ref().unwrap_or(&Default::default()), + ), + tx_public_key: hex::encode( + src.tx_public_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + tx_out_hash: hex::encode(src.tx_out_hash.as_slice()), + tombstone: src.tombstone, + confirmation_number: hex::encode(src.confirmation_number.as_slice()), } } } @@ -438,9 +479,13 @@ pub struct JsonSendPaymentResponse { impl From<&api::SendPaymentResponse> for JsonSendPaymentResponse { fn from(src: &api::SendPaymentResponse) -> Self { Self { - sender_tx_receipt: JsonSenderTxReceipt::from(src.get_sender_tx_receipt()), + sender_tx_receipt: JsonSenderTxReceipt::from( + src.sender_tx_receipt + .as_ref() + .unwrap_or(&Default::default()), + ), receiver_tx_receipt_list: src - .get_receiver_tx_receipt_list() + .receiver_tx_receipt_list .iter() .map(JsonReceiverTxReceipt::from) .collect(), @@ -465,8 +510,8 @@ pub struct JsonOutlay { impl From<&api::Outlay> for JsonOutlay { fn from(src: &api::Outlay) -> Self { Self { - value: JsonU64(src.get_value()), - receiver: src.get_receiver().into(), + value: JsonU64(src.value), + receiver: src.receiver.as_ref().unwrap_or(&Default::default()).into(), } } } @@ -475,14 +520,14 @@ impl TryFrom<&JsonOutlay> for api::Outlay { type Error = String; fn try_from(src: &JsonOutlay) -> Result { - let mut outlay = api::Outlay::new(); - outlay.set_value(src.value.into()); - outlay.set_receiver( - PublicAddress::try_from(&src.receiver) - .map_err(|err| format!("Could not convert receiver: {err}"))?, - ); - - Ok(outlay) + Ok(api::Outlay { + value: src.value.into(), + receiver: Some( + PublicAddress::try_from(&src.receiver) + .map_err(|err| format!("Could not convert receiver: {err}"))?, + ), + ..Default::default() + }) } } @@ -496,9 +541,9 @@ pub struct JsonOutlayV2 { impl From<&api::OutlayV2> for JsonOutlayV2 { fn from(src: &api::OutlayV2) -> Self { Self { - value: JsonU64(src.get_value()), - token_id: JsonU64(src.get_token_id()), - receiver: src.get_receiver().into(), + value: JsonU64(src.value), + token_id: JsonU64(src.token_id), + receiver: src.receiver.as_ref().unwrap_or(&Default::default()).into(), } } } @@ -507,15 +552,15 @@ impl TryFrom<&JsonOutlayV2> for api::OutlayV2 { type Error = String; fn try_from(src: &JsonOutlayV2) -> Result { - let mut outlay = api::OutlayV2::new(); - outlay.set_value(src.value.into()); - outlay.set_token_id(src.token_id.into()); - outlay.set_receiver( - PublicAddress::try_from(&src.receiver) - .map_err(|err| format!("Could not convert receiver: {err}"))?, - ); - - Ok(outlay) + Ok(api::OutlayV2 { + value: src.value.into(), + token_id: src.token_id.into(), + receiver: Some( + PublicAddress::try_from(&src.receiver) + .map_err(|err| format!("Could not convert receiver: {err}"))?, + ), + ..Default::default() + }) } } @@ -527,19 +572,31 @@ pub struct JsonMaskedAmount { pub version: Option, } -impl From<&mc_api::external::TxOut_oneof_masked_amount> for JsonMaskedAmount { - fn from(src: &mc_api::external::TxOut_oneof_masked_amount) -> Self { +impl From<&mc_api::external::tx_out::MaskedAmount> for JsonMaskedAmount { + fn from(src: &mc_api::external::tx_out::MaskedAmount) -> Self { match src { - mc_api::external::TxOut_oneof_masked_amount::masked_amount_v1(src) => Self { - commitment: hex::encode(src.get_commitment().get_data()), - masked_value: JsonU64(src.get_masked_value()), - masked_token_id: hex::encode(src.get_masked_token_id()), + mc_api::external::tx_out::MaskedAmount::MaskedAmountV1(src) => Self { + commitment: hex::encode( + src.commitment + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + masked_value: JsonU64(src.masked_value), + masked_token_id: hex::encode(src.masked_token_id.as_slice()), version: Some(1), }, - mc_api::external::TxOut_oneof_masked_amount::masked_amount_v2(src) => Self { - commitment: hex::encode(src.get_commitment().get_data()), - masked_value: JsonU64(src.get_masked_value()), - masked_token_id: hex::encode(src.get_masked_token_id()), + mc_api::external::tx_out::MaskedAmount::MaskedAmountV2(src) => Self { + commitment: hex::encode( + src.commitment + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + masked_value: JsonU64(src.masked_value), + masked_token_id: hex::encode(src.masked_token_id.as_slice()), version: Some(2), }, } @@ -547,32 +604,28 @@ impl From<&mc_api::external::TxOut_oneof_masked_amount> for JsonMaskedAmount { } // Helper conversion between json and protobuf -impl TryFrom<&JsonMaskedAmount> for mc_api::external::TxOut_oneof_masked_amount { +impl TryFrom<&JsonMaskedAmount> for mc_api::external::tx_out::MaskedAmount { type Error = String; - fn try_from( - src: &JsonMaskedAmount, - ) -> Result { - let mut commitment = CompressedRistretto::new(); - commitment.set_data( - hex::decode(&src.commitment) + fn try_from(src: &JsonMaskedAmount) -> Result { + let commitment = CompressedRistretto { + data: hex::decode(&src.commitment) .map_err(|err| format!("Failed to decode commitment hex: {err}"))?, - ); - let mut masked_amount = MaskedAmount::new(); - masked_amount.set_commitment(commitment); - masked_amount.set_masked_value(src.masked_value.into()); - masked_amount.set_masked_token_id( - hex::decode(&src.masked_token_id) + }; + let masked_amount = MaskedAmount { + commitment: Some(commitment), + masked_value: src.masked_value.into(), + masked_token_id: hex::decode(&src.masked_token_id) .map_err(|err| format!("Failed to decode masked token id hex: {err}"))?, - ); + }; match src.version { - None | Some(1) => { - Ok(mc_api::external::TxOut_oneof_masked_amount::masked_amount_v1(masked_amount)) - } - Some(2) => { - Ok(mc_api::external::TxOut_oneof_masked_amount::masked_amount_v2(masked_amount)) - } + None | Some(1) => Ok(mc_api::external::tx_out::MaskedAmount::MaskedAmountV1( + masked_amount, + )), + Some(2) => Ok(mc_api::external::tx_out::MaskedAmount::MaskedAmountV2( + masked_amount, + )), Some(other) => Err(format!("Unknown masked amount version: {other}")), } } @@ -591,10 +644,34 @@ impl From<&mc_api::external::TxOut> for JsonTxOut { fn from(src: &mc_api::external::TxOut) -> Self { Self { masked_amount: src.masked_amount.as_ref().map(Into::into), - target_key: hex::encode(src.get_target_key().get_data()), - public_key: hex::encode(src.get_public_key().get_data()), - e_fog_hint: hex::encode(src.get_e_fog_hint().get_data()), - e_memo: hex::encode(src.get_e_memo().get_data()), + target_key: hex::encode( + src.target_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + public_key: hex::encode( + src.public_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + e_fog_hint: hex::encode( + src.e_fog_hint + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + e_memo: hex::encode( + src.e_memo + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), } } } @@ -604,41 +681,34 @@ impl TryFrom<&JsonTxOut> for mc_api::external::TxOut { type Error = String; fn try_from(src: &JsonTxOut) -> Result { - let mut target_key = CompressedRistretto::new(); - target_key.set_data( - hex::decode(&src.target_key) + let target_key = CompressedRistretto { + data: hex::decode(&src.target_key) .map_err(|err| format!("Failed to decode target key hex: {err}"))?, - ); - let mut public_key = CompressedRistretto::new(); - public_key.set_data( - hex::decode(&src.public_key) + }; + let public_key = CompressedRistretto { + data: hex::decode(&src.public_key) .map_err(|err| format!("Failed to decode public key hex: {err}"))?, - ); - let mut e_fog_hint = EncryptedFogHint::new(); - e_fog_hint.set_data( - hex::decode(&src.e_fog_hint) + }; + let e_fog_hint = EncryptedFogHint { + data: hex::decode(&src.e_fog_hint) .map_err(|err| format!("Failed to decode e_fog_hint hex: {err}"))?, - ); - let mut e_memo = EncryptedMemo::new(); - e_memo.set_data( - hex::decode(&src.e_memo) + }; + let e_memo = EncryptedMemo { + data: hex::decode(&src.e_memo) .map_err(|err| format!("Failed to decode e_memo hex: {err}"))?, - ); - - let mut txo = mc_api::external::TxOut::new(); - txo.masked_amount = src - .masked_amount - .as_ref() - .map(TryInto::try_into) - .transpose()?; - txo.set_target_key(target_key); - txo.set_public_key(public_key); - txo.set_e_fog_hint(e_fog_hint); - if !e_memo.get_data().is_empty() { - txo.set_e_memo(e_memo); - } + }; - Ok(txo) + Ok(mc_api::external::TxOut { + masked_amount: src + .masked_amount + .as_ref() + .map(TryInto::try_into) + .transpose()?, + target_key: Some(target_key), + public_key: Some(public_key), + e_fog_hint: Some(e_fog_hint), + e_memo: Some(e_memo), + }) } } @@ -658,10 +728,16 @@ impl From<&TxOutMembershipElement> for JsonTxOutMembershipElement { fn from(src: &TxOutMembershipElement) -> Self { Self { range: JsonRange { - from: JsonU64(src.get_range().get_from()), - to: JsonU64(src.get_range().get_to()), + from: JsonU64(src.range.as_ref().unwrap_or(&Default::default()).from), + to: JsonU64(src.range.as_ref().unwrap_or(&Default::default()).to), }, - hash: hex::encode(src.get_hash().get_data()), + hash: hex::encode( + src.hash + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), } } } @@ -676,10 +752,10 @@ pub struct JsonTxOutMembershipProof { impl From<&TxOutMembershipProof> for JsonTxOutMembershipProof { fn from(src: &TxOutMembershipProof) -> Self { Self { - index: JsonU64(src.get_index()), - highest_index: JsonU64(src.get_highest_index()), + index: JsonU64(src.index), + highest_index: JsonU64(src.highest_index), elements: src - .get_elements() + .elements .iter() .map(JsonTxOutMembershipElement::from) .collect(), @@ -693,28 +769,28 @@ impl TryFrom<&JsonTxOutMembershipProof> for TxOutMembershipProof { fn try_from(src: &JsonTxOutMembershipProof) -> Result { let mut elements: Vec = Vec::new(); for element in &src.elements { - let mut range = mc_api::external::Range::new(); - range.set_from(element.range.from.into()); - range.set_to(element.range.to.into()); + let range = mc_api::external::Range { + from: element.range.from.into(), + to: element.range.to.into(), + }; - let mut hash = TxOutMembershipHash::new(); - hash.set_data( - hex::decode(&element.hash) + let hash = TxOutMembershipHash { + data: hex::decode(&element.hash) .map_err(|err| format!("Could not decode elem hash: {err}"))?, - ); + }; - let mut elem = TxOutMembershipElement::new(); - elem.set_range(range); - elem.set_hash(hash); + let elem = TxOutMembershipElement { + range: Some(range), + hash: Some(hash), + }; elements.push(elem); } - let mut proof = TxOutMembershipProof::new(); - proof.set_index(src.index.into()); - proof.set_highest_index(src.highest_index.into()); - proof.set_elements(RepeatedField::from_vec(elements)); - - Ok(proof) + Ok(TxOutMembershipProof { + index: src.index.into(), + highest_index: src.highest_index.into(), + elements, + }) } } @@ -760,11 +836,7 @@ pub struct JsonInputRules { impl From<&InputRules> for JsonInputRules { fn from(src: &InputRules) -> Self { Self { - required_outputs: src - .get_required_outputs() - .iter() - .map(JsonTxOut::from) - .collect(), + required_outputs: src.required_outputs.iter().map(JsonTxOut::from).collect(), max_tombstone_block: src.max_tombstone_block, } } @@ -774,18 +846,18 @@ impl TryFrom<&JsonInputRules> for InputRules { type Error = String; fn try_from(src: &JsonInputRules) -> Result { - let mut input_rules = InputRules::new(); - input_rules.set_required_outputs( - src.required_outputs + Ok(InputRules { + required_outputs: src + .required_outputs .iter() .map(|out| { mc_api::external::TxOut::try_from(out) .map_err(|err| format!("Could not get TxOut: {err}")) }) .collect::>()?, - ); - input_rules.max_tombstone_block = src.max_tombstone_block; - Ok(input_rules) + max_tombstone_block: src.max_tombstone_block, + ..Default::default() + }) } } @@ -799,9 +871,9 @@ pub struct JsonTxIn { impl From<&TxIn> for JsonTxIn { fn from(src: &TxIn) -> Self { Self { - ring: src.get_ring().iter().map(JsonTxOut::from).collect(), + ring: src.ring.iter().map(JsonTxOut::from).collect(), proofs: src - .get_proofs() + .proofs .iter() .map(JsonTxOutMembershipProof::from) .collect(), @@ -834,14 +906,11 @@ impl TryFrom<&JsonTxIn> for TxIn { .map(InputRules::try_from) .transpose()?; - let mut txin = TxIn::new(); - txin.set_ring(RepeatedField::from_vec(outputs)); - txin.set_proofs(RepeatedField::from_vec(proofs)); - if let Some(rules) = input_rules { - txin.set_input_rules(rules); - } - - Ok(txin) + Ok(TxIn { + ring: outputs, + proofs, + input_rules, + }) } } @@ -856,10 +925,10 @@ pub struct JsonTxPrefix { impl From<&TxPrefix> for JsonTxPrefix { fn from(src: &TxPrefix) -> Self { Self { - inputs: src.get_inputs().iter().map(JsonTxIn::from).collect(), - outputs: src.get_outputs().iter().map(JsonTxOut::from).collect(), - fee: JsonU64(src.get_fee()), - tombstone_block: JsonU64(src.get_tombstone_block()), + inputs: src.inputs.iter().map(JsonTxIn::from).collect(), + outputs: src.outputs.iter().map(JsonTxOut::from).collect(), + fee: JsonU64(src.fee), + tombstone_block: JsonU64(src.tombstone_block), } } } @@ -882,13 +951,13 @@ impl TryFrom<&JsonTxPrefix> for TxPrefix { outputs.push(p_output); } - let mut prefix = TxPrefix::new(); - prefix.set_inputs(RepeatedField::from_vec(inputs)); - prefix.set_outputs(RepeatedField::from_vec(outputs)); - prefix.set_fee(src.fee.into()); - prefix.set_tombstone_block(src.tombstone_block.into()); - - Ok(prefix) + Ok(TxPrefix { + inputs, + outputs, + fee: src.fee.into(), + tombstone_block: src.tombstone_block.into(), + ..Default::default() + }) } } @@ -899,16 +968,28 @@ pub struct JsonRingMLSAG { pub key_image: String, } -impl From<&RingMLSAG> for JsonRingMLSAG { - fn from(src: &RingMLSAG) -> Self { +impl From<&RingMlsag> for JsonRingMLSAG { + fn from(src: &RingMlsag) -> Self { Self { - c_zero: hex::encode(src.get_c_zero().get_data()), + c_zero: hex::encode( + src.c_zero + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), responses: src - .get_responses() + .responses .iter() - .map(|x| hex::encode(x.get_data())) + .map(|x| hex::encode(x.data.as_slice())) .collect(), - key_image: hex::encode(src.get_key_image().get_data()), + key_image: hex::encode( + src.key_image + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), } } } @@ -927,17 +1008,17 @@ impl From<&SignatureRctBulletproofs> for JsonSignatureRctBulletproofs { fn from(src: &SignatureRctBulletproofs) -> Self { Self { ring_signatures: src - .get_ring_signatures() + .ring_signatures .iter() .map(JsonRingMLSAG::from) .collect(), pseudo_output_commitments: src - .get_pseudo_output_commitments() + .pseudo_output_commitments .iter() - .map(|x| hex::encode(x.get_data())) + .map(|x| hex::encode(x.data.as_slice())) .collect(), - range_proof_bytes: hex::encode(src.get_range_proof_bytes()), - range_proofs: src.get_range_proofs().iter().map(hex::encode).collect(), + range_proof_bytes: hex::encode(src.range_proof_bytes.as_slice()), + range_proofs: src.range_proofs.iter().map(hex::encode).collect(), pseudo_output_token_ids: src.pseudo_output_token_ids.iter().map(Into::into).collect(), output_token_ids: src.output_token_ids.iter().map(Into::into).collect(), } @@ -948,72 +1029,65 @@ impl TryFrom<&JsonSignatureRctBulletproofs> for SignatureRctBulletproofs { type Error = String; fn try_from(src: &JsonSignatureRctBulletproofs) -> Result { - let mut ring_sigs: Vec = Vec::new(); + let mut ring_sigs: Vec = Vec::new(); for sig in &src.ring_signatures { - let mut c_zero = mc_api::external::CurveScalar::new(); - c_zero.set_data( - hex::decode(&sig.c_zero) + let c_zero = mc_api::external::CurveScalar { + data: hex::decode(&sig.c_zero) .map_err(|err| format!("Could not decode from hex: {err}"))?, - ); + }; let mut responses: Vec = Vec::new(); for resp in &sig.responses { - let mut response = mc_api::external::CurveScalar::new(); - response.set_data( - hex::decode(resp).map_err(|err| format!("Could not decode from hex: {err}"))?, - ); + let response = mc_api::external::CurveScalar { + data: hex::decode(resp) + .map_err(|err| format!("Could not decode from hex: {err}"))?, + }; responses.push(response); } - let mut key_image = KeyImage::new(); - key_image.set_data( - hex::decode(&sig.key_image) + let key_image = KeyImage { + data: hex::decode(&sig.key_image) .map_err(|err| format!("Could not decode from hex: {err}"))?, - ); - - let mut ring_sig = RingMLSAG::new(); - ring_sig.set_c_zero(c_zero); - ring_sig.set_responses(RepeatedField::from_vec(responses)); - ring_sig.set_key_image(key_image); + }; + let ring_sig = RingMlsag { + c_zero: Some(c_zero), + responses, + key_image: Some(key_image), + }; ring_sigs.push(ring_sig); } let mut commitments: Vec = Vec::new(); for comm in &src.pseudo_output_commitments { - let mut compressed = CompressedRistretto::new(); - compressed.set_data( - hex::decode(comm).map_err(|err| format!("Could not decode from hex: {err}"))?, - ); + let compressed = CompressedRistretto { + data: hex::decode(comm) + .map_err(|err| format!("Could not decode from hex: {err}"))?, + }; commitments.push(compressed); } - let mut signature = SignatureRctBulletproofs::new(); - signature.set_ring_signatures(RepeatedField::from_vec(ring_sigs)); - signature.set_pseudo_output_commitments(RepeatedField::from_vec(commitments)); - let range_proof_bytes = hex::decode(&src.range_proof_bytes).map_err(|err| { - format!( - "Could not decode top-level range proof from hex '{}': {}", - &src.range_proof_bytes, err - ) - })?; - signature.set_range_proof_bytes(range_proof_bytes); - let range_proofs = src - .range_proofs - .iter() - .map(|hex_str| { - hex::decode(hex_str).map_err(|err| { - format!("Could not decode range proof from hex '{hex_str}': {err}") + let signature = SignatureRctBulletproofs { + ring_signatures: ring_sigs, + pseudo_output_commitments: commitments, + range_proof_bytes: hex::decode(&src.range_proof_bytes).map_err(|err| { + format!( + "Could not decode top-level range proof from hex '{}': {}", + &src.range_proof_bytes, err + ) + })?, + range_proofs: src + .range_proofs + .iter() + .map(|hex_str| { + hex::decode(hex_str).map_err(|err| { + format!("Could not decode range proof from hex '{hex_str}': {err}") + }) }) - }) - .collect::>()?; - signature.set_range_proofs(range_proofs); - - signature.set_pseudo_output_token_ids( - src.pseudo_output_token_ids.iter().map(Into::into).collect(), - ); - signature.set_output_token_ids(src.output_token_ids.iter().map(Into::into).collect()); - + .collect::>()?, + pseudo_output_token_ids: src.pseudo_output_token_ids.iter().map(Into::into).collect(), + output_token_ids: src.output_token_ids.iter().map(Into::into).collect(), + }; Ok(signature) } } @@ -1027,8 +1101,8 @@ pub struct JsonTx { impl From<&Tx> for JsonTx { fn from(src: &Tx) -> Self { Self { - prefix: src.get_prefix().into(), - signature: src.get_signature().into(), + prefix: src.prefix.as_ref().unwrap_or(&Default::default()).into(), + signature: src.signature.as_ref().unwrap_or(&Default::default()).into(), } } } @@ -1037,17 +1111,17 @@ impl TryFrom<&JsonTx> for Tx { type Error = String; fn try_from(src: &JsonTx) -> Result { - let mut tx = Tx::new(); - - tx.set_prefix( - TxPrefix::try_from(&src.prefix) - .map_err(|err| format!("Could not convert TxPrefix: {err}"))?, - ); - tx.set_signature( - SignatureRctBulletproofs::try_from(&src.signature) - .map_err(|err| format!("Could not convert signature: {err}"))?, - ); - + let tx = Tx { + prefix: Some( + TxPrefix::try_from(&src.prefix) + .map_err(|err| format!("Could not convert TxPrefix: {err}"))?, + ), + signature: Some( + SignatureRctBulletproofs::try_from(&src.signature) + .map_err(|err| format!("Could not convert signature: {err}"))?, + ), + ..Default::default() + }; Ok(tx) } } @@ -1066,25 +1140,17 @@ pub struct JsonTxProposal { impl From<&api::TxProposal> for JsonTxProposal { fn from(src: &api::TxProposal) -> Self { let outlay_map: Vec<(usize, usize)> = src - .get_outlay_index_to_tx_out_index() + .outlay_index_to_tx_out_index .iter() .map(|(key, val)| (*key as usize, *val as usize)) .collect(); Self { - input_list: src - .get_input_list() - .iter() - .map(JsonUnspentTxOut::from) - .collect(), - outlay_list: src - .get_outlay_list() - .iter() - .map(JsonOutlayV2::from) - .collect(), - tx: src.get_tx().into(), - fee: src.get_fee(), + input_list: src.input_list.iter().map(JsonUnspentTxOut::from).collect(), + outlay_list: src.outlay_list.iter().map(JsonOutlayV2::from).collect(), + tx: src.tx.as_ref().unwrap_or(&Default::default()).into(), + fee: src.fee, outlay_index_to_tx_out_index: outlay_map, - outlay_confirmation_numbers: src.get_outlay_confirmation_numbers().to_vec(), + outlay_confirmation_numbers: src.outlay_confirmation_numbers.to_vec(), } } } @@ -1109,23 +1175,19 @@ impl TryFrom<&JsonTxProposal> for api::TxProposal { } // Reconstruct the public address as a protobuf - let mut proposal = api::TxProposal::new(); - proposal.set_input_list(RepeatedField::from_vec(inputs)); - proposal.set_outlay_list(RepeatedField::from_vec(outlays)); - proposal - .set_tx(Tx::try_from(&src.tx).map_err(|err| format!("Could not convert tx: {err}"))?); - proposal.set_fee(src.fee); - proposal.set_outlay_index_to_tx_out_index( - src.outlay_index_to_tx_out_index + Ok(api::TxProposal { + input_list: inputs, + outlay_list: outlays, + tx: Some(Tx::try_from(&src.tx).map_err(|err| format!("Could not convert tx: {err}"))?), + fee: src.fee, + outlay_index_to_tx_out_index: src + .outlay_index_to_tx_out_index .iter() .map(|(key, val)| (*key as u64, *val as u64)) .collect(), - ); - proposal.set_outlay_confirmation_numbers(RepeatedField::from_vec( - src.outlay_confirmation_numbers.clone(), - )); - - Ok(proposal) + outlay_confirmation_numbers: src.outlay_confirmation_numbers.clone(), + ..Default::default() + }) } } @@ -1143,7 +1205,11 @@ pub struct JsonCreateTxProposalResponse { impl From<&api::GenerateTxResponse> for JsonCreateTxProposalResponse { fn from(src: &api::GenerateTxResponse) -> Self { Self { - tx_proposal: src.get_tx_proposal().into(), + tx_proposal: src + .tx_proposal + .as_ref() + .unwrap_or(&Default::default()) + .into(), } } } @@ -1162,9 +1228,13 @@ pub struct JsonSubmitTxResponse { impl From<&api::SubmitTxResponse> for JsonSubmitTxResponse { fn from(src: &api::SubmitTxResponse) -> Self { Self { - sender_tx_receipt: src.get_sender_tx_receipt().into(), + sender_tx_receipt: src + .sender_tx_receipt + .as_ref() + .unwrap_or(&Default::default()) + .into(), receiver_tx_receipt_list: src - .get_receiver_tx_receipt_list() + .receiver_tx_receipt_list .iter() .map(JsonReceiverTxReceipt::from) .collect(), @@ -1176,8 +1246,6 @@ impl TryFrom<&JsonSubmitTxResponse> for api::SubmitTxResponse { type Error = String; fn try_from(src: &JsonSubmitTxResponse) -> Result { - let mut sender_receipt = api::SenderTxReceipt::new(); - let key_images: Vec = src .sender_tx_receipt .key_images @@ -1188,41 +1256,37 @@ impl TryFrom<&JsonSubmitTxResponse> for api::SubmitTxResponse { }) }) .collect::, String>>()?; - - sender_receipt.set_key_image_list(RepeatedField::from_vec(key_images)); - sender_receipt.set_tombstone(src.sender_tx_receipt.tombstone); + let sender_receipt = api::SenderTxReceipt { + key_image_list: key_images, + tombstone: src.sender_tx_receipt.tombstone, + }; let mut receiver_receipts = Vec::new(); for r in src.receiver_tx_receipt_list.iter() { - let mut receiver_receipt = api::ReceiverTxReceipt::new(); - receiver_receipt.set_recipient( - PublicAddress::try_from(&r.recipient) - .map_err(|err| format!("Failed to convert recipient: {err}"))?, - ); - let mut pubkey = mc_api::external::CompressedRistretto::new(); - pubkey.set_data( - hex::decode(&r.tx_public_key) + let pubkey = mc_api::external::CompressedRistretto { + data: hex::decode(&r.tx_public_key) .map_err(|err| format!("Failed to decode hex for tx_public_key: {err}"))?, - ); - receiver_receipt.set_tx_public_key(pubkey); - receiver_receipt.set_tx_out_hash( - hex::decode(&r.tx_out_hash) + }; + let receiver_receipt = api::ReceiverTxReceipt { + recipient: Some( + PublicAddress::try_from(&r.recipient) + .map_err(|err| format!("Failed to convert recipient: {err}"))?, + ), + tx_public_key: Some(pubkey), + tx_out_hash: hex::decode(&r.tx_out_hash) .map_err(|err| format!("Failed to decode hex for tx_out_hash: {err}"))?, - ); - receiver_receipt.set_tombstone(r.tombstone); - receiver_receipt.set_confirmation_number( - hex::decode(&r.confirmation_number).map_err(|err| { + tombstone: r.tombstone, + confirmation_number: hex::decode(&r.confirmation_number).map_err(|err| { format!("Failed to decode hex for confirmation_number: {err}") })?, - ); + }; receiver_receipts.push(receiver_receipt); } - let mut resp = api::SubmitTxResponse::new(); - resp.set_sender_tx_receipt(sender_receipt); - resp.set_receiver_tx_receipt_list(RepeatedField::from_vec(receiver_receipts)); - - Ok(resp) + Ok(api::SubmitTxResponse { + sender_tx_receipt: Some(sender_receipt), + receiver_tx_receipt_list: receiver_receipts, + }) } } @@ -1233,7 +1297,7 @@ pub struct JsonStatusResponse { impl From<&api::GetTxStatusAsSenderResponse> for JsonStatusResponse { fn from(src: &api::GetTxStatusAsSenderResponse) -> Self { - let status_str = match src.get_status() { + let status_str = match src.status() { api::TxStatus::Unknown => "unknown", api::TxStatus::Verified => "verified", api::TxStatus::TombstoneBlockExceeded => "failed", @@ -1255,7 +1319,7 @@ impl From<&api::GetTxStatusAsSenderResponse> for JsonStatusResponse { impl From<&api::GetTxStatusAsReceiverResponse> for JsonStatusResponse { fn from(src: &api::GetTxStatusAsReceiverResponse) -> Self { - let status_str = match src.get_status() { + let status_str = match src.status() { api::TxStatus::Unknown => "unknown", api::TxStatus::Verified => "verified", api::TxStatus::TombstoneBlockExceeded => "failed", @@ -1301,12 +1365,28 @@ pub struct JsonBlockSignature { impl From<&api::ArchiveBlockSignatureData> for JsonBlockSignature { fn from(src: &api::ArchiveBlockSignatureData) -> Self { + let default_signature = Default::default(); + let signature = src.signature.as_ref().unwrap_or(&default_signature); Self { src_url: src.src_url.clone(), filename: src.filename.clone(), - signature: hex::encode(src.get_signature().get_signature().get_data()), - signer: hex::encode(src.get_signature().get_signer().get_data()), - signed_at: src.get_signature().signed_at, + signature: hex::encode( + signature + .signature + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + signer: hex::encode( + signature + .signer + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + signed_at: signature.signed_at, } } } @@ -1341,23 +1421,45 @@ pub struct JsonBlockDetailsResponse { impl From<&api::GetBlockResponse> for JsonBlockDetailsResponse { fn from(src: &api::GetBlockResponse) -> Self { - let block = src.get_block(); + let default_block = Default::default(); + let block = src.block.as_ref().unwrap_or(&default_block); Self { - block_id: hex::encode(block.get_id().get_data()), - version: block.get_version(), - parent_id: hex::encode(block.get_parent_id().get_data()), - index: JsonU64(block.get_index()), - cumulative_txo_count: JsonU64(block.get_cumulative_txo_count()), - contents_hash: hex::encode(block.get_contents_hash().get_data()), + block_id: hex::encode( + block + .id + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + version: block.version, + parent_id: hex::encode( + block + .parent_id + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + index: JsonU64(block.index), + cumulative_txo_count: JsonU64(block.cumulative_txo_count), + contents_hash: hex::encode( + block + .contents_hash + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), key_images: src - .get_key_images() + .key_images .iter() - .map(|k| hex::encode(k.get_data())) + .map(|k| hex::encode(k.data.as_slice())) .collect(), - txos: src.get_txos().iter().map(JsonTxOut::from).collect(), + txos: src.txos.iter().map(JsonTxOut::from).collect(), signatures: src - .get_signatures() + .signatures .iter() .map(JsonBlockSignature::from) .collect(), @@ -1377,17 +1479,29 @@ pub struct JsonProcessedTxOut { impl From<&api::ProcessedTxOut> for JsonProcessedTxOut { fn from(src: &api::ProcessedTxOut) -> Self { - let direction_str = match src.direction { + let direction_str = match src.direction() { api::ProcessedTxOutDirection::Invalid => "invalid", api::ProcessedTxOutDirection::Received => "received", api::ProcessedTxOutDirection::Spent => "spent", }; Self { - monitor_id: hex::encode(src.get_monitor_id()), + monitor_id: hex::encode(src.monitor_id.as_slice()), subaddress_index: src.subaddress_index, - public_key: hex::encode(src.get_public_key().get_data()), - key_image: hex::encode(src.get_key_image().get_data()), + public_key: hex::encode( + src.public_key + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), + key_image: hex::encode( + src.key_image + .as_ref() + .unwrap_or(&Default::default()) + .data + .as_slice(), + ), value: JsonU64(src.value), direction: direction_str.to_owned(), } @@ -1402,11 +1516,7 @@ pub struct JsonProcessedBlockResponse { impl From<&api::GetProcessedBlockResponse> for JsonProcessedBlockResponse { fn from(src: &api::GetProcessedBlockResponse) -> Self { Self { - tx_outs: src - .get_tx_outs() - .iter() - .map(JsonProcessedTxOut::from) - .collect(), + tx_outs: src.tx_outs.iter().map(JsonProcessedTxOut::from).collect(), } } } @@ -1432,7 +1542,7 @@ pub struct JsonMobilecoindVersionResponse { impl From<&api::MobilecoindVersionResponse> for JsonMobilecoindVersionResponse { fn from(src: &api::MobilecoindVersionResponse) -> Self { Self { - version: src.get_version().to_string(), + version: src.version.to_string(), } } } @@ -1449,7 +1559,7 @@ mod test { use mc_transaction_core_test_utils::AccountKey; use mc_util_from_random::FromRandom; use rand::{rngs::StdRng, SeedableRng}; - use std::collections::HashMap; + use std::collections::BTreeMap; /// Test conversion of TxProposal #[test] @@ -1498,39 +1608,43 @@ mod test { let attempted_spend_tombstone = 1234; // make proto UnspentTxOut - let mut unspent = api::UnspentTxOut::new(); - unspent.set_tx_out(mc_api::external::TxOut::from(&tx_out)); - unspent.set_subaddress_index(subaddress_index); - unspent.set_key_image(mc_api::external::KeyImage::from(&key_image)); - unspent.set_value(value); - unspent.set_attempted_spend_height(attempted_spend_height); - unspent.set_attempted_spend_tombstone(attempted_spend_tombstone); - unspent + api::UnspentTxOut { + tx_out: Some((&tx_out).into()), + subaddress_index, + key_image: Some((&key_image).into()), + value, + attempted_spend_height, + attempted_spend_tombstone, + ..Default::default() + } }; // Make proto outlay - let mut outlay = api::OutlayV2::new(); let public_addr = AccountKey::random(&mut rng).default_subaddress(); - outlay.set_receiver(mc_api::external::PublicAddress::from(&public_addr)); - outlay.set_value(1234); + let outlay = api::OutlayV2 { + value: 1234, + receiver: Some((&public_addr).into()), + ..Default::default() + }; - let outlay_index_to_tx_out_index = HashMap::from_iter(vec![(0, 0)]); + let outlay_index_to_tx_out_index = BTreeMap::from_iter(vec![(0, 0)]); let outlay_confirmation_numbers = [mc_transaction_extra::TxOutConfirmationNumber::from( [0u8; 32], )]; // Make proto TxProposal - let mut proto_proposal = api::TxProposal::new(); - proto_proposal.set_input_list(RepeatedField::from_vec(vec![utxo])); - proto_proposal.set_outlay_list(RepeatedField::from_vec(vec![outlay])); - proto_proposal.set_tx(mc_api::external::Tx::from(&tx)); - proto_proposal.set_outlay_index_to_tx_out_index(outlay_index_to_tx_out_index); - proto_proposal.set_outlay_confirmation_numbers(RepeatedField::from_vec( - outlay_confirmation_numbers + let proto_proposal = api::TxProposal { + input_list: vec![utxo], + outlay_list: vec![outlay], + tx: Some((&tx).into()), + fee: 0, + outlay_index_to_tx_out_index, + outlay_confirmation_numbers: outlay_confirmation_numbers .iter() .map(|x| x.to_vec()) .collect(), - )); + ..Default::default() + }; // Proto -> Json let json_proposal = JsonTxProposal::from(&proto_proposal); @@ -1543,63 +1657,183 @@ mod test { assert_eq!(proto_proposal.outlay_list, proto2.outlay_list); // The tx is complicated, so check each field of the tx - assert_eq!(proto_proposal.get_tx().prefix, proto2.get_tx().prefix); + assert_eq!( + proto_proposal.tx.as_ref().unwrap().prefix, + proto2.tx.as_ref().unwrap().prefix + ); assert_eq!( proto_proposal - .get_tx() - .get_signature() - .get_ring_signatures()[0] + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .ring_signatures[0] .c_zero, - proto2.get_tx().get_signature().get_ring_signatures()[0].c_zero + proto2 + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .ring_signatures[0] + .c_zero ); assert_eq!( proto_proposal - .get_tx() - .get_signature() - .get_ring_signatures()[0] + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .ring_signatures[0] .responses, - proto2.get_tx().get_signature().get_ring_signatures()[0].responses + proto2 + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .ring_signatures[0] + .responses ); assert_eq!( proto_proposal - .get_tx() - .get_signature() - .get_ring_signatures()[0] + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .ring_signatures[0] .key_image, - proto2.get_tx().get_signature().get_ring_signatures()[0].key_image + proto2 + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .ring_signatures[0] + .key_image ); assert_eq!( - proto_proposal.get_tx().get_signature().ring_signatures, - proto2.get_tx().get_signature().ring_signatures + proto_proposal + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .ring_signatures, + proto2 + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .ring_signatures ); assert_eq!( proto_proposal - .get_tx() - .get_signature() + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() .pseudo_output_commitments, - proto2.get_tx().get_signature().pseudo_output_commitments + proto2 + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .pseudo_output_commitments ); assert_eq!( - proto_proposal.get_tx().get_signature().range_proof_bytes, - proto2.get_tx().get_signature().range_proof_bytes, + proto_proposal + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .range_proof_bytes, + proto2 + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .range_proof_bytes ); assert_eq!( - proto_proposal.get_tx().get_signature().range_proofs, - proto2.get_tx().get_signature().range_proofs + proto_proposal + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .range_proofs, + proto2 + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .range_proofs ); assert_eq!( proto_proposal - .get_tx() - .get_signature() + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() .pseudo_output_token_ids, - proto2.get_tx().get_signature().pseudo_output_token_ids, + proto2 + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .pseudo_output_token_ids ); assert_eq!( - proto_proposal.get_tx().get_signature().output_token_ids, - proto2.get_tx().get_signature().output_token_ids, + proto_proposal + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .output_token_ids, + proto2 + .tx + .as_ref() + .unwrap() + .signature + .as_ref() + .unwrap() + .output_token_ids ); - assert_eq!(proto_proposal.get_tx().signature, proto2.get_tx().signature); + assert_eq!( + proto_proposal.tx.as_ref().unwrap().signature, + proto2.tx.as_ref().unwrap().signature + ); assert_eq!(proto_proposal.tx, proto2.tx); // Check the rest of the fields diff --git a/mobilecoind/Cargo.toml b/mobilecoind/Cargo.toml index 89044c7f10..0e8614d06e 100644 --- a/mobilecoind/Cargo.toml +++ b/mobilecoind/Cargo.toml @@ -62,13 +62,12 @@ aes-gcm = "0.10.3" clap = { version = "4.5", features = ["derive", "env"] } crossbeam-channel = "0.5" displaydoc = "0.2" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } hex_fmt = "0.3" lmdb-rkv = "0.14.0" mc-attestation-verifier = "0.4.3" num_cpus = "1.16" prost = { version = "0.11", default-features = false, features = ["prost-derive"] } -protobuf = "2.27.1" rand = "0.8" rayon = "1.9" reqwest = { version = "0.11", default-features = false, features = ["blocking", "rustls-tls", "gzip"] } diff --git a/mobilecoind/api/Cargo.toml b/mobilecoind/api/Cargo.toml index 460189fee5..13b860c21f 100644 --- a/mobilecoind/api/Cargo.toml +++ b/mobilecoind/api/Cargo.toml @@ -16,8 +16,8 @@ mc-fog-api = { path = "../../fog/api" } mc-util-uri = { path = "../../util/uri" } futures = "0.3" -grpcio = "0.13" -protobuf = "2.27.1" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } +prost = { version = "0.11", default-features = false, features = ["prost-derive"] } [dev-dependencies] mc-common = { path = "../../common", features = ["loggers"] } diff --git a/mobilecoind/api/proto/mobilecoind_api.proto b/mobilecoind/api/proto/mobilecoind_api.proto index 3476c948d7..ac5e50106b 100644 --- a/mobilecoind/api/proto/mobilecoind_api.proto +++ b/mobilecoind/api/proto/mobilecoind_api.proto @@ -138,7 +138,9 @@ message OutlayV2 { } // Structure used to refer to a TxOut in the ledger that is presumed to be spendable. -// The structure is annotated with extra information needed to spend the TxOut in a payment, calculated using the private keys that control the TxOut. +// +// The structure is annotated with extra information needed to spend the TxOut +// in a payment, calculated using the private keys that control the TxOut. message UnspentTxOut { // The actual TxOut object found in the ledger. external.TxOut tx_out = 1; @@ -182,6 +184,7 @@ message DecodedMemo { } // Structure used to represent the decoded MCIP #4 Authenticated sender memo and its variants. +// // Note that the sender can write whatever they want in a memo, and to rely on the data. // You must validate the memo by checking the hmac, see the ValidateAuthenticatedSenderMemo rpc call. message AuthenticatedSenderMemo { @@ -340,10 +343,12 @@ message ProcessedTxOut { } -// Recoverable Transaction History memo with an optional u64 specifying the -// subaddress index to generate the sender memo credential from. +// Recoverable Transaction History memo +// +// With an optional u64 specifying the subaddress index to generate the sender +// memo credential from. // Defaults to the default subaddress of the monitor. -// Allows optinally speciying a payment intent id or payment request id. +// Allows optionally specifying a payment intent id or payment request id. message TransactionMemo_RTH { optional uint64 subaddress_index = 1; oneof payment_id { @@ -556,7 +561,9 @@ message CreateRequestCodeResponse { } // Decode a base-58 encoded "MobileCoin Transfer Code" into entropy/tx_public_key/memo. -// This code provides a mobile client with everything required to construct a self-payment, allowing funds to be withdrawn from a gift card. +// +// This code provides a mobile client with everything required to construct a +// self-payment, allowing funds to be withdrawn from a gift card. message ParseTransferCodeRequest { string b58_code = 1; } @@ -628,6 +635,7 @@ message GetMembershipProofsResponse { // - Sum of inputs needs to be greater than sum of outlays and fee. // - The set of inputs to use would be chosen automatically by mobilecoind. // - The fee field could be set to zero, in which case mobilecoind would choose a fee. +// // Right now that fee is the network-reported minimum fee for the given token id. message GenerateTxRequest { // Monitor id sending the funds. @@ -675,6 +683,7 @@ message GenerateTxResponse { // - Sum of inputs needs to be greater than or equal to the sum of outlays and fee. // - The set of inputs to use would be chosen automatically by mobilecoind. // - The fee field could be set to zero, in which case mobilecoind would choose a fee. +// // Right now that fee is the network-reported minimum fee for the fee token id. message GenerateMixedTxRequest { // Monitor id sending the funds. @@ -761,9 +770,10 @@ message GenerateTransferCodeTxResponse { bytes bip39_entropy = 6; } -// Generate a transaction without a monitor, requires an account key and -// a list of UnspentTxOuts. All coins (minus the fee) are transferred to -// a single recipient. Used for temporary accounts like gift codes. +// Generate a transaction without a monitor. +// +// Requires an account key and a list of UnspentTxOuts. All coins (minus the fee) +// are transferred to a single recipient. Used for temporary accounts like gift codes. // All inputs must be of the same token id. message GenerateTxFromTxOutListRequest { // Account key that owns the transactions @@ -829,8 +839,10 @@ message GenerateBurnRedemptionTxResponse { TxProposal tx_proposal = 1; } -// Generate a simple swap proposal. The result is a signed contingent input -// which trades one currency for another and is suitable for use with the deqs. +// Generate a simple swap proposal. +// +// The result is a signed contingent input which trades one currency for another +// and is suitable for use with the deqs. // (This API is restrictive and doesn't let you build more complex SCIs.) message GenerateSwapRequest { // Monitor id sending the funds. diff --git a/mobilecoind/api/src/lib.rs b/mobilecoind/api/src/lib.rs index 4f1648fc1a..320cd27a4a 100644 --- a/mobilecoind/api/src/lib.rs +++ b/mobilecoind/api/src/lib.rs @@ -2,24 +2,19 @@ //! mobilecoind gRPC API. -// workaround for #![allow(box_pointers)] in protobuf generated files. -#![allow(renamed_and_removed_lints)] - use mc_util_uri::{Uri, UriScheme}; mod autogenerated_code { // Expose proto data types from included third-party/external proto files. pub use mc_api::{blockchain, external, printable, watcher}; - pub use mc_fog_api::ledger; - pub use protobuf::well_known_types::Empty; + pub use mc_fog_api::fog_ledger; - // Needed due to how to the auto-generated code references the Empty message. - pub mod empty { - pub use protobuf::well_known_types::Empty; + pub mod mobilecoind_api { + include!(concat!( + env!("OUT_DIR"), + "/protos-auto-gen/mobilecoind_api.rs" + )); } - - // Include the auto-generated code. - include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/mod.rs")); } pub use autogenerated_code::{mobilecoind_api::*, *}; @@ -27,11 +22,12 @@ pub use autogenerated_code::{mobilecoind_api::*, *}; impl OutlayV2 { /// This is used for some tests pub fn new_from_outlay_and_token_id(outlay: &Outlay, token_id: u64) -> Self { - let mut result = Self::new(); - result.set_value(outlay.value); - result.set_token_id(token_id); - result.set_receiver(outlay.get_receiver().clone()); - result + Self { + value: outlay.value, + receiver: outlay.receiver.clone(), + token_id, + tx_private_key: outlay.tx_private_key.clone(), + } } } diff --git a/mobilecoind/src/conversions.rs b/mobilecoind/src/conversions.rs index 615f32f240..001de64547 100644 --- a/mobilecoind/src/conversions.rs +++ b/mobilecoind/src/conversions.rs @@ -18,26 +18,23 @@ use mc_transaction_core::{ Amount, MemoPayload, TokenId, }; use mc_transaction_extra::{MemoType, TxOutConfirmationNumber}; -use protobuf::RepeatedField; impl From<&UnspentTxOut> for api::UnspentTxOut { fn from(src: &UnspentTxOut) -> Self { - let mut dst = Self::new(); - - dst.set_tx_out((&src.tx_out).into()); - dst.set_subaddress_index(src.subaddress_index); - dst.set_key_image((&src.key_image).into()); - dst.set_value(src.value); - dst.set_attempted_spend_height(src.attempted_spend_height); - dst.set_attempted_spend_tombstone(src.attempted_spend_tombstone); - dst.set_token_id(src.token_id); - dst.set_memo_payload(src.memo_payload.clone()); - - if let Ok(mp) = MemoPayload::try_from(&src.memo_payload[..]) { - dst.set_decoded_memo(decode_memo(&mp)); + Self { + tx_out: Some((&src.tx_out).into()), + subaddress_index: src.subaddress_index, + key_image: Some((&src.key_image).into()), + value: src.value, + attempted_spend_height: src.attempted_spend_height, + attempted_spend_tombstone: src.attempted_spend_tombstone, + token_id: src.token_id, + memo_payload: src.memo_payload.clone(), + decoded_memo: MemoPayload::try_from(&src.memo_payload[..]) + .ok() + .map(|m| decode_memo(&m)), + ..Default::default() } - - dst } } @@ -45,9 +42,9 @@ impl TryFrom<&api::UnspentTxOut> for UnspentTxOut { type Error = ConversionError; fn try_from(src: &api::UnspentTxOut) -> Result { - let tx_out = TxOut::try_from(src.get_tx_out())?; + let tx_out = TxOut::try_from(src.tx_out.as_ref().unwrap_or(&Default::default()))?; let subaddress_index = src.subaddress_index; - let key_image = KeyImage::try_from(src.get_key_image())?; + let key_image = KeyImage::try_from(src.key_image.as_ref().unwrap_or(&Default::default()))?; let value = src.value; let attempted_spend_height = src.attempted_spend_height; let attempted_spend_tombstone = src.attempted_spend_tombstone; @@ -82,31 +79,41 @@ fn bytes_to_tx_private_key(bytes: &[u8]) -> Result, Con // Note: This could be From<&MemoPayload> for api::DecodedMemo, but there are // orphan rules issues. fn decode_memo(memo_payload: &MemoPayload) -> api::DecodedMemo { - let mut result = api::DecodedMemo::new(); + let mut result = api::DecodedMemo::default(); match MemoType::try_from(memo_payload) { Ok(MemoType::Unused(_)) => {} Ok(MemoType::AuthenticatedSender(memo)) => { - let mut asm = api::AuthenticatedSenderMemo::new(); - asm.set_sender_hash(memo.sender_address_hash().as_ref().to_vec()); - result.set_authenticated_sender_memo(asm); + let asm = api::AuthenticatedSenderMemo { + sender_hash: memo.sender_address_hash().as_ref().to_vec(), + ..Default::default() + }; + result.decoded_memo = + Some(api::decoded_memo::DecodedMemo::AuthenticatedSenderMemo(asm)); } Ok(MemoType::AuthenticatedSenderWithPaymentRequestId(memo)) => { - let mut asm = api::AuthenticatedSenderMemo::new(); - asm.set_sender_hash(memo.sender_address_hash().as_ref().to_vec()); - asm.set_payment_request_id(memo.payment_request_id()); - result.set_authenticated_sender_memo(asm); + let asm = api::AuthenticatedSenderMemo { + sender_hash: memo.sender_address_hash().as_ref().to_vec(), + payment_request_id: Some(memo.payment_request_id()), + ..Default::default() + }; + result.decoded_memo = + Some(api::decoded_memo::DecodedMemo::AuthenticatedSenderMemo(asm)); } Ok(MemoType::AuthenticatedSenderWithPaymentIntentId(memo)) => { - let mut asm = api::AuthenticatedSenderMemo::new(); - asm.set_sender_hash(memo.sender_address_hash().as_ref().to_vec()); - asm.set_payment_intent_id(memo.payment_intent_id()); - result.set_authenticated_sender_memo(asm); + let asm = api::AuthenticatedSenderMemo { + sender_hash: memo.sender_address_hash().as_ref().to_vec(), + payment_intent_id: Some(memo.payment_intent_id()), + ..Default::default() + }; + result.decoded_memo = + Some(api::decoded_memo::DecodedMemo::AuthenticatedSenderMemo(asm)); } Ok(_) | Err(_) => { - let mut um = api::UnknownMemo::new(); - um.set_type_bytes(memo_payload.get_memo_type().to_vec()); - result.set_unknown_memo(um); + let um = api::UnknownMemo { + type_bytes: memo_payload.get_memo_type().to_vec(), + }; + result.decoded_memo = Some(api::decoded_memo::DecodedMemo::UnknownMemo(um)); } } @@ -115,15 +122,14 @@ fn decode_memo(memo_payload: &MemoPayload) -> api::DecodedMemo { impl From<&Outlay> for api::Outlay { fn from(src: &Outlay) -> Self { - let mut dst = Self::new(); - - dst.set_value(src.value); - dst.set_receiver((&src.receiver).into()); - if let Some(key) = src.tx_private_key { - dst.set_tx_private_key(key.to_bytes().to_vec()); + Self { + value: src.value, + receiver: Some((&src.receiver).into()), + tx_private_key: src + .tx_private_key + .map(|k| k.to_bytes().to_vec()) + .unwrap_or_default(), } - - dst } } @@ -132,8 +138,9 @@ impl TryFrom<&api::Outlay> for Outlay { fn try_from(src: &api::Outlay) -> Result { let value = src.value; - let receiver = PublicAddress::try_from(src.get_receiver())?; - let tx_private_key = bytes_to_tx_private_key(src.get_tx_private_key())?; + let receiver = + PublicAddress::try_from(src.receiver.as_ref().unwrap_or(&Default::default()))?; + let tx_private_key = bytes_to_tx_private_key(src.tx_private_key.as_slice())?; Ok(Self { value, @@ -145,16 +152,15 @@ impl TryFrom<&api::Outlay> for Outlay { impl From<&OutlayV2> for api::OutlayV2 { fn from(src: &OutlayV2) -> Self { - let mut dst = Self::new(); - - dst.set_value(src.amount.value); - dst.set_token_id(*src.amount.token_id); - dst.set_receiver((&src.receiver).into()); - if let Some(key) = src.tx_private_key { - dst.set_tx_private_key(key.to_bytes().to_vec()); + Self { + value: src.amount.value, + token_id: *src.amount.token_id, + receiver: Some((&src.receiver).into()), + tx_private_key: src + .tx_private_key + .map(|k| k.to_bytes().to_vec()) + .unwrap_or_default(), } - - dst } } @@ -163,8 +169,9 @@ impl TryFrom<&api::OutlayV2> for OutlayV2 { fn try_from(src: &api::OutlayV2) -> Result { let amount = Amount::new(src.value, TokenId::from(src.token_id)); - let receiver = PublicAddress::try_from(src.get_receiver())?; - let tx_private_key = bytes_to_tx_private_key(src.get_tx_private_key())?; + let receiver = + PublicAddress::try_from(src.receiver.as_ref().unwrap_or(&Default::default()))?; + let tx_private_key = bytes_to_tx_private_key(src.tx_private_key.as_slice())?; Ok(Self { amount, @@ -176,31 +183,23 @@ impl TryFrom<&api::OutlayV2> for OutlayV2 { impl From<&TxProposal> for api::TxProposal { fn from(src: &TxProposal) -> api::TxProposal { - let mut dst = api::TxProposal::new(); - - dst.set_input_list(RepeatedField::from_vec( - src.utxos.iter().map(|utxo| utxo.into()).collect(), - )); - dst.set_outlay_list(RepeatedField::from_vec( - src.outlays.iter().map(|outlay| outlay.into()).collect(), - )); - dst.set_tx((&src.tx).into()); - dst.set_fee(src.tx.prefix.fee); - dst.set_outlay_index_to_tx_out_index( - src.outlay_index_to_tx_out_index + Self { + input_list: src.utxos.iter().map(Into::into).collect(), + outlay_list: src.outlays.iter().map(Into::into).collect(), + tx: Some((&src.tx).into()), + fee: src.tx.prefix.fee, + outlay_index_to_tx_out_index: src + .outlay_index_to_tx_out_index .iter() .map(|(key, val)| (*key as u64, *val as u64)) .collect(), - ); - dst.set_outlay_confirmation_numbers( - src.outlay_confirmation_numbers + outlay_confirmation_numbers: src + .outlay_confirmation_numbers .iter() .map(|val| val.to_vec()) .collect(), - ); - dst.set_scis(src.scis.iter().map(Into::into).collect()); - - dst + scis: src.scis.iter().map(Into::into).collect(), + } } } @@ -208,32 +207,41 @@ impl TryFrom<&api::TxProposal> for TxProposal { type Error = ConversionError; fn try_from(src: &api::TxProposal) -> Result { - if src.fee != src.get_tx().get_prefix().fee { + if src.fee + != src + .tx + .as_ref() + .unwrap_or(&Default::default()) + .prefix + .as_ref() + .unwrap_or(&Default::default()) + .fee + { return Err(ConversionError::FeeMismatch); } let utxos = src - .get_input_list() + .input_list .iter() .map(UnspentTxOut::try_from) .collect::, ConversionError>>()?; let outlays: Vec = src - .get_outlay_list() + .outlay_list .iter() .map(OutlayV2::try_from) .collect::>()?; let scis: Vec = src - .get_scis() + .scis .iter() .map(SciForTx::try_from) .collect::>()?; - let tx = Tx::try_from(src.get_tx())?; + let tx = Tx::try_from(src.tx.as_ref().unwrap_or(&Default::default()))?; let outlay_index_to_tx_out_index = src - .get_outlay_index_to_tx_out_index() + .outlay_index_to_tx_out_index .iter() .map(|(key, val)| (*key as usize, *val as usize)) .collect::>(); @@ -250,7 +258,7 @@ impl TryFrom<&api::TxProposal> for TxProposal { } let outlay_confirmation_numbers = src - .get_outlay_confirmation_numbers() + .outlay_confirmation_numbers .iter() .map(|src| match src.len() { 32 => { @@ -275,10 +283,10 @@ impl TryFrom<&api::TxProposal> for TxProposal { impl From<&SciForTx> for api::SciForTx { fn from(src: &SciForTx) -> Self { - let mut dst = Self::new(); - dst.set_sci((&src.sci).into()); - dst.set_partial_fill_value(src.partial_fill_value); - dst + Self { + sci: Some((&src.sci).into()), + partial_fill_value: src.partial_fill_value, + } } } @@ -286,7 +294,7 @@ impl TryFrom<&api::SciForTx> for SciForTx { type Error = ConversionError; fn try_from(src: &api::SciForTx) -> Result { - let sci = src.get_sci().try_into()?; + let sci = src.sci.as_ref().unwrap_or(&Default::default()).try_into()?; let partial_fill_value = src.partial_fill_value; Ok(Self { @@ -305,6 +313,7 @@ mod test { test_utils::{create_ledger, create_transaction, initialize_ledger}, Ledger, }; + use mc_mobilecoind_api::decoded_memo; use mc_transaction_core::{tokens::Mob, BlockVersion, Token}; use mc_transaction_extra::{ AuthenticatedSenderMemo, AuthenticatedSenderWithPaymentIntentIdMemo, @@ -351,11 +360,14 @@ mod test { let proto = api::UnspentTxOut::from(&rust); - assert_eq!(tx_out, TxOut::try_from(proto.get_tx_out()).unwrap()); + assert_eq!( + tx_out, + TxOut::try_from(proto.tx_out.as_ref().unwrap()).unwrap() + ); assert_eq!(subaddress_index, proto.subaddress_index); assert_eq!( key_image, - KeyImage::try_from(proto.get_key_image()).unwrap() + KeyImage::try_from(proto.key_image.as_ref().unwrap()).unwrap() ); assert_eq!(value, proto.value); assert_eq!(attempted_spend_height, proto.attempted_spend_height); @@ -392,11 +404,14 @@ mod test { let memo2 = AuthenticatedSenderMemo::new(&alice_cred, bob_addr.view_public_key(), &tx_public_key); let decoded = decode_memo(&MemoPayload::from(memo2)); - assert!(decoded.has_authenticated_sender_memo()); - let sender_memo = decoded.get_authenticated_sender_memo(); - assert_eq!(sender_memo.get_sender_hash(), alice_hash.as_ref()); - assert!(!sender_memo.has_payment_request_id()); - assert!(!sender_memo.has_payment_intent_id()); + if let Some(decoded_memo::DecodedMemo::AuthenticatedSenderMemo(memo)) = decoded.decoded_memo + { + assert_eq!(memo.sender_hash, alice_hash.as_ref()); + assert_eq!(memo.payment_request_id, None); + assert_eq!(memo.payment_intent_id, None); + } else { + panic!("Expected AuthenticatedSenderMemo, got {decoded:?}"); + } let memo3 = AuthenticatedSenderWithPaymentRequestIdMemo::new( &alice_cred, @@ -405,13 +420,14 @@ mod test { 7u64, ); let decoded = decode_memo(&MemoPayload::from(memo3)); - assert!(decoded.has_authenticated_sender_memo()); - assert!(!decoded.has_unknown_memo()); - let sender_memo = decoded.get_authenticated_sender_memo(); - assert_eq!(sender_memo.get_sender_hash(), alice_hash.as_ref()); - assert!(sender_memo.has_payment_request_id()); - assert_eq!(sender_memo.get_payment_request_id(), 7); - assert!(!sender_memo.has_payment_intent_id()); + if let Some(decoded_memo::DecodedMemo::AuthenticatedSenderMemo(memo)) = decoded.decoded_memo + { + assert_eq!(memo.sender_hash, alice_hash.as_ref()); + assert_eq!(memo.payment_request_id, Some(7)); + assert_eq!(memo.payment_intent_id, None); + } else { + panic!("Expected AuthenticatedSenderMemo, got {decoded:?}"); + } let memo4 = AuthenticatedSenderWithPaymentIntentIdMemo::new( &alice_cred, @@ -420,29 +436,32 @@ mod test { 9u64, ); let decoded = decode_memo(&MemoPayload::from(memo4)); - assert!(decoded.has_authenticated_sender_memo()); - assert!(!decoded.has_unknown_memo()); - let sender_memo = decoded.get_authenticated_sender_memo(); - assert_eq!(sender_memo.get_sender_hash(), alice_hash.as_ref()); - assert!(!sender_memo.has_payment_request_id()); - assert!(sender_memo.has_payment_intent_id()); - assert_eq!(sender_memo.get_payment_intent_id(), 9); + if let Some(decoded_memo::DecodedMemo::AuthenticatedSenderMemo(memo)) = decoded.decoded_memo + { + assert_eq!(memo.sender_hash, alice_hash.as_ref()); + assert_eq!(memo.payment_request_id, None); + assert_eq!(memo.payment_intent_id, Some(9)); + } else { + panic!("Expected AuthenticatedSenderMemo, got {decoded:?}"); + } // Destination memos are not implemented yet let memo5 = DestinationMemo::new(ShortAddressHash::from(&bob_addr), 17, 18).unwrap(); let decoded = decode_memo(&MemoPayload::from(memo5)); - assert!(!decoded.has_authenticated_sender_memo()); - assert!(decoded.has_unknown_memo()); - let type_bytes = decoded.get_unknown_memo().get_type_bytes(); - assert_eq!(&type_bytes, &[2u8, 0u8]); + if let Some(decoded_memo::DecodedMemo::UnknownMemo(memo)) = decoded.decoded_memo { + assert_eq!(memo.type_bytes, &[2u8, 0u8]); + } else { + panic!("Expected UnknownMemo, got {decoded:?}"); + } // This is an unassigned memo type let memo6 = MemoPayload::new([7u8, 8u8], [0u8; 64]); let decoded = decode_memo(&memo6); - assert!(!decoded.has_authenticated_sender_memo()); - assert!(decoded.has_unknown_memo()); - let type_bytes = decoded.get_unknown_memo().get_type_bytes(); - assert_eq!(&type_bytes, &[7u8, 8u8]); + if let Some(decoded_memo::DecodedMemo::UnknownMemo(memo)) = decoded.decoded_memo { + assert_eq!(memo.type_bytes, &[7u8, 8u8]); + } else { + panic!("Expected UnknownMemo, got {decoded:?}"); + } } #[test] @@ -460,7 +479,7 @@ mod test { assert_eq!(proto.value, rust.value); assert_eq!( - PublicAddress::try_from(proto.get_receiver()).unwrap(), + PublicAddress::try_from(proto.receiver.as_ref().unwrap()).unwrap(), public_addr ); @@ -483,7 +502,7 @@ mod test { assert_eq!(proto.value, rust.value); assert_eq!( - PublicAddress::try_from(proto.get_receiver()).unwrap(), + PublicAddress::try_from(proto.receiver.as_ref().unwrap()).unwrap(), public_addr ); @@ -573,18 +592,18 @@ mod test { assert_eq!( rust.utxos, - vec![UnspentTxOut::try_from(&proto.get_input_list()[0]).unwrap()], + vec![UnspentTxOut::try_from(&proto.input_list[0]).unwrap()], ); assert_eq!( rust.outlays, - vec![OutlayV2::try_from(&proto.get_outlay_list()[0]).unwrap()], + vec![OutlayV2::try_from(&proto.outlay_list[0]).unwrap()], ); - assert_eq!(proto.get_outlay_index_to_tx_out_index().len(), 1); - assert_eq!(proto.get_outlay_index_to_tx_out_index().get(&0), Some(&0)); + assert_eq!(proto.outlay_index_to_tx_out_index.len(), 1); + assert_eq!(proto.outlay_index_to_tx_out_index.get(&0), Some(&0)); - assert_eq!(rust.tx, Tx::try_from(proto.get_tx()).unwrap()); + assert_eq!(rust.tx, Tx::try_from(proto.tx.as_ref().unwrap()).unwrap()); // Proto -> Rust assert_eq!(rust, TxProposal::try_from(&proto).unwrap()); diff --git a/mobilecoind/src/error.rs b/mobilecoind/src/error.rs index 40bb164366..1b4f95a76a 100644 --- a/mobilecoind/src/error.rs +++ b/mobilecoind/src/error.rs @@ -122,9 +122,6 @@ pub enum Error { /// Signed Contingent Input: {0} SignedContingentInput(SignedContingentInputError), - - /// Protobuf error: {0} - Protobuf(protobuf::ProtobufError), } impl From> for Error { @@ -210,9 +207,3 @@ impl From for Error { Self::SignedContingentInput(e) } } - -impl From for Error { - fn from(e: protobuf::ProtobufError) -> Self { - Self::Protobuf(e) - } -} diff --git a/mobilecoind/src/service.rs b/mobilecoind/src/service.rs index 7517620d24..2c9b4fe3c5 100644 --- a/mobilecoind/src/service.rs +++ b/mobilecoind/src/service.rs @@ -15,14 +15,14 @@ use crate::{ transaction_memo::TransactionMemo, utxo_store::{UnspentTxOut, UtxoId}, }; -use api::ledger::{TxOutResult, TxOutResultCode}; +use api::fog_ledger::{TxOutResult, TxOutResultCode}; use bip39::{Language, Mnemonic, MnemonicType}; use grpcio::{EnvBuilder, RpcContext, RpcStatus, RpcStatusCode, ServerBuilder, UnarySink}; use mc_account_keys::{ burn_address, AccountKey, PublicAddress, RootIdentity, ShortAddressHash, DEFAULT_SUBADDRESS_INDEX, }; -use mc_api::blockchain::ArchiveBlock; +use mc_api::{blockchain::ArchiveBlock, printable, printable::printable_wrapper}; use mc_blockchain_types::BlockIndex; use mc_common::{ logger::{log, Logger}, @@ -36,7 +36,7 @@ use mc_ledger_db::{Error as LedgerError, Ledger, LedgerDB}; use mc_ledger_sync::{NetworkState, PollingNetworkState}; use mc_mobilecoind_api::{ self as api, - mobilecoind_api_grpc::{create_mobilecoind_api, MobilecoindApi}, + mobilecoind_api::{create_mobilecoind_api, MobilecoindApi}, MobilecoindUri, }; use mc_transaction_builder::BurnRedemptionMemoBuilder; @@ -55,7 +55,6 @@ use mc_util_grpc::{ }; use mc_watcher::watcher_db::WatcherDB; use mc_watcher_api::TimestampResultCode; -use protobuf::{ProtobufEnum, RepeatedField}; use std::sync::{Arc, Mutex, RwLock}; pub struct Service { @@ -66,6 +65,8 @@ pub struct Service { _server: grpcio::Server, } +// for the root_entropy usage +#[allow(deprecated)] impl Service { pub fn new< T: BlockchainConnection + UserTxConnection + 'static, @@ -199,6 +200,7 @@ impl ServiceApi { @@ -236,13 +238,10 @@ impl Result { - let mut response = api::MobilecoindVersionResponse::new(); - response.set_version(env!("CARGO_PKG_VERSION").to_string()); - Ok(response) + fn get_version_impl(&self, _request: ()) -> Result { + Ok(api::MobilecoindVersionResponse { + version: (env!("CARGO_PKG_VERSION").to_string()), + }) } fn add_monitor_impl( @@ -275,16 +274,13 @@ impl Result { + fn remove_monitor_impl(&mut self, request: api::RemoveMonitorRequest) -> Result<(), RpcStatus> { // Get MonitorId from from the GRPC request. let monitor_id = MonitorId::try_from(&request.monitor_id) .map_err(|err| rpc_internal_error("monitor_id.try_from.bytes", err, &self.logger))?; @@ -297,24 +293,21 @@ impl Result { let monitor_map: HashMap = self.mobilecoind_db.get_monitor_map().map_err(|err| { rpc_internal_error("mobilecoind_db.get_monitor_store_map", err, &self.logger) })?; - let mut response = api::GetMonitorListResponse::new(); - for id in monitor_map.keys() { - response.mut_monitor_id_list().push(id.to_vec()); - } - Ok(response) + Ok(api::GetMonitorListResponse { + monitor_id_list: monitor_map.keys().map(|id| id.to_vec()).collect(), + }) } fn get_monitor_status_impl( @@ -331,16 +324,18 @@ impl = utxos.iter().map(|utxo| utxo.into()).collect(); // Return response. - let mut response = api::GetUnspentTxOutListResponse::new(); - response.set_output_list(RepeatedField::from_vec(proto_utxos)); - Ok(response) + Ok(api::GetUnspentTxOutListResponse { + output_list: proto_utxos, + }) } fn get_all_unspent_tx_out_impl( @@ -394,32 +389,32 @@ impl = utxos.iter().map(|utxo| utxo.into()).collect(); // Return response. - let mut response = api::GetAllUnspentTxOutResponse::new(); - response.set_output_list(RepeatedField::from_vec(proto_utxos)); - Ok(response) + Ok(api::GetAllUnspentTxOutResponse { + output_list: proto_utxos, + }) } fn generate_root_entropy_impl( &mut self, - _request: api::Empty, + _request: (), ) -> Result { let mut rng = rand::thread_rng(); let root_id = RootIdentity::from_random(&mut rng); - let mut response = api::GenerateRootEntropyResponse::new(); - response.set_root_entropy(root_id.root_entropy.as_ref().to_vec()); - Ok(response) + Ok(api::GenerateRootEntropyResponse { + root_entropy: root_id.root_entropy.as_ref().to_vec(), + }) } fn generate_mnemonic_impl( &mut self, - _request: api::Empty, + _request: (), ) -> Result { let mnemonic = Mnemonic::new(MnemonicType::Words24, Language::English); - let mut response = api::GenerateMnemonicResponse::new(); - response.set_mnemonic(mnemonic.phrase().to_string()); - response.set_bip39_entropy(mnemonic.entropy().to_vec()); - Ok(response) + Ok(api::GenerateMnemonicResponse { + mnemonic: mnemonic.phrase().to_string(), + bip39_entropy: mnemonic.entropy().to_vec(), + }) } fn get_account_key_from_root_entropy_impl( @@ -427,7 +422,7 @@ impl Result { // Get the entropy. - if request.get_root_entropy().len() != 32 { + if request.root_entropy.len() != 32 { return Err(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, "entropy".into(), @@ -436,29 +431,29 @@ impl Result { - let mnemonic = Mnemonic::from_phrase(request.get_mnemonic(), Language::English) + let mnemonic = Mnemonic::from_phrase(&request.mnemonic, Language::English) .map_err(|err| rpc_invalid_arg_error("mnemonic", err, &self.logger))?; let key = mnemonic.derive_slip10_key(request.account_index); let account_key = AccountKey::from(key); // Return response. - let mut response = api::GetAccountKeyResponse::new(); - response.set_account_key((&account_key).into()); - Ok(response) + Ok(api::GetAccountKeyResponse { + account_key: Some((&account_key).into()), + }) } fn get_public_address_impl( @@ -492,33 +487,38 @@ impl Result { - let address = PublicAddress::try_from(request.get_public_address()) - .map_err(|err| rpc_invalid_arg_error("PublicAddress.try_from", err, &self.logger))?; + let address = PublicAddress::try_from( + request + .public_address + .as_ref() + .unwrap_or(&Default::default()), + ) + .map_err(|err| rpc_invalid_arg_error("PublicAddress.try_from", err, &self.logger))?; let hash = ShortAddressHash::from(&address); - let mut response = api::GetShortAddressHashResponse::new(); - response.set_hash(hash.as_ref().to_vec()); - Ok(response) + Ok(api::GetShortAddressHashResponse { + hash: hash.as_ref().to_vec(), + }) } fn validate_authenticated_sender_memo_impl( @@ -526,18 +526,19 @@ impl Result { // Read the utxo proto - let utxo = UnspentTxOut::try_from(request.get_utxo()) + let utxo = UnspentTxOut::try_from(request.utxo.as_ref().unwrap_or(&Default::default())) .map_err(|err| rpc_invalid_arg_error("unspent_tx_out.try_from", err, &self.logger))?; let memo_payload = MemoPayload::try_from(&utxo.memo_payload[..]) .map_err(|err| rpc_invalid_arg_error("memo_payload.try_from", err, &self.logger))?; // Read the sender proto - let sender = PublicAddress::try_from(request.get_sender()) - .map_err(|err| rpc_invalid_arg_error("sender.try_from", err, &self.logger))?; + let sender = + PublicAddress::try_from(request.sender.as_ref().unwrap_or(&Default::default())) + .map_err(|err| rpc_invalid_arg_error("sender.try_from", err, &self.logger))?; // Get MonitorId from the GRPC request. - let monitor_id = MonitorId::try_from(request.get_monitor_id()) + let monitor_id = MonitorId::try_from(request.monitor_id.as_slice()) .map_err(|err| rpc_invalid_arg_error("monitor_id.try_from.bytes", err, &self.logger))?; // Get monitor data. @@ -553,9 +554,7 @@ impl { memo.validate(&sender, &subaddress_vpk, tx_out_public_key) } @@ -579,19 +578,24 @@ impl Result { - let tx_out = TxOut::try_from(request.get_txo()) + let tx_out = TxOut::try_from(request.txo.as_ref().unwrap_or(&Default::default())) .map_err(|err| rpc_internal_error("tx_out.try_from", err, &self.logger))?; - let view_private_key = RistrettoPrivate::try_from(request.get_view_private_key()) - .map_err(|err| rpc_invalid_arg_error("view_private_key.try_from", err, &self.logger))?; + let view_private_key = RistrettoPrivate::try_from( + request + .view_private_key + .as_ref() + .unwrap_or(&Default::default()), + ) + .map_err(|err| rpc_invalid_arg_error("view_private_key.try_from", err, &self.logger))?; match tx_out.view_key_match(&view_private_key) { Ok((amount, shared_secret)) => { @@ -601,8 +605,7 @@ impl Ok(api::TxOutViewKeyMatchResponse { @@ -616,33 +619,30 @@ impl Result { - let wrapper = - api::printable::PrintableWrapper::b58_decode(request.get_b58_code().to_string()) - .map_err(|err| { - rpc_internal_error("PrintableWrapper_b58_decode", err, &self.logger) - })?; - - // A request code could be a public address or a payment request - if wrapper.has_payment_request() { - let payment_request = wrapper.get_payment_request(); - let mut response = api::ParseRequestCodeResponse::new(); - response.set_receiver(payment_request.get_public_address().clone()); - response.set_value(payment_request.get_value()); - response.set_memo(payment_request.get_memo().to_string()); - response.set_token_id(payment_request.get_token_id()); - Ok(response) - } else if wrapper.has_public_address() { - let public_address = wrapper.get_public_address(); - let mut response = api::ParseRequestCodeResponse::new(); - response.set_receiver(public_address.clone()); - response.set_value(0); - response.set_memo(String::new()); - Ok(response) - } else { - Err(RpcStatus::with_message( + let wrapper = api::printable::PrintableWrapper::b58_decode(request.b58_code.to_string()) + .map_err(|err| rpc_internal_error("PrintableWrapper_b58_decode", err, &self.logger))?; + + match wrapper.wrapper { + Some(printable_wrapper::Wrapper::PaymentRequest(payment_request)) => { + Ok(api::ParseRequestCodeResponse { + receiver: payment_request.public_address, + value: payment_request.value, + memo: payment_request.memo, + token_id: payment_request.token_id, + }) + } + Some(printable_wrapper::Wrapper::PublicAddress(public_address)) => { + Ok(api::ParseRequestCodeResponse { + receiver: Some(public_address), + value: 0, + memo: String::new(), + ..Default::default() + }) + } + _ => Err(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, "Neither payment request nor public address".into(), - )) + )), } } @@ -650,47 +650,55 @@ impl Result { - let receiver = PublicAddress::try_from(request.get_receiver()) - .map_err(|err| rpc_internal_error("PublicAddress.try_from", err, &self.logger))?; + let receiver = + PublicAddress::try_from(request.receiver.as_ref().unwrap_or(&Default::default())) + .map_err(|err| rpc_internal_error("PublicAddress.try_from", err, &self.logger))?; - let mut payment_request = api::printable::PaymentRequest::new(); - payment_request.set_public_address((&receiver).into()); - payment_request.set_value(request.get_value()); - payment_request.set_memo(request.get_memo().to_string()); - payment_request.set_token_id(request.get_token_id()); + let payment_request = api::printable::PaymentRequest { + public_address: Some((&receiver).into()), + value: request.value, + memo: request.memo.clone(), + token_id: request.token_id, + ..Default::default() + }; - let mut wrapper = api::printable::PrintableWrapper::new(); - wrapper.set_payment_request(payment_request); + let wrapper = api::printable::PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PaymentRequest(payment_request)), + }; let encoded = wrapper .b58_encode() .map_err(|err| rpc_internal_error("b58_encode", err, &self.logger))?; - let mut response = api::CreateRequestCodeResponse::new(); - response.set_b58_code(encoded); - Ok(response) + Ok(api::CreateRequestCodeResponse { b58_code: encoded }) } fn parse_transfer_code_impl( &mut self, request: api::ParseTransferCodeRequest, ) -> Result { - let wrapper = - api::printable::PrintableWrapper::b58_decode(request.get_b58_code().to_string()) - .map_err(|err| { - rpc_internal_error("PrintableWrapper.b58_decode", err, &self.logger) - })?; + let wrapper = api::printable::PrintableWrapper::b58_decode(request.b58_code.to_string()) + .map_err(|err| rpc_internal_error("PrintableWrapper.b58_decode", err, &self.logger))?; - if !wrapper.has_transfer_payload() { - return Err(RpcStatus::with_message( - RpcStatusCode::INVALID_ARGUMENT, - "has_transfer_payload".into(), - )); - } - let transfer_payload = wrapper.get_transfer_payload(); + let transfer_payload = + if let Some(printable_wrapper::Wrapper::TransferPayload(transfer_payload)) = + wrapper.wrapper + { + transfer_payload + } else { + return Err(RpcStatus::with_message( + RpcStatusCode::INVALID_ARGUMENT, + "has_transfer_payload".into(), + )); + }; - let tx_public_key = RistrettoPublic::try_from(transfer_payload.get_tx_out_public_key()) - .map_err(|err| rpc_internal_error("RistrettoPublic.try_from", err, &self.logger))?; + let tx_public_key = RistrettoPublic::try_from( + transfer_payload + .tx_out_public_key + .as_ref() + .unwrap_or(&Default::default()), + ) + .map_err(|err| rpc_internal_error("RistrettoPublic.try_from", err, &self.logger))?; let compressed_tx_public_key = CompressedRistrettoPublic::from(&tx_public_key); @@ -714,23 +722,23 @@ impl Result { - let wrapper = - api::printable::PrintableWrapper::b58_decode(request.get_b58_code().to_string()) - .map_err(|err| { - rpc_invalid_arg_error("PrintableWrapper_b58_decode", err, &self.logger) - })?; + let wrapper = api::printable::PrintableWrapper::b58_decode(request.b58_code.to_string()) + .map_err(|err| { + rpc_invalid_arg_error("PrintableWrapper_b58_decode", err, &self.logger) + })?; - // An address code could be a public address or a payment request - if wrapper.has_payment_request() { - let payment_request = wrapper.get_payment_request(); - let mut response = api::ParseAddressCodeResponse::new(); - response.set_receiver(payment_request.get_public_address().clone()); - Ok(response) - } else if wrapper.has_public_address() { - let public_address = wrapper.get_public_address(); - let mut response = api::ParseAddressCodeResponse::new(); - response.set_receiver(public_address.clone()); - Ok(response) - } else { - Err(RpcStatus::with_message( + match wrapper.wrapper { + Some(printable_wrapper::Wrapper::PaymentRequest(printable::PaymentRequest { + public_address: Some(public_address), + .. + })) => Ok(api::ParseAddressCodeResponse { + receiver: Some(public_address), + }), + Some(printable_wrapper::Wrapper::PublicAddress(public_address)) => { + Ok(api::ParseAddressCodeResponse { + receiver: Some(public_address), + }) + } + _ => Err(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, "Neither payment request nor public address".into(), - )) + )), } } @@ -873,19 +888,21 @@ impl Result { - let receiver = PublicAddress::try_from(request.get_receiver()) - .map_err(|err| rpc_internal_error("PublicAddress.try_from", err, &self.logger))?; - - let mut wrapper = api::printable::PrintableWrapper::new(); - wrapper.set_public_address((&receiver).into()); + let receiver = + PublicAddress::try_from(request.receiver.as_ref().unwrap_or(&Default::default())) + .map_err(|err| rpc_internal_error("PublicAddress.try_from", err, &self.logger))?; + + let wrapper = api::printable::PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress( + (&receiver).into(), + )), + }; let encoded = wrapper .b58_encode() .map_err(|err| rpc_internal_error("b58_encode", err, &self.logger))?; - let mut response = api::CreateAddressCodeResponse::new(); - response.set_b58_code(encoded); - Ok(response) + Ok(api::CreateAddressCodeResponse { b58_code: encoded }) } /// Get mixins @@ -893,9 +910,9 @@ impl Result { - let num_mixins: usize = request.get_num_mixins() as usize; + let num_mixins: usize = request.num_mixins as usize; let excluded: Vec = request - .get_excluded() + .excluded .iter() .map(|tx_out| { // Proto -> Rust struct conversion. @@ -926,20 +943,17 @@ impl = mixins_with_proofs .iter() - .map(|(tx_out, proof)| { - let mut tx_out_with_proof = api::TxOutWithProof::new(); - tx_out_with_proof.set_output(tx_out.into()); - tx_out_with_proof.set_proof(proof.into()); - tx_out_with_proof + .map(|(tx_out, proof)| api::TxOutWithProof { + output: Some(tx_out.into()), + proof: Some(proof.into()), }) .collect(); - response.set_mixins(RepeatedField::from(tx_outs_with_proofs)); - Ok(response) + Ok(api::GetMixinsResponse { + mixins: tx_outs_with_proofs, + }) } /// Get a proof of membership for each requested TxOut. @@ -950,7 +964,7 @@ impl = match (request.outputs.is_empty(), request.indices.is_empty()) { // No outputs but indices are provided (true, false) => request - .get_indices() + .indices .iter() .map(|idx| { self.ledger_db @@ -968,7 +982,7 @@ impl { request - .get_outputs() + .outputs .iter() .map(|tx_out| { // Proto -> Rust struct conversion. @@ -996,16 +1010,16 @@ impl = request - .get_input_list() + .input_list .iter() .enumerate() .map(|(i, proto_utxo)| { @@ -1080,7 +1094,7 @@ impl = request - .get_outlay_list() + .outlay_list .iter() .map(|outlay_proto| { Outlay::try_from(outlay_proto) @@ -1089,8 +1103,11 @@ impl, RpcStatus>>()?; // Get transaction memo builder. - let transaction_memo = TransactionMemo::try_from(request.get_memo()) - .map_err(|err| rpc_invalid_arg_error("transaction_memo.try_from", err, &self.logger))?; + let transaction_memo = + TransactionMemo::try_from(request.memo.as_ref().unwrap_or(&Default::default())) + .map_err(|err| { + rpc_invalid_arg_error("transaction_memo.try_from", err, &self.logger) + })?; let memo_builder = transaction_memo.memo_builder(&sender_monitor_data.account_key); // Attempt to construct a transaction. @@ -1112,9 +1129,9 @@ impl = request - .get_input_list() + .input_list .iter() .enumerate() .map(|(i, proto_utxo)| { @@ -1181,7 +1198,7 @@ impl = request - .get_outlay_list() + .outlay_list .iter() .map(OutlayV2::try_from) .collect::>() @@ -1189,7 +1206,7 @@ impl = request - .get_scis() + .scis .iter() .map(SciForTx::try_from) .collect::>() @@ -1219,9 +1236,9 @@ impl = request - .get_input_list() + .input_list .iter() .enumerate() .map(|(i, proto_utxo)| { @@ -1291,8 +1308,9 @@ impl, RpcStatus>>()?; - let receiver = PublicAddress::try_from(request.get_receiver()) - .map_err(|err| rpc_internal_error("PublicAddress.try_from", err, &self.logger))?; + let receiver = + PublicAddress::try_from(request.receiver.as_ref().unwrap_or(&Default::default())) + .map_err(|err| rpc_internal_error("PublicAddress.try_from", err, &self.logger))?; let tx_proposal = self .transactions_manager @@ -1312,9 +1330,9 @@ impl = request - .get_input_list() + .input_list .iter() .enumerate() .map(|(i, proto_utxo)| { @@ -1389,13 +1407,13 @@ impl Result { // Generate entropy. - let mnemonic_response = self.generate_mnemonic_impl(api::Empty::new())?; - let mnemonic_str = mnemonic_response.get_mnemonic().to_string(); - let bip39_entropy = mnemonic_response.get_bip39_entropy(); + let mnemonic_response = self.generate_mnemonic_impl(())?; + let mnemonic_str = mnemonic_response.mnemonic.to_string(); + let bip39_entropy = mnemonic_response.bip39_entropy; // Generate a new account using this mnemonic. - let mut account_key_request = api::GetAccountKeyFromMnemonicRequest::new(); - account_key_request.set_mnemonic(mnemonic_str); + let account_key_request = api::GetAccountKeyFromMnemonicRequest { + mnemonic: mnemonic_str, + ..Default::default() + }; let account_key_response = self.get_account_key_from_mnemonic_impl(account_key_request)?; - let account_key = AccountKey::try_from(account_key_response.get_account_key()) - .map_err(|err| rpc_internal_error("account_key.try_from", err, &self.logger))?; + let account_key = AccountKey::try_from( + account_key_response + .account_key + .as_ref() + .unwrap_or(&Default::default()), + ) + .map_err(|err| rpc_internal_error("account_key.try_from", err, &self.logger))?; // The outlay we are sending the money to. let outlay = Outlay { @@ -1457,34 +1482,36 @@ impl Result { // Get TxProposal from request. - let tx_proposal = TxProposal::try_from(request.get_tx_proposal()) - .map_err(|err| rpc_internal_error("tx_proposal.try_from", err, &self.logger))?; + let tx_proposal = + TxProposal::try_from(request.tx_proposal.as_ref().unwrap_or(&Default::default())) + .map_err(|err| rpc_internal_error("tx_proposal.try_from", err, &self.logger))?; // Submit to network. let block_height = self @@ -1658,15 +1700,14 @@ impl = tx_proposal @@ -1696,16 +1737,17 @@ impl outlay_index { - receiver_tx_receipt.set_confirmation_number( - tx_proposal.outlay_confirmation_numbers[outlay_index].to_vec(), - ); + receiver_tx_receipt.confirmation_number = + tx_proposal.outlay_confirmation_numbers[outlay_index].to_vec(); } Ok(receiver_tx_receipt) @@ -1713,15 +1755,15 @@ impl, RpcStatus>>()?; // Return response. - let mut response = api::SubmitTxResponse::new(); - response.set_sender_tx_receipt(sender_tx_receipt); - response.set_receiver_tx_receipt_list(RepeatedField::from_vec(receiver_tx_receipts)); - Ok(response) + Ok(api::SubmitTxResponse { + sender_tx_receipt: Some(sender_tx_receipt), + receiver_tx_receipt_list: receiver_tx_receipts, + }) } fn get_ledger_info_impl( &mut self, - _request: api::Empty, + _request: (), ) -> Result { let num_blocks = self .ledger_db @@ -1733,10 +1775,10 @@ impl Result { - let mut response = api::GetBlockResponse::new(); - let block_data = self .ledger_db .get_block_data(request.block) .map_err(|err| rpc_internal_error("ledger_db.get_block_data", err, &self.logger))?; - response.set_block(mc_consensus_api::blockchain::Block::from( - block_data.block(), - )); - - for key_image in &block_data.contents().key_images { - response - .mut_key_images() - .push(mc_consensus_api::external::KeyImage::from(key_image)); - } - for output in &block_data.contents().outputs { - response - .mut_txos() - .push(mc_consensus_api::external::TxOut::from(output)); - } + let mut response = api::GetBlockResponse { + block: Some(mc_consensus_api::blockchain::Block::from( + block_data.block(), + )), + key_images: block_data + .contents() + .key_images + .iter() + .map(Into::into) + .collect(), + txos: block_data + .contents() + .outputs + .iter() + .map(Into::into) + .collect(), + ..Default::default() + }; if let Some(watcher_db) = self.watcher_db.as_ref() { let signatures = watcher_db @@ -1791,29 +1835,23 @@ impl Result { + fn get_latest_block_impl(&mut self, _request: ()) -> Result { let num_blocks = self .ledger_db .num_blocks() @@ -1821,7 +1859,6 @@ impl Result { + let sender_tx_receipt = request.sender_tx_receipt.unwrap_or_default(); + let receiver_tx_receipt_list = request.receiver_tx_receipt_list; // Sanity-test the request. - if request - .get_sender_tx_receipt() - .get_key_image_list() - .is_empty() - { + if sender_tx_receipt.key_image_list.is_empty() { return Err(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, "sender_receipt.key_image_list".into(), )); } - if request.get_sender_tx_receipt().tombstone == 0 { + if sender_tx_receipt.tombstone == 0 { return Err(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, "sender_receipt.tombstone".into(), @@ -1903,7 +1936,7 @@ impl = request - .get_sender_tx_receipt() - .get_key_image_list() + let key_images: Vec = sender_tx_receipt + .key_image_list .iter() .map(|key_image| { KeyImage::try_from(key_image) @@ -1922,11 +1954,10 @@ impl, RpcStatus>>()?; // Get list of tx_public_keys from the request. - let compressed_pubkeys: Vec = request - .get_receiver_tx_receipt_list() + let compressed_pubkeys: Vec = receiver_tx_receipt_list .iter() .map(|r| { - RistrettoPublic::try_from(r.get_tx_public_key()) + RistrettoPublic::try_from(r.tx_public_key.as_ref().unwrap_or(&Default::default())) .map_err(|err| { rpc_internal_error("RistrettoPublic.try_from", err, &self.logger) }) @@ -1964,15 +1995,15 @@ impl= request.get_sender_tx_receipt().tombstone { - let mut response = api::GetTxStatusAsSenderResponse::new(); - response.set_status(api::TxStatus::TombstoneBlockExceeded); - return Ok(response); + if num_blocks >= sender_tx_receipt.tombstone { + return Ok(api::GetTxStatusAsSenderResponse { + status: api::TxStatus::TombstoneBlockExceeded.into(), + }); } // No key images in ledger, tombstone block not yet exceeded. - let mut response = api::GetTxStatusAsSenderResponse::new(); - response.set_status(api::TxStatus::Unknown); - Ok(response) + Ok(api::GetTxStatusAsSenderResponse { + status: api::TxStatus::Unknown.into(), + }) } fn get_tx_status_as_receiver_impl( @@ -2044,14 +2075,27 @@ impl Result { // Sanity-test the request. - if request.get_receipt().get_tx_out_hash().len() != 32 { + if request + .receipt + .as_ref() + .unwrap_or(&Default::default()) + .tx_out_hash + .len() + != 32 + { return Err(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, "receipt.tx_out_hash".into(), )); } - if request.get_receipt().tombstone == 0 { + if request + .receipt + .as_ref() + .unwrap_or(&Default::default()) + .tombstone + == 0 + { return Err(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, "receipt.tombstone".into(), @@ -2060,12 +2104,18 @@ impl { // If a monitor ID was given then validate the confirmation number - match request.get_monitor_id().len() { + match request.monitor_id.len() { 0 => { /* no monitor ID given */ } 32 => { let monitor_id = @@ -2084,18 +2134,28 @@ impl { @@ -2131,9 +2197,9 @@ impl {} Err(err) => { @@ -2151,16 +2217,22 @@ impl= request.get_receipt().tombstone { - let mut response = api::GetTxStatusAsReceiverResponse::new(); - response.set_status(api::TxStatus::TombstoneBlockExceeded); - return Ok(response); + if num_blocks + >= request + .receipt + .as_ref() + .unwrap_or(&Default::default()) + .tombstone + { + return Ok(api::GetTxStatusAsReceiverResponse { + status: api::TxStatus::TombstoneBlockExceeded.into(), + }); } // Tx out not in ledger, tombstone block not yet exceeded. - let mut response = api::GetTxStatusAsReceiverResponse::new(); - response.set_status(api::TxStatus::Unknown); - Ok(response) + Ok(api::GetTxStatusAsReceiverResponse { + status: api::TxStatus::Unknown.into(), + }) } fn get_processed_block_impl( @@ -2189,41 +2261,47 @@ impl, _>>()?; // Return response - let mut response = api::GetProcessedBlockResponse::new(); - response.set_tx_outs(RepeatedField::from_vec(processed_tx_outs)); - Ok(response) + Ok(api::GetProcessedBlockResponse { + tx_outs: processed_tx_outs, + }) } fn get_block_index_by_tx_pub_key_impl( &mut self, request: api::GetBlockIndexByTxPubKeyRequest, ) -> Result { - let tx_public_key = RistrettoPublic::try_from(request.get_tx_public_key()) - .map_err(|err| rpc_internal_error("RistrettoPublic.try_from", err, &self.logger))?; + let tx_public_key = RistrettoPublic::try_from( + request + .tx_public_key + .as_ref() + .unwrap_or(&Default::default()), + ) + .map_err(|err| rpc_internal_error("RistrettoPublic.try_from", err, &self.logger))?; let compressed_tx_public_key = CompressedRistrettoPublic::from(&tx_public_key); @@ -2249,9 +2327,7 @@ impl = request - .get_outlay_list() + .outlay_list .iter() .map(|outlay_proto| { Outlay::try_from(outlay_proto) @@ -2372,8 +2447,11 @@ impl Result { // Sanity check. - if request.get_amount() == 0 { + if request.amount == 0 { return Err(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, "amount".into(), @@ -2422,33 +2501,38 @@ impl Result { let network_state = self.network_state.read().expect("lock poisoned"); let num_blocks = self @@ -2480,48 +2564,41 @@ impl Result { + ) -> Result<(), RpcStatus> { // Check if the database is unlocked and allowing this operation. if !self.mobilecoind_db.is_unlocked() { return Err(RpcStatus::with_message( @@ -2532,15 +2609,15 @@ impl Result { + fn unlock_db_impl(&mut self, request: api::UnlockDbRequest) -> Result<(), RpcStatus> { if self.mobilecoind_db.is_unlocked() { return Err(RpcStatus::with_message( RpcStatusCode::INTERNAL, @@ -2549,7 +2626,7 @@ impl (u64, TimestampResultCode) { @@ -2571,13 +2648,15 @@ impl Result { - let mut result = TxOutResult::new(); - result.set_tx_out_pubkey(tx_out_pubkey.into()); + let mut result = TxOutResult { + tx_out_pubkey: Some(tx_out_pubkey.into()), + ..Default::default() + }; let tx_out_index = match self.ledger_db.get_tx_out_index_by_public_key(tx_out_pubkey) { Ok(index) => index, Err(LedgerError::NotFound) => { - result.result_code = TxOutResultCode::NotFound; + result.result_code = TxOutResultCode::NotFound.into(); return Ok(result); } Err(err) => { @@ -2585,7 +2664,7 @@ impl ( impl MobilecoindApi for ServiceApi { @@ -2621,8 +2700,8 @@ macro_rules! build_api { fn $service_function_name( &mut self, ctx: RpcContext, - request: api::$service_request_type, - sink: UnarySink, + request: $service_request_type, + sink: UnarySink<$service_response_type>, ) { let logger = rpc_logger(&ctx, &self.logger); send_result( @@ -2639,74 +2718,74 @@ macro_rules! build_api { build_api! { // Monitors - add_monitor AddMonitorRequest AddMonitorResponse add_monitor_impl, - remove_monitor RemoveMonitorRequest Empty remove_monitor_impl, - get_monitor_list Empty GetMonitorListResponse get_monitor_list_impl, - get_monitor_status GetMonitorStatusRequest GetMonitorStatusResponse get_monitor_status_impl, - get_unspent_tx_out_list GetUnspentTxOutListRequest GetUnspentTxOutListResponse get_unspent_tx_out_list_impl, - get_all_unspent_tx_out GetAllUnspentTxOutRequest GetAllUnspentTxOutResponse get_all_unspent_tx_out_impl, + add_monitor, api::AddMonitorRequest, api::AddMonitorResponse, add_monitor_impl, + remove_monitor, api::RemoveMonitorRequest, (), remove_monitor_impl, + get_monitor_list, (), api::GetMonitorListResponse, get_monitor_list_impl, + get_monitor_status, api::GetMonitorStatusRequest, api::GetMonitorStatusResponse, get_monitor_status_impl, + get_unspent_tx_out_list, api::GetUnspentTxOutListRequest, api::GetUnspentTxOutListResponse, get_unspent_tx_out_list_impl, + get_all_unspent_tx_out, api::GetAllUnspentTxOutRequest, api::GetAllUnspentTxOutResponse, get_all_unspent_tx_out_impl, // Utilities - generate_root_entropy Empty GenerateRootEntropyResponse generate_root_entropy_impl, - generate_mnemonic Empty GenerateMnemonicResponse generate_mnemonic_impl, - get_account_key_from_root_entropy GetAccountKeyFromRootEntropyRequest GetAccountKeyResponse get_account_key_from_root_entropy_impl, - get_account_key_from_mnemonic GetAccountKeyFromMnemonicRequest GetAccountKeyResponse get_account_key_from_mnemonic_impl, - get_public_address GetPublicAddressRequest GetPublicAddressResponse get_public_address_impl, - get_short_address_hash GetShortAddressHashRequest GetShortAddressHashResponse get_short_address_hash_impl, - validate_authenticated_sender_memo ValidateAuthenticatedSenderMemoRequest ValidateAuthenticatedSenderMemoResponse validate_authenticated_sender_memo_impl, - tx_out_view_key_match TxOutViewKeyMatchRequest TxOutViewKeyMatchResponse tx_out_view_key_match_impl, + generate_root_entropy, (), api::GenerateRootEntropyResponse, generate_root_entropy_impl, + generate_mnemonic, (), api::GenerateMnemonicResponse, generate_mnemonic_impl, + get_account_key_from_root_entropy, api::GetAccountKeyFromRootEntropyRequest, api::GetAccountKeyResponse, get_account_key_from_root_entropy_impl, + get_account_key_from_mnemonic, api::GetAccountKeyFromMnemonicRequest, api::GetAccountKeyResponse, get_account_key_from_mnemonic_impl, + get_public_address, api::GetPublicAddressRequest, api::GetPublicAddressResponse, get_public_address_impl, + get_short_address_hash, api::GetShortAddressHashRequest, api::GetShortAddressHashResponse, get_short_address_hash_impl, + validate_authenticated_sender_memo, api::ValidateAuthenticatedSenderMemoRequest, api::ValidateAuthenticatedSenderMemoResponse, validate_authenticated_sender_memo_impl, + tx_out_view_key_match, api::TxOutViewKeyMatchRequest, api::TxOutViewKeyMatchResponse, tx_out_view_key_match_impl, // b58 codes - parse_request_code ParseRequestCodeRequest ParseRequestCodeResponse parse_request_code_impl, - create_request_code CreateRequestCodeRequest CreateRequestCodeResponse create_request_code_impl, - parse_transfer_code ParseTransferCodeRequest ParseTransferCodeResponse parse_transfer_code_impl, - create_transfer_code CreateTransferCodeRequest CreateTransferCodeResponse create_transfer_code_impl, - parse_address_code ParseAddressCodeRequest ParseAddressCodeResponse parse_address_code_impl, - create_address_code CreateAddressCodeRequest CreateAddressCodeResponse create_address_code_impl, + parse_request_code, api::ParseRequestCodeRequest, api::ParseRequestCodeResponse, parse_request_code_impl, + create_request_code, api::CreateRequestCodeRequest, api::CreateRequestCodeResponse, create_request_code_impl, + parse_transfer_code, api::ParseTransferCodeRequest, api::ParseTransferCodeResponse, parse_transfer_code_impl, + create_transfer_code, api::CreateTransferCodeRequest, api::CreateTransferCodeResponse, create_transfer_code_impl, + parse_address_code, api::ParseAddressCodeRequest, api::ParseAddressCodeResponse, parse_address_code_impl, + create_address_code, api::CreateAddressCodeRequest, api::CreateAddressCodeResponse, create_address_code_impl, // Transactions - get_mixins GetMixinsRequest GetMixinsResponse get_mixins_impl, - get_membership_proofs GetMembershipProofsRequest GetMembershipProofsResponse get_membership_proofs_impl, - generate_tx GenerateTxRequest GenerateTxResponse generate_tx_impl, - generate_optimization_tx GenerateOptimizationTxRequest GenerateOptimizationTxResponse generate_optimization_tx_impl, - generate_transfer_code_tx GenerateTransferCodeTxRequest GenerateTransferCodeTxResponse generate_transfer_code_tx_impl, - generate_tx_from_tx_out_list GenerateTxFromTxOutListRequest GenerateTxFromTxOutListResponse generate_tx_from_tx_out_list_impl, - generate_burn_redemption_tx GenerateBurnRedemptionTxRequest GenerateBurnRedemptionTxResponse generate_burn_redemption_tx_impl, - submit_tx SubmitTxRequest SubmitTxResponse submit_tx_impl, + get_mixins, api::GetMixinsRequest, api::GetMixinsResponse, get_mixins_impl, + get_membership_proofs, api::GetMembershipProofsRequest, api::GetMembershipProofsResponse, get_membership_proofs_impl, + generate_tx, api::GenerateTxRequest, api::GenerateTxResponse, generate_tx_impl, + generate_optimization_tx, api::GenerateOptimizationTxRequest, api::GenerateOptimizationTxResponse, generate_optimization_tx_impl, + generate_transfer_code_tx, api::GenerateTransferCodeTxRequest, api::GenerateTransferCodeTxResponse, generate_transfer_code_tx_impl, + generate_tx_from_tx_out_list, api::GenerateTxFromTxOutListRequest, api::GenerateTxFromTxOutListResponse, generate_tx_from_tx_out_list_impl, + generate_burn_redemption_tx, api::GenerateBurnRedemptionTxRequest, api::GenerateBurnRedemptionTxResponse, generate_burn_redemption_tx_impl, + submit_tx, api::SubmitTxRequest, api::SubmitTxResponse, submit_tx_impl, // Signed contingent inputs - generate_swap GenerateSwapRequest GenerateSwapResponse generate_swap_impl, - generate_mixed_tx GenerateMixedTxRequest GenerateMixedTxResponse generate_mixed_tx_impl, + generate_swap, api::GenerateSwapRequest, api::GenerateSwapResponse, generate_swap_impl, + generate_mixed_tx, api::GenerateMixedTxRequest, api::GenerateMixedTxResponse, generate_mixed_tx_impl, // Databases - get_ledger_info Empty GetLedgerInfoResponse get_ledger_info_impl, - get_block_info GetBlockInfoRequest GetBlockInfoResponse get_block_info_impl, - get_block GetBlockRequest GetBlockResponse get_block_impl, - get_latest_block Empty GetBlockResponse get_latest_block_impl, - get_blocks_data GetBlocksDataRequest GetBlocksDataResponse get_blocks_data_impl, - get_tx_status_as_sender SubmitTxResponse GetTxStatusAsSenderResponse get_tx_status_as_sender_impl, - get_tx_status_as_receiver GetTxStatusAsReceiverRequest GetTxStatusAsReceiverResponse get_tx_status_as_receiver_impl, - get_processed_block GetProcessedBlockRequest GetProcessedBlockResponse get_processed_block_impl, - get_block_index_by_tx_pub_key GetBlockIndexByTxPubKeyRequest GetBlockIndexByTxPubKeyResponse get_block_index_by_tx_pub_key_impl, - get_tx_out_results_by_pub_key GetTxOutResultsByPubKeyRequest GetTxOutResultsByPubKeyResponse get_tx_out_results_by_pub_key_impl, + get_ledger_info, (), api::GetLedgerInfoResponse, get_ledger_info_impl, + get_block_info, api::GetBlockInfoRequest, api::GetBlockInfoResponse, get_block_info_impl, + get_block, api::GetBlockRequest, api::GetBlockResponse, get_block_impl, + get_latest_block, (), api::GetBlockResponse, get_latest_block_impl, + get_blocks_data, api::GetBlocksDataRequest, api::GetBlocksDataResponse, get_blocks_data_impl, + get_tx_status_as_sender, api::SubmitTxResponse, api::GetTxStatusAsSenderResponse, get_tx_status_as_sender_impl, + get_tx_status_as_receiver, api::GetTxStatusAsReceiverRequest, api::GetTxStatusAsReceiverResponse, get_tx_status_as_receiver_impl, + get_processed_block, api::GetProcessedBlockRequest, api::GetProcessedBlockResponse, get_processed_block_impl, + get_block_index_by_tx_pub_key, api::GetBlockIndexByTxPubKeyRequest, api::GetBlockIndexByTxPubKeyResponse, get_block_index_by_tx_pub_key_impl, + get_tx_out_results_by_pub_key, api::GetTxOutResultsByPubKeyRequest, api::GetTxOutResultsByPubKeyResponse, get_tx_out_results_by_pub_key_impl, // Convenience calls - get_balance GetBalanceRequest GetBalanceResponse get_balance_impl, - send_payment SendPaymentRequest SendPaymentResponse send_payment_impl, - pay_address_code PayAddressCodeRequest SendPaymentResponse pay_address_code_impl, + get_balance, api::GetBalanceRequest, api::GetBalanceResponse, get_balance_impl, + send_payment, api::SendPaymentRequest, api::SendPaymentResponse, send_payment_impl, + pay_address_code, api::PayAddressCodeRequest, api::SendPaymentResponse, pay_address_code_impl, // Network status - get_network_status Empty GetNetworkStatusResponse get_network_status_impl, + get_network_status, (), api::GetNetworkStatusResponse, get_network_status_impl, // Database encryption - set_db_password SetDbPasswordRequest Empty set_db_password_impl, - unlock_db UnlockDbRequest Empty unlock_db_impl, + set_db_password, api::SetDbPasswordRequest, (), set_db_password_impl, + unlock_db, api::UnlockDbRequest, (), unlock_db_impl, - get_version Empty MobilecoindVersionResponse get_version_impl, + get_version, (), api::MobilecoindVersionResponse, get_version_impl, } #[cfg(test)] -#[allow(clippy::needless_collect)] +#[allow(clippy::needless_collect, deprecated)] mod test { use super::*; use crate::{ @@ -2724,6 +2803,7 @@ mod test { use mc_fog_report_validation::{FullyValidatedFogPubkey, MockFogPubkeyResolver}; use mc_fog_report_validation_test_utils::MockFogResolver; use mc_ledger_db::test_utils::add_txos_and_key_images_to_ledger; + use mc_mobilecoind_api::{decoded_memo, transaction_memo_rth}; use mc_rand::RngCore; use mc_transaction_builder::{ EmptyMemoBuilder, MemoBuilder, RTHMemoBuilder, TransactionBuilder, TxOutContext, @@ -2763,11 +2843,13 @@ mod test { ) .expect("failed to create data"); - let mut request = api::AddMonitorRequest::new(); - request.set_account_key(mc_api::external::AccountKey::from(&data.account_key)); - request.set_first_subaddress(data.first_subaddress); - request.set_num_subaddresses(data.num_subaddresses); - request.set_first_block(data.first_block); + let request = api::AddMonitorRequest { + account_key: Some(mc_api::external::AccountKey::from(&data.account_key)), + first_subaddress: data.first_subaddress, + num_subaddresses: data.num_subaddresses, + first_block: data.first_block, + ..Default::default() + }; // Send request. let response = client.add_monitor(&request).expect("failed to add monitor"); @@ -2830,8 +2912,9 @@ mod test { // Remove all the monitors we added. for id in monitor_ids { - let mut request = api::RemoveMonitorRequest::new(); - request.set_monitor_id(id.to_vec()); + let request = api::RemoveMonitorRequest { + monitor_id: id.to_vec(), + }; client .remove_monitor(&request) .unwrap_or_else(|_| panic!("failed to remove monitor {id}")); @@ -2870,7 +2953,7 @@ mod test { // Ask the api for a list of all monitors. let response = client - .get_monitor_list(&api::Empty::new()) + .get_monitor_list(&()) .expect("failed to get monitor list"); let monitor_id_list: Vec = response @@ -2918,8 +3001,9 @@ mod test { wait_for_monitors(&mobilecoind_db, &ledger_db, &logger); // Query monitor status. - let mut request = api::GetMonitorStatusRequest::new(); - request.set_monitor_id(id.to_vec()); + let request = api::GetMonitorStatusRequest { + monitor_id: id.to_vec(), + }; let response = client .get_monitor_status(&request) @@ -2940,15 +3024,17 @@ mod test { // return an error. mobilecoind_db.remove_monitor(&id).unwrap(); - let mut request = api::GetMonitorStatusRequest::new(); - request.set_monitor_id(id.to_vec()); + let request = api::GetMonitorStatusRequest { + monitor_id: id.to_vec(), + }; assert!(client.get_monitor_status(&request).is_err()); - let request = api::GetMonitorStatusRequest::new(); + let request = api::GetMonitorStatusRequest::default(); assert!(client.get_monitor_status(&request).is_err()); - let mut request = api::GetMonitorStatusRequest::new(); - request.set_monitor_id(vec![3; 3]); + let request = api::GetMonitorStatusRequest { + monitor_id: vec![3; 3], + }; assert!(client.get_monitor_status(&request).is_err()); } @@ -3000,9 +3086,11 @@ mod test { wait_for_monitors(&mobilecoind_db, &ledger_db, &logger); // Query for unspent tx outs for a subaddress that did not receive any tx outs. - let mut request = api::GetUnspentTxOutListRequest::new(); - request.set_monitor_id(id.to_vec()); - request.set_subaddress_index(1); + let request = api::GetUnspentTxOutListRequest { + monitor_id: id.to_vec(), + subaddress_index: 1, + ..Default::default() + }; let response = client .get_unspent_tx_out_list(&request) @@ -3011,9 +3099,11 @@ mod test { assert_eq!(response.output_list.to_vec(), vec![]); // Query with the correct subaddress index. - let mut request = api::GetUnspentTxOutListRequest::new(); - request.set_monitor_id(id.to_vec()); - request.set_subaddress_index(0); + let mut request = api::GetUnspentTxOutListRequest { + monitor_id: id.to_vec(), + subaddress_index: 0, + ..Default::default() + }; let response = client .get_unspent_tx_out_list(&request) @@ -3083,7 +3173,7 @@ mod test { ); // Try with the non-MOB token id. - request.set_token_id(2); + request.token_id = 2; let response = client .get_unspent_tx_out_list(&request) .expect("failed to get unspent tx out list"); @@ -3167,8 +3257,9 @@ mod test { wait_for_monitors(&mobilecoind_db, &ledger_db, &logger); // Query with the known id - let mut request = api::GetAllUnspentTxOutRequest::new(); - request.set_monitor_id(id.to_vec()); + let request = api::GetAllUnspentTxOutRequest { + monitor_id: id.to_vec(), + }; let response = client .get_all_unspent_tx_out(&request) @@ -3247,10 +3338,8 @@ mod test { get_testing_environment(BLOCK_VERSION, 3, &[], &[], logger, &mut rng); // call get entropy - let response = client - .generate_root_entropy(&api::Empty::default()) - .unwrap(); - let entropy = response.get_root_entropy().to_vec(); + let response = client.generate_root_entropy(&()).unwrap(); + let entropy = response.root_entropy; assert_eq!(entropy.len(), 32); assert_ne!(entropy, vec![0; 32]); } @@ -3264,8 +3353,8 @@ mod test { get_testing_environment(BLOCK_VERSION, 3, &[], &[], logger, &mut rng); // call get entropy - let response = client.generate_mnemonic(&api::Empty::default()).unwrap(); - let mnemonic_str = response.get_mnemonic(); + let response = client.generate_mnemonic(&()).unwrap(); + let mnemonic_str = &response.mnemonic; assert_ne!(mnemonic_str, ""); // Should be a valid mnemonic. @@ -3273,7 +3362,7 @@ mod test { Mnemonic::from_phrase(mnemonic_str, Language::English).expect("invalid mnemonic_str"); assert_eq!(mnemonic.entropy().len(), 32); - assert_eq!(mnemonic.entropy(), response.get_bip39_entropy()); + assert_eq!(mnemonic.entropy(), response.bip39_entropy); } #[test_with_logger] @@ -3294,23 +3383,26 @@ mod test { AccountKey::from(key) }; - let mut request = api::GetAccountKeyFromMnemonicRequest::new(); - request.set_mnemonic(mnemonic_str.to_string()); - request.set_account_index(666); + let request = api::GetAccountKeyFromMnemonicRequest { + mnemonic: mnemonic_str.to_string(), + account_index: 666, + }; let response = client.get_account_key_from_mnemonic(&request).unwrap(); assert_eq!( expected_account_key, - AccountKey::try_from(response.get_account_key()).unwrap(), + AccountKey::try_from(response.account_key.as_ref().unwrap()).unwrap(), ); // Calling with no mnemonic or invalid mnemonic should error. - let request = api::GetAccountKeyFromMnemonicRequest::new(); + let request = api::GetAccountKeyFromMnemonicRequest::default(); assert!(client.get_account_key_from_mnemonic(&request).is_err()); - let mut request = api::GetAccountKeyFromMnemonicRequest::new(); - request.set_mnemonic("lol".to_string()); + let request = api::GetAccountKeyFromMnemonicRequest { + mnemonic: "lol".to_string(), + ..Default::default() + }; assert!(client.get_account_key_from_mnemonic(&request).is_err()); } @@ -3327,23 +3419,25 @@ mod test { let root_id = RootIdentity::from(&root_entropy); let account_key = AccountKey::from(&root_id); - let mut request = api::GetAccountKeyFromRootEntropyRequest::new(); - request.set_root_entropy(root_entropy.to_vec()); + let request = api::GetAccountKeyFromRootEntropyRequest { + root_entropy: root_entropy.to_vec(), + }; let response = client.get_account_key_from_root_entropy(&request).unwrap(); assert_eq!( account_key, - AccountKey::try_from(response.get_account_key()).unwrap(), + AccountKey::try_from(response.account_key.as_ref().unwrap()).unwrap(), ); // Calling with no root entropy or invalid root entropy should error. - let request = api::GetAccountKeyFromRootEntropyRequest::new(); + let request = api::GetAccountKeyFromRootEntropyRequest::default(); assert!(client.get_account_key_from_root_entropy(&request).is_err()); let root_entropy = [123u8; 31]; - let mut request = api::GetAccountKeyFromRootEntropyRequest::new(); - request.set_root_entropy(root_entropy.to_vec()); + let request = api::GetAccountKeyFromRootEntropyRequest { + root_entropy: root_entropy.to_vec(), + }; assert!(client.get_account_key_from_root_entropy(&request).is_err()); } @@ -3368,39 +3462,46 @@ mod test { let id = mobilecoind_db.add_monitor(&data).unwrap(); // Call get public address. - let mut request = api::GetPublicAddressRequest::new(); - request.set_monitor_id(id.to_vec()); - request.set_subaddress_index(10); + let request = api::GetPublicAddressRequest { + monitor_id: id.to_vec(), + subaddress_index: 10, + }; let response = client.get_public_address(&request).unwrap(); assert_eq!( - PublicAddress::try_from(response.get_public_address()).unwrap(), + PublicAddress::try_from(response.public_address.as_ref().unwrap()).unwrap(), account_key.subaddress(10) ); // Test that the b58 encoding is correct - let mut wrapper = api::printable::PrintableWrapper::new(); - wrapper.set_public_address((&account_key.subaddress(10)).into()); + let wrapper = api::printable::PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress( + (&account_key.subaddress(10)).into(), + )), + }; let b58_code = wrapper.b58_encode().unwrap(); - assert_eq!(response.get_b58_code(), b58_code,); + assert_eq!(response.b58_code, b58_code,); // Subaddress that is out of index or an invalid monitor id should error. - let request = api::GetPublicAddressRequest::new(); + let request = api::GetPublicAddressRequest::default(); assert!(client.get_public_address(&request).is_err()); - let mut request = api::GetPublicAddressRequest::new(); - request.set_monitor_id(vec![3; 3]); - request.set_subaddress_index(10); + let request = api::GetPublicAddressRequest { + monitor_id: vec![3; 3], + subaddress_index: 10, + }; assert!(client.get_public_address(&request).is_err()); - let mut request = api::GetPublicAddressRequest::new(); - request.set_monitor_id(id.to_vec()); - request.set_subaddress_index(0); + let request = api::GetPublicAddressRequest { + monitor_id: id.to_vec(), + subaddress_index: 0, + }; assert!(client.get_public_address(&request).is_err()); - let mut request = api::GetPublicAddressRequest::new(); - request.set_monitor_id(id.to_vec()); - request.set_subaddress_index(1000); + let request = api::GetPublicAddressRequest { + monitor_id: id.to_vec(), + subaddress_index: 1000, + }; assert!(client.get_public_address(&request).is_err()); } @@ -3416,11 +3517,11 @@ mod test { let public_address = account_key.default_subaddress(); // Try to compute the short address hash - let mut request = api::GetShortAddressHashRequest::new(); + let mut request = api::GetShortAddressHashRequest::default(); // Check that an invalid request returns an error assert!(client.get_short_address_hash(&request).is_err()); - request.set_public_address((&public_address).into()); + request.public_address = Some((&public_address).into()); let response = client.get_short_address_hash(&request).unwrap(); // Test that the short address hash is correct @@ -3485,9 +3586,11 @@ mod test { wait_for_monitors(&mobilecoind_db, &ledger_db, &logger); // Bob should find the UTXO - let mut request = api::GetUnspentTxOutListRequest::new(); - request.set_monitor_id(id.to_vec()); - request.set_subaddress_index(10); + let request = api::GetUnspentTxOutListRequest { + monitor_id: id.to_vec(), + subaddress_index: 10, + ..Default::default() + }; let response = client.get_unspent_tx_out_list(&request).unwrap(); assert_eq!(response.output_list.len(), 1); @@ -3501,29 +3604,37 @@ mod test { assert_eq!(utxo.memo_payload.len(), 66); // The utxo should have been decoded successfully - let decoded = utxo.get_decoded_memo(); - assert!(!decoded.has_unknown_memo()); - assert!(decoded.has_authenticated_sender_memo()); - // The details should match to alice's hash and have a payment request id - let asm = decoded.get_authenticated_sender_memo(); - assert_eq!(asm.get_sender_hash(), alice_hash.as_ref()); - assert!(asm.has_payment_request_id()); - assert_eq!(asm.get_payment_request_id(), 99); - assert!(!asm.has_payment_intent_id()); + let decoded = utxo + .decoded_memo + .as_ref() + .unwrap() + .decoded_memo + .as_ref() + .unwrap(); + match decoded { + decoded_memo::DecodedMemo::AuthenticatedSenderMemo(asm) => { + // The details should match to alice's hash and have a payment request id + assert_eq!(asm.sender_hash, alice_hash.as_ref()); + assert_eq!(asm.payment_request_id, Some(99)); + assert_eq!(asm.payment_intent_id, None); + } + _ => panic!("Unexpected memo type"), + } // If we go fetch Alice's address via her hash, we should be able to validate // the memo. - let mut request = api::ValidateAuthenticatedSenderMemoRequest::new(); - request.set_monitor_id(id.to_vec()); - request.set_utxo(utxo.clone()); - request.set_sender((&alice_addr).into()); + let mut request = api::ValidateAuthenticatedSenderMemoRequest { + monitor_id: id.to_vec(), + utxo: Some(utxo.clone()), + sender: Some((&alice_addr).into()), + }; let response = client.validate_authenticated_sender_memo(&request).unwrap(); assert!(response.success); // If we don't use the right address during validation, then validation should // fail - request.set_sender((&bob_addr).into()); + request.sender = Some((&bob_addr).into()); let response = client.validate_authenticated_sender_memo(&request).unwrap(); assert!(!response.success); } @@ -3552,7 +3663,6 @@ mod test { let block = client .get_block(&api::GetBlockRequest { block: ledger_db.num_blocks().unwrap() - 1, - ..Default::default() }) .unwrap(); @@ -3562,16 +3672,15 @@ mod test { mc_api::external::RistrettoPrivate::from(recipient.view_private_key()); let resp = client .tx_out_view_key_match(&api::TxOutViewKeyMatchRequest { - txo: Some(block.txos[0].clone()).into(), - view_private_key: Some(view_private_key).into(), - ..Default::default() + txo: Some(block.txos[0].clone()), + view_private_key: Some(view_private_key), }) .unwrap(); assert!(resp.matched); assert_eq!(resp.value, 102030); assert_eq!(resp.token_id, 1); - assert_eq!(resp.get_shared_secret().data.len(), 32); + assert_eq!(resp.shared_secret.unwrap().data.len(), 32); // Try with an incorrect view private key let view_private_key = mc_api::external::RistrettoPrivate::from( @@ -3579,16 +3688,15 @@ mod test { ); let resp = client .tx_out_view_key_match(&api::TxOutViewKeyMatchRequest { - txo: Some(block.txos[0].clone()).into(), - view_private_key: Some(view_private_key).into(), - ..Default::default() + txo: Some(block.txos[0].clone()), + view_private_key: Some(view_private_key), }) .unwrap(); assert!(!resp.matched); assert_eq!(resp.value, 0); assert_eq!(resp.token_id, 0); - assert_eq!(resp.get_shared_secret().data.len(), 0); + assert_eq!(resp.shared_secret.unwrap().data.len(), 0); } #[test_with_logger] @@ -3602,11 +3710,13 @@ mod test { let (mut ledger_db, mobilecoind_db, client, _server, _server_conn_manager) = get_testing_environment(BlockVersion::THREE, 3, &[], &[], logger.clone(), &mut rng); - let mut request = api::GetAccountKeyFromMnemonicRequest::new(); - request.set_mnemonic("veteran leaf business lounge rocket prepare endorse town text reject nothing fuel earn solid want drum clog flip entire icon swallow birth loyal return".to_owned()); + let request = api::GetAccountKeyFromMnemonicRequest { + mnemonic: "veteran leaf business lounge rocket prepare endorse town text reject nothing fuel earn solid want drum clog flip entire icon swallow birth loyal return".to_owned(), + ..Default::default() + }; let response = client.get_account_key_from_mnemonic(&request).unwrap(); - let account_key = AccountKey::try_from(response.get_account_key()).unwrap(); + let account_key = AccountKey::try_from(response.account_key.as_ref().unwrap()).unwrap(); let data = MonitorData::new( account_key.clone(), @@ -3640,9 +3750,11 @@ mod test { wait_for_monitors(&mobilecoind_db, &ledger_db, &logger); // Bob should find the UTXO - let mut request = api::GetUnspentTxOutListRequest::new(); - request.set_monitor_id(id.to_vec()); - request.set_subaddress_index(0); + let request = api::GetUnspentTxOutListRequest { + monitor_id: id.to_vec(), + subaddress_index: 0, + ..Default::default() + }; let response = client.get_unspent_tx_out_list(&request).unwrap(); assert_eq!(response.output_list.len(), 1); @@ -3656,40 +3768,52 @@ mod test { assert_eq!(utxo.memo_payload.len(), 66); // The utxo should have been decoded successfully - let decoded = utxo.get_decoded_memo(); - assert!(!decoded.has_unknown_memo()); - assert!(decoded.has_authenticated_sender_memo()); - - // The details should have no payment request / intent id's - let asm = decoded.get_authenticated_sender_memo(); - assert!(!asm.has_payment_request_id()); - assert!(!asm.has_payment_intent_id()); - - // The short hash should match the expected value - // Get public address and hash from the b58 address - let sender_b58 = "WZKU1isCc7HUrNgpugWZaUhfLnsxsL3w3s3KaTu8AkwtCjqt9AEpWh3TNhG9dXjAKkL8qRput4paEeCAMS4PJ2E6r44ysPgMiStkjq2ons6GLaQqtVpYZQzxsbsLAtPkpXhKnxyjfHZxtD3CExzxxGUpnmZNjvdVJh1nByZaJ7pjhdPK81haNPqL7Kv7tk9m9A9segvmyZjzjkvFuHYrnWjgMwsfGpkkhtHz8yp3ftrUs"; - - let mut request = api::ParseAddressCodeRequest::new(); - request.set_b58_code(sender_b58.to_owned()); - let response = client.parse_address_code(&request).unwrap(); - let public_address = response.get_receiver(); - - let mut request = api::GetShortAddressHashRequest::new(); - request.set_public_address(public_address.clone()); - let response = client.get_short_address_hash(&request).unwrap(); - let expected_hash = response.get_hash(); - - assert_eq!(asm.get_sender_hash(), expected_hash); - - // If we go fetch Alice's address via her hash, we should be able to validate - // the memo. - let mut request = api::ValidateAuthenticatedSenderMemoRequest::new(); - request.set_monitor_id(id.to_vec()); - request.set_utxo(utxo.clone()); - request.set_sender(public_address.clone()); - - let response = client.validate_authenticated_sender_memo(&request).unwrap(); - assert!(response.success); + let decoded = utxo + .decoded_memo + .as_ref() + .unwrap() + .decoded_memo + .as_ref() + .unwrap(); + match decoded { + decoded_memo::DecodedMemo::AuthenticatedSenderMemo(asm) => { + // The details should have no payment request / intent id's + assert_eq!(asm.payment_request_id, None); + assert_eq!(asm.payment_intent_id, None); + + // The short hash should match the expected value + // Get public address and hash from the b58 address + let sender_b58 = "WZKU1isCc7HUrNgpugWZaUhfLnsxsL3w3s3KaTu8AkwtCjqt9AEpWh3TNhG9dXjAKkL8qRput4paEeCAMS4PJ2E6r44ysPgMiStkjq2ons6GLaQqtVpYZQzxsbsLAtPkpXhKnxyjfHZxtD3CExzxxGUpnmZNjvdVJh1nByZaJ7pjhdPK81haNPqL7Kv7tk9m9A9segvmyZjzjkvFuHYrnWjgMwsfGpkkhtHz8yp3ftrUs"; + + let request = api::ParseAddressCodeRequest { + b58_code: sender_b58.to_owned(), + }; + let response = client.parse_address_code(&request).unwrap(); + let public_address = response.receiver.unwrap(); + + let request = api::GetShortAddressHashRequest { + public_address: Some(public_address.clone()), + }; + let response = client.get_short_address_hash(&request).unwrap(); + let expected_hash = response.hash; + + assert_eq!(asm.sender_hash, expected_hash); + + // If we go fetch Alice's address via her hash, we should be able to validate + // the memo. + let request = api::ValidateAuthenticatedSenderMemoRequest { + monitor_id: id.to_vec(), + utxo: Some(utxo.clone()), + sender: Some(public_address.clone()), + }; + + let response = client.validate_authenticated_sender_memo(&request).unwrap(); + assert!(response.success); + } + _ => { + panic!("Expected AuthenticatedSenderMemo"); + } + } } #[test_with_logger] @@ -3701,7 +3825,7 @@ mod test { get_testing_environment(BLOCK_VERSION, 3, &[], &[], logger, &mut rng); // Call get ledger info. - let response = client.get_ledger_info(&api::Empty::new()).unwrap(); + let response = client.get_ledger_info(&()).unwrap(); assert_eq!(response.block_count, ledger_db.num_blocks().unwrap()); assert_eq!(response.txo_count, ledger_db.num_txos().unwrap()); } @@ -3715,17 +3839,16 @@ mod test { get_testing_environment(BLOCK_VERSION, 3, &[], &[], logger, &mut rng); // Call get block info for a valid block. - let mut request = api::GetBlockInfoRequest::new(); - request.set_block(0); + let request = api::GetBlockInfoRequest { block: 0 }; let response = client.get_block_info(&request).unwrap(); assert_eq!(response.key_image_count, 0); // test code does not generate any key images assert_eq!(response.txo_count, 3); // 3 recipients = 3 tx outs // Call with an invalid block number. - let mut request = api::GetBlockInfoRequest::new(); - request.set_block(ledger_db.num_blocks().unwrap()); - + let request = api::GetBlockInfoRequest { + block: ledger_db.num_blocks().unwrap(), + }; assert!(client.get_block_info(&request).is_err()); } @@ -3738,12 +3861,11 @@ mod test { get_testing_environment(BLOCK_VERSION, 3, &[], &[], logger, &mut rng); // Call get block info for a valid block. - let mut request = api::GetBlockRequest::new(); - request.set_block(0); + let request = api::GetBlockRequest { block: 0 }; let response = client.get_block(&request).unwrap(); assert_eq!( - Block::try_from(response.get_block()).unwrap(), + Block::try_from(response.block.as_ref().unwrap()).unwrap(), ledger_db.get_block(0).unwrap() ); // FIXME: Implement block signatures for mobilecoind and test @@ -3751,7 +3873,7 @@ mod test { assert_eq!(response.key_images.len(), 0); // test code does not generate // any key images assert_eq!( - response.timestamp_result_code, + response.timestamp_result_code(), mc_api::watcher::TimestampResultCode::WatcherDatabaseError ); // test code doesnt have a watcher } @@ -3768,14 +3890,14 @@ mod test { let response = client.get_latest_block(&Default::default()).unwrap(); assert_eq!( - Block::try_from(response.get_block()).unwrap(), + Block::try_from(response.block.as_ref().unwrap()).unwrap(), ledger_db.get_latest_block().unwrap(), ); // FIXME: Implement block signatures for mobilecoind and test assert_eq!(response.txos.len(), 3); // 3 recipients = 3 tx outs assert_eq!(response.key_images.len(), 1); assert_eq!( - response.timestamp_result_code, + response.timestamp_result_code(), mc_api::watcher::TimestampResultCode::WatcherDatabaseError ); // test code doesnt have a watcher } @@ -3789,16 +3911,17 @@ mod test { get_testing_environment(BLOCK_VERSION, 3, &[], &[], logger, &mut rng); // Call get block data - let mut request = api::GetBlocksDataRequest::new(); - request.set_blocks(vec![0, 2, 100, 1]); + let request = api::GetBlocksDataRequest { + blocks: vec![0, 2, 100, 1], + }; let response = client.get_blocks_data(&request).unwrap(); assert_eq!( - Block::try_from(response.get_latest_block()).unwrap(), + Block::try_from(response.latest_block.as_ref().unwrap()).unwrap(), ledger_db.get_latest_block().unwrap() ); - let blocks = response.get_results(); + let blocks = response.results; assert_eq!(blocks.len(), 4); assert!(blocks[0].found); assert!(blocks[1].found); @@ -3807,11 +3930,11 @@ mod test { assert_eq!( blocks.iter().map(|b| b.block_index).collect::>(), - request.get_blocks() + request.blocks ); assert_eq!( - blocks[0].get_block_data(), + blocks[0].block_data.as_ref().unwrap(), &ArchiveBlock::from(&ledger_db.get_block_data(0).unwrap()) ); } @@ -3843,57 +3966,57 @@ mod test { .unwrap(); let output = block.outputs[0].clone(); - let mut receiver_receipt = api::ReceiverTxReceipt::new(); - receiver_receipt.set_recipient(api::external::PublicAddress::from(&recipient)); - receiver_receipt - .set_tx_public_key(api::external::CompressedRistretto::from(&output.public_key)); - receiver_receipt.set_tx_out_hash(output.hash().into()); - receiver_receipt.set_tombstone(1); - // For this test, confirmation number is irrelevant, so left blank + let mut receiver_receipt = api::ReceiverTxReceipt { + recipient: Some(api::external::PublicAddress::from(&recipient)), + tx_public_key: Some(api::external::CompressedRistretto::from(&output.public_key)), + tx_out_hash: output.hash().into(), + tombstone: 1, + ..Default::default() + }; // A receipt with all key images in the same block is verified. { - let mut sender_receipt = api::SenderTxReceipt::new(); - sender_receipt.set_key_image_list(RepeatedField::from_vec(vec![ - (&KeyImage::from(1)).into(), - (&KeyImage::from(2)).into(), - (&KeyImage::from(3)).into(), - ])); - sender_receipt.set_tombstone(1); - - let mut request = api::SubmitTxResponse::new(); - request.set_sender_tx_receipt(sender_receipt); - request.set_receiver_tx_receipt_list(RepeatedField::from_vec(vec![ - receiver_receipt.clone() - ])); + let sender_receipt = api::SenderTxReceipt { + key_image_list: vec![ + (&KeyImage::from(1)).into(), + (&KeyImage::from(2)).into(), + (&KeyImage::from(3)).into(), + ], + tombstone: 1, + }; + + let request = api::SubmitTxResponse { + sender_tx_receipt: Some(sender_receipt), + receiver_tx_receipt_list: vec![receiver_receipt.clone()], + }; let response = client.get_tx_status_as_sender(&request).unwrap(); - assert_eq!(response.get_status(), api::TxStatus::Verified); + assert_eq!(response.status(), api::TxStatus::Verified); } // A receipt with an extra key image should be // TransactionFailureKeyImageBlockMismatch. { - let mut sender_receipt = api::SenderTxReceipt::new(); - sender_receipt.set_key_image_list(RepeatedField::from_vec(vec![ - (&KeyImage::from(1)).into(), - (&KeyImage::from(2)).into(), - (&KeyImage::from(3)).into(), - (&KeyImage::from(4)).into(), - ])); - sender_receipt.set_tombstone(1); - - let mut request = api::SubmitTxResponse::new(); - request.set_sender_tx_receipt(sender_receipt); - request.set_receiver_tx_receipt_list(RepeatedField::from_vec(vec![ - receiver_receipt.clone() - ])); + let sender_receipt = api::SenderTxReceipt { + key_image_list: vec![ + (&KeyImage::from(1)).into(), + (&KeyImage::from(2)).into(), + (&KeyImage::from(3)).into(), + (&KeyImage::from(4)).into(), + ], + tombstone: 1, + }; + + let request = api::SubmitTxResponse { + sender_tx_receipt: Some(sender_receipt), + receiver_tx_receipt_list: vec![receiver_receipt.clone()], + }; let response = client.get_tx_status_as_sender(&request).unwrap(); assert_eq!( - response.get_status(), + response.status(), api::TxStatus::TransactionFailureKeyImageBlockMismatch ); } @@ -3901,43 +4024,37 @@ mod test { // A receipt with key images that are not in the ledger is pending (unknown) if // its tombstone block has not been exceeded. { - let mut sender_receipt = api::SenderTxReceipt::new(); - sender_receipt.set_key_image_list(RepeatedField::from_vec(vec![ - (&KeyImage::from(4)).into(), - (&KeyImage::from(5)).into(), - ])); - sender_receipt.set_tombstone(ledger_db.num_blocks().unwrap() + 1); - - let mut request = api::SubmitTxResponse::new(); - request.set_sender_tx_receipt(sender_receipt); - request.set_receiver_tx_receipt_list(RepeatedField::from_vec(vec![ - receiver_receipt.clone() - ])); + let sender_receipt = api::SenderTxReceipt { + key_image_list: vec![(&KeyImage::from(4)).into(), (&KeyImage::from(5)).into()], + tombstone: ledger_db.num_blocks().unwrap() + 1, + }; + + let request = api::SubmitTxResponse { + sender_tx_receipt: Some(sender_receipt), + receiver_tx_receipt_list: vec![receiver_receipt.clone()], + }; let response = client.get_tx_status_as_sender(&request).unwrap(); - assert_eq!(response.get_status(), api::TxStatus::Unknown); + assert_eq!(response.status(), api::TxStatus::Unknown); } // A receipt with key images that are not in the ledger having its tombstone // block exceeded. { - let mut sender_receipt = api::SenderTxReceipt::new(); - sender_receipt.set_key_image_list(RepeatedField::from_vec(vec![ - (&KeyImage::from(4)).into(), - (&KeyImage::from(5)).into(), - ])); - sender_receipt.set_tombstone(ledger_db.num_blocks().unwrap()); - - let mut request = api::SubmitTxResponse::new(); - request.set_sender_tx_receipt(sender_receipt); - request.set_receiver_tx_receipt_list(RepeatedField::from_vec(vec![ - receiver_receipt.clone() - ])); + let sender_receipt = api::SenderTxReceipt { + key_image_list: vec![(&KeyImage::from(4)).into(), (&KeyImage::from(5)).into()], + tombstone: ledger_db.num_blocks().unwrap(), + }; + + let request = api::SubmitTxResponse { + sender_tx_receipt: Some(sender_receipt), + receiver_tx_receipt_list: vec![receiver_receipt.clone()], + }; let response = client.get_tx_status_as_sender(&request).unwrap(); - assert_eq!(response.get_status(), api::TxStatus::TombstoneBlockExceeded); + assert_eq!(response.status(), api::TxStatus::TombstoneBlockExceeded); } // Add another block to the ledger with different key images, to the same @@ -3955,24 +4072,23 @@ mod test { // A receipt with all the key_images in the ledger, but in different blocks, // should fail. { - let mut sender_receipt = api::SenderTxReceipt::new(); - sender_receipt.set_key_image_list(RepeatedField::from_vec(vec![ - (&KeyImage::from(1)).into(), - (&KeyImage::from(2)).into(), - (&KeyImage::from(4)).into(), - ])); - sender_receipt.set_tombstone(1); - - let mut request = api::SubmitTxResponse::new(); - request.set_sender_tx_receipt(sender_receipt); - request.set_receiver_tx_receipt_list(RepeatedField::from_vec(vec![ - receiver_receipt.clone() - ])); + let sender_receipt = api::SenderTxReceipt { + key_image_list: vec![ + (&KeyImage::from(1)).into(), + (&KeyImage::from(2)).into(), + (&KeyImage::from(4)).into(), + ], + tombstone: 1, + }; + let request = api::SubmitTxResponse { + sender_tx_receipt: Some(sender_receipt), + receiver_tx_receipt_list: vec![receiver_receipt.clone()], + }; let response = client.get_tx_status_as_sender(&request).unwrap(); assert_eq!( - response.get_status(), + response.status(), api::TxStatus::TransactionFailureKeyImageBlockMismatch ); } @@ -3984,37 +4100,32 @@ mod test { .unwrap(); let output2 = block2.outputs[0].clone(); - let mut receiver_receipt2 = api::ReceiverTxReceipt::new(); - receiver_receipt2.set_recipient(api::external::PublicAddress::from(&recipient)); - receiver_receipt2.set_tx_public_key(api::external::CompressedRistretto::from( - &output2.public_key, - )); - receiver_receipt2.set_tx_out_hash(output2.hash().into()); - receiver_receipt2.set_tombstone(1); - // For this test, confirmation number is irrelevant, so left blank + let receiver_receipt2 = api::ReceiverTxReceipt { + recipient: Some(api::external::PublicAddress::from(&recipient)), + tx_public_key: Some(api::external::CompressedRistretto::from( + &output2.public_key, + )), + tx_out_hash: output2.hash().into(), + tombstone: 1, + ..Default::default() + }; // A receiver receipt with multiple public keys in different blocks should fail { - let mut sender_receipt = api::SenderTxReceipt::new(); - sender_receipt.set_key_image_list(RepeatedField::from_vec(vec![ - (&KeyImage::from(1)).into(), - (&KeyImage::from(2)).into(), - ])); - sender_receipt.set_tombstone(1); - - let mut request = api::SubmitTxResponse::new(); - request.set_sender_tx_receipt(sender_receipt); - request - .mut_receiver_tx_receipt_list() - .push(receiver_receipt.clone()); - request - .mut_receiver_tx_receipt_list() - .push(receiver_receipt2); + let sender_receipt = api::SenderTxReceipt { + key_image_list: vec![(&KeyImage::from(1)).into(), (&KeyImage::from(2)).into()], + tombstone: 1, + }; + + let request = api::SubmitTxResponse { + sender_tx_receipt: Some(sender_receipt), + receiver_tx_receipt_list: vec![receiver_receipt.clone(), receiver_receipt2], + }; let response = client.get_tx_status_as_sender(&request).unwrap(); assert_eq!( - response.get_status(), + response.status(), api::TxStatus::PublicKeysInDifferentBlocks ); } @@ -4023,25 +4134,23 @@ mod test { // key_images which have should fail. // A receiver receipt with multiple public keys in different blocks should fail { - let mut sender_receipt = api::SenderTxReceipt::new(); - sender_receipt.set_key_image_list(RepeatedField::from_vec(vec![ - (&KeyImage::from(1)).into(), - (&KeyImage::from(4)).into(), - ])); - sender_receipt.set_tombstone(1); - - let mut request = api::SubmitTxResponse::new(); - request.set_sender_tx_receipt(sender_receipt); + let sender_receipt = api::SenderTxReceipt { + key_image_list: vec![(&KeyImage::from(1)).into(), (&KeyImage::from(4)).into()], + tombstone: 1, + }; // Modify the receiver_receipt to have a public key not in the ledger - receiver_receipt.set_tx_public_key(api::external::CompressedRistretto::from( + receiver_receipt.tx_public_key = Some(api::external::CompressedRistretto::from( &CompressedRistrettoPublic::from(&RistrettoPublic::from_random(&mut rng)), )); - request.set_receiver_tx_receipt_list(RepeatedField::from_vec(vec![receiver_receipt])); + let request = api::SubmitTxResponse { + sender_tx_receipt: Some(sender_receipt), + receiver_tx_receipt_list: vec![receiver_receipt], + }; let response = client.get_tx_status_as_sender(&request).unwrap(); assert_eq!( - response.get_status(), + response.status(), api::TxStatus::TransactionFailureKeyImageAlreadySpent ); } @@ -4057,11 +4166,15 @@ mod test { // A call with an invalid hash should fail { - let mut receipt = api::ReceiverTxReceipt::new(); - receipt.set_tombstone(1); + let receipt = api::ReceiverTxReceipt { + tombstone: 1, + ..Default::default() + }; - let mut request = api::GetTxStatusAsReceiverRequest::new(); - request.set_receipt(receipt); + let request = api::GetTxStatusAsReceiverRequest { + receipt: Some(receipt), + ..Default::default() + }; assert!(client.get_tx_status_as_receiver(&request).is_err()); } @@ -4071,15 +4184,19 @@ mod test { let tx_out = ledger_db.get_tx_out_by_index(1).unwrap(); let hash = tx_out.hash(); - let mut receipt = api::ReceiverTxReceipt::new(); - receipt.set_tx_out_hash(hash.to_vec()); - receipt.set_tombstone(1); + let receipt = api::ReceiverTxReceipt { + tx_out_hash: hash.to_vec(), + tombstone: 1, + ..Default::default() + }; - let mut request = api::GetTxStatusAsReceiverRequest::new(); - request.set_receipt(receipt); + let request = api::GetTxStatusAsReceiverRequest { + receipt: Some(receipt), + ..Default::default() + }; let response = client.get_tx_status_as_receiver(&request).unwrap(); - assert_eq!(response.get_status(), api::TxStatus::Verified); + assert_eq!(response.status(), api::TxStatus::Verified); } // A call with a hash thats is not in the ledger and hasn't exceeded tombstone @@ -4087,15 +4204,19 @@ mod test { { let hash = [0; 32]; - let mut receipt = api::ReceiverTxReceipt::new(); - receipt.set_tx_out_hash(hash.to_vec()); - receipt.set_tombstone(ledger_db.num_blocks().unwrap() + 1); + let receipt = api::ReceiverTxReceipt { + tx_out_hash: hash.to_vec(), + tombstone: ledger_db.num_blocks().unwrap() + 1, + ..Default::default() + }; - let mut request = api::GetTxStatusAsReceiverRequest::new(); - request.set_receipt(receipt); + let request = api::GetTxStatusAsReceiverRequest { + receipt: Some(receipt), + ..Default::default() + }; let response = client.get_tx_status_as_receiver(&request).unwrap(); - assert_eq!(response.get_status(), api::TxStatus::Unknown); + assert_eq!(response.status(), api::TxStatus::Unknown); } // A call with a hash thats is not in the ledger and has exceeded tombstone @@ -4103,15 +4224,19 @@ mod test { { let hash = [0; 32]; - let mut receipt = api::ReceiverTxReceipt::new(); - receipt.set_tx_out_hash(hash.to_vec()); - receipt.set_tombstone(ledger_db.num_blocks().unwrap()); + let receipt = api::ReceiverTxReceipt { + tx_out_hash: hash.to_vec(), + tombstone: ledger_db.num_blocks().unwrap(), + ..Default::default() + }; - let mut request = api::GetTxStatusAsReceiverRequest::new(); - request.set_receipt(receipt); + let request = api::GetTxStatusAsReceiverRequest { + receipt: Some(receipt), + ..Default::default() + }; let response = client.get_tx_status_as_receiver(&request).unwrap(); - assert_eq!(response.get_status(), api::TxStatus::TombstoneBlockExceeded); + assert_eq!(response.status(), api::TxStatus::TombstoneBlockExceeded); } // Now create a monitor for the receiver to test confirmation numbers @@ -4149,18 +4274,21 @@ mod test { { let hash = tx_out.hash(); - let mut receipt = api::ReceiverTxReceipt::new(); - receipt.set_tx_public_key(api::external::CompressedRistretto::from(&tx_out.public_key)); - receipt.set_tx_out_hash(hash.to_vec()); - receipt.set_tombstone(10); - receipt.set_confirmation_number(confirmation.to_vec()); + let receipt = api::ReceiverTxReceipt { + tx_public_key: Some(api::external::CompressedRistretto::from(&tx_out.public_key)), + tx_out_hash: hash.to_vec(), + tombstone: 10, + confirmation_number: confirmation.to_vec(), + ..Default::default() + }; - let mut request = api::GetTxStatusAsReceiverRequest::new(); - request.set_receipt(receipt); - request.set_monitor_id(monitor_id.to_vec()); + let request = api::GetTxStatusAsReceiverRequest { + receipt: Some(receipt), + monitor_id: monitor_id.to_vec(), + }; let response = client.get_tx_status_as_receiver(&request).unwrap(); - assert_eq!(response.get_status(), api::TxStatus::Verified); + assert_eq!(response.status(), api::TxStatus::Verified); } // A request with an a bad confirmation number and a monitor ID should return @@ -4168,21 +4296,21 @@ mod test { { let hash = tx_out.hash(); - let mut receipt = api::ReceiverTxReceipt::new(); - receipt.set_tx_public_key(api::external::CompressedRistretto::from(&tx_out.public_key)); - receipt.set_tx_out_hash(hash.to_vec()); - receipt.set_tombstone(10); - receipt.set_confirmation_number(vec![0u8; 32]); + let receipt = api::ReceiverTxReceipt { + tx_public_key: Some(api::external::CompressedRistretto::from(&tx_out.public_key)), + tx_out_hash: hash.to_vec(), + tombstone: 10, + confirmation_number: vec![0u8; 32], + ..Default::default() + }; - let mut request = api::GetTxStatusAsReceiverRequest::new(); - request.set_receipt(receipt); - request.set_monitor_id(monitor_id.to_vec()); + let request = api::GetTxStatusAsReceiverRequest { + receipt: Some(receipt), + monitor_id: monitor_id.to_vec(), + }; let response = client.get_tx_status_as_receiver(&request).unwrap(); - assert_eq!( - response.get_status(), - api::TxStatus::InvalidConfirmationNumber - ); + assert_eq!(response.status(), api::TxStatus::InvalidConfirmationNumber); } } @@ -4260,50 +4388,51 @@ mod test { // Query a bunch of blocks and verify the data. for block_index in 1..num_blocks { - let mut request = api::GetProcessedBlockRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); - request.set_block(block_index); + let request = api::GetProcessedBlockRequest { + monitor_id: monitor_id.to_vec(), + block: block_index, + }; let response = client .get_processed_block(&request) .expect("failed to get processed block"); // We expect one utxo per block for our monitor. - let tx_outs = response.get_tx_outs(); + let tx_outs = response.tx_outs; assert_eq!(tx_outs.len(), 1); let tx_out = &tx_outs[0]; let expected_utxo = &expected_utxos[block_index as usize]; - assert_eq!(tx_out.get_monitor_id().to_vec(), monitor_id.to_vec()); - assert_eq!( - tx_out.get_subaddress_index(), - expected_utxo.subaddress_index - ); + assert_eq!(tx_out.monitor_id.to_vec(), monitor_id.to_vec()); + assert_eq!(tx_out.subaddress_index, expected_utxo.subaddress_index); assert_eq!( - tx_out.get_public_key(), + tx_out.public_key.as_ref().unwrap(), &(&expected_utxo.tx_out.public_key).into(), ); - assert_eq!(tx_out.get_key_image(), &(&expected_utxo.key_image).into()); - assert_eq!(tx_out.value, expected_utxo.value); assert_eq!( - tx_out.get_direction(), - api::ProcessedTxOutDirection::Received, + tx_out.key_image.as_ref().unwrap(), + &(&expected_utxo.key_image).into() ); + assert_eq!(tx_out.value, expected_utxo.value); + assert_eq!(tx_out.direction(), api::ProcessedTxOutDirection::Received,); // test address code - let mut request = api::GetPublicAddressRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); - request.set_subaddress_index(expected_utxo.subaddress_index); + let request = api::GetPublicAddressRequest { + monitor_id: monitor_id.to_vec(), + subaddress_index: expected_utxo.subaddress_index, + }; let response = client.get_public_address(&request).unwrap(); - let public_address = PublicAddress::try_from(response.get_public_address()).unwrap(); + let public_address = + PublicAddress::try_from(response.public_address.as_ref().unwrap()).unwrap(); - let mut request = api::CreateAddressCodeRequest::new(); - request.set_receiver(mc_api::external::PublicAddress::from(&public_address)); + let request = api::CreateAddressCodeRequest { + receiver: Some(mc_api::external::PublicAddress::from(&public_address)), + }; let response = client.create_address_code(&request).unwrap(); - let b58_code = response.get_b58_code(); + let b58_code = response.b58_code; - assert_eq!(tx_out.get_address_code(), b58_code); + assert_eq!(tx_out.address_code, b58_code); assert_eq!(tx_out.token_id, *Mob::ID); } @@ -4327,15 +4456,16 @@ mod test { wait_for_monitors(&mobilecoind_db, &ledger_db, &logger); - let mut request = api::GetProcessedBlockRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); - request.set_block(num_blocks); + let request = api::GetProcessedBlockRequest { + monitor_id: monitor_id.to_vec(), + block: num_blocks, + }; let response = client .get_processed_block(&request) .expect("failed to get processed block"); - let tx_outs = response.get_tx_outs(); + let tx_outs = response.tx_outs; assert_eq!(tx_outs.len(), 2); let expected_utxos_by_key_image = HashMap::from_iter( @@ -4349,23 +4479,23 @@ mod test { for tx_out in tx_outs.iter() { let expected_utxo = expected_utxos_by_key_image .get( - &KeyImage::try_from(tx_out.get_key_image().get_data()) + &KeyImage::try_from(tx_out.key_image.as_ref().unwrap()) .expect("failed constructing key image"), ) .expect("failed getting expected utxo"); - assert_eq!(tx_out.get_monitor_id().to_vec(), monitor_id.to_vec()); + assert_eq!(tx_out.monitor_id.to_vec(), monitor_id.to_vec()); + assert_eq!(tx_out.subaddress_index, expected_utxo.subaddress_index); assert_eq!( - tx_out.get_subaddress_index(), - expected_utxo.subaddress_index + tx_out.public_key.as_ref().unwrap(), + &(&expected_utxo.tx_out.public_key).into(), ); assert_eq!( - tx_out.get_public_key(), - &(&expected_utxo.tx_out.public_key).into(), + tx_out.key_image.as_ref().unwrap(), + &(&expected_utxo.key_image).into() ); - assert_eq!(tx_out.get_key_image(), &(&expected_utxo.key_image).into()); assert_eq!(tx_out.value, expected_utxo.value); - assert_eq!(tx_out.get_direction(), api::ProcessedTxOutDirection::Spent,); + assert_eq!(tx_out.direction(), api::ProcessedTxOutDirection::Spent,); } } @@ -4384,46 +4514,47 @@ mod test { wait_for_monitors(&mobilecoind_db, &ledger_db, &logger); - let mut request = api::GetProcessedBlockRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); - request.set_block(num_blocks + 1); + let request = api::GetProcessedBlockRequest { + monitor_id: monitor_id.to_vec(), + block: num_blocks + 1, + }; let response = client .get_processed_block(&request) .expect("failed to get processed block"); - let tx_outs = response.get_tx_outs(); + let tx_outs = response.tx_outs; assert_eq!(tx_outs.len(), 1); let tx_out = &tx_outs[0]; - assert_eq!(tx_out.get_monitor_id().to_vec(), monitor_id.to_vec()); - assert_eq!(tx_out.get_value(), 102030); - assert_eq!( - tx_out.get_direction(), - api::ProcessedTxOutDirection::Received - ); - assert_eq!(tx_out.get_token_id(), 2); + assert_eq!(tx_out.monitor_id.to_vec(), monitor_id.to_vec()); + assert_eq!(tx_out.value, 102030); + assert_eq!(tx_out.direction(), api::ProcessedTxOutDirection::Received); + assert_eq!(tx_out.token_id, 2); } // Query a block that will never get processed since its before the monitor's // first block. - let mut request = api::GetProcessedBlockRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); - request.set_block(0); + let request = api::GetProcessedBlockRequest { + monitor_id: monitor_id.to_vec(), + block: 0, + }; assert!(client.get_processed_block(&request).is_err()); // Query a block that hasn't been processed yet. - let mut request = api::GetProcessedBlockRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); - request.set_block(num_blocks + 2); + let request = api::GetProcessedBlockRequest { + monitor_id: monitor_id.to_vec(), + block: num_blocks + 2, + }; assert!(client.get_processed_block(&request).is_err()); // Query with an unknown monitor id. - let mut request = api::GetProcessedBlockRequest::new(); - request.set_monitor_id(vec![1; 32]); - request.set_block(1); + let request = api::GetProcessedBlockRequest { + monitor_id: vec![1; 32], + block: 1, + }; assert!(client.get_processed_block(&request).is_err()); } @@ -4451,10 +4582,12 @@ mod test { // Response should contain the requested number of distinct mixins. { - let mut request = api::GetMixinsRequest::new(); - request.set_num_mixins(13); + let request = api::GetMixinsRequest { + num_mixins: 13, + ..Default::default() + }; let response = client.get_mixins(&request).unwrap(); - let mixins_with_proofs: Vec = response.get_mixins().to_vec(); + let mixins_with_proofs: Vec = response.mixins.to_vec(); assert_eq!(mixins_with_proofs.len(), 13); @@ -4462,7 +4595,7 @@ mod test { let mixin_hashes: HashSet<_> = mixins_with_proofs .iter() .map(|mixin| { - let tx_out: TxOut = TxOut::try_from(mixin.get_output()).unwrap(); + let tx_out: TxOut = TxOut::try_from(mixin.output.as_ref().unwrap()).unwrap(); tx_out.hash() }) .collect(); @@ -4473,8 +4606,10 @@ mod test { // Requesting more mixins than exist in the ledger should return an error. // TODO: enforce a limit on the number of mixins that may be requested. { - let mut bad_request = api::GetMixinsRequest::new(); - bad_request.set_num_mixins(10000); + let bad_request = api::GetMixinsRequest { + num_mixins: 10000, + ..Default::default() + }; let response = client.get_mixins(&bad_request); assert!(response.is_err()); @@ -4530,15 +4665,14 @@ mod test { // The ledger contains 40 outputs. Requesting 30 and excluding 10 should return // exactly the remaining 30. - let mut request = api::GetMixinsRequest::new(); - request.set_num_mixins(30); - request.set_excluded(RepeatedField::from_vec( - to_exclude.iter().map(api::external::TxOut::from).collect(), - )); + let request = api::GetMixinsRequest { + num_mixins: 30, + excluded: to_exclude.iter().map(api::external::TxOut::from).collect(), + }; let response = client.get_mixins(&request).unwrap(); - let mixins_with_proofs: Vec = response.get_mixins().to_vec(); + let mixins_with_proofs: Vec = response.mixins.to_vec(); // Should contain 30 mixins assert_eq!(mixins_with_proofs.len(), 30); @@ -4547,7 +4681,7 @@ mod test { let excluded_hashes: HashSet<_> = to_exclude.iter().map(|tx_out| tx_out.hash()).collect(); for mixin in &mixins_with_proofs { - let mixin: TxOut = TxOut::try_from(mixin.get_output()).unwrap(); + let mixin: TxOut = TxOut::try_from(mixin.output.as_ref().unwrap()).unwrap(); assert!(!excluded_hashes.contains(&mixin.hash())); } } @@ -4570,17 +4704,19 @@ mod test { ); let mixins_with_proofs: Vec = { - let mut request = api::GetMixinsRequest::new(); - request.set_num_mixins(13); + let request = api::GetMixinsRequest { + num_mixins: 13, + ..Default::default() + }; let response = client.get_mixins(&request).unwrap(); - response.get_mixins().to_vec() + response.mixins.to_vec() }; assert_eq!(mixins_with_proofs.len(), 13); // Each membership proof should be correct. for mixin_with_proof in &mixins_with_proofs { - let mixin: TxOut = TxOut::try_from(mixin_with_proof.get_output()).unwrap(); + let mixin: TxOut = TxOut::try_from(mixin_with_proof.output.as_ref().unwrap()).unwrap(); // The returned proof should be correct. let expected_proof = { @@ -4590,7 +4726,7 @@ mod test { api::external::TxOutMembershipProof::from(&proofs[0]) }; - assert_eq!(mixin_with_proof.get_proof(), &expected_proof); + assert_eq!(mixin_with_proof.proof.as_ref().unwrap(), &expected_proof); } } @@ -4640,20 +4776,20 @@ mod test { }; // Try with only outputs - let mut request = api::GetMembershipProofsRequest::new(); - request.set_outputs(RepeatedField::from_vec( - outputs.iter().map(api::external::TxOut::from).collect(), - )); + let request = api::GetMembershipProofsRequest { + outputs: outputs.iter().map(api::external::TxOut::from).collect(), + ..Default::default() + }; let response = client.get_membership_proofs(&request).unwrap(); // The response should should contain an element for each requested output. assert_eq!(response.output_list.len(), outputs.len()); - for (tx_out, output_with_proof) in outputs.iter().zip(response.get_output_list().iter()) { + for (tx_out, output_with_proof) in outputs.iter().zip(response.output_list.iter()) { // The response should contain a TxOutWithProof for each requested TxOut. assert_eq!( - output_with_proof.get_output(), + output_with_proof.output.as_ref().unwrap(), &api::external::TxOut::from(tx_out) ); @@ -4666,38 +4802,39 @@ mod test { api::external::TxOutMembershipProof::from(&proofs[0]) }; - assert_eq!(output_with_proof.get_proof(), &expected_proof); + assert_eq!(output_with_proof.proof.as_ref().unwrap(), &expected_proof); } // Try with only indices, we should receive an identical response. - let mut request2 = api::GetMembershipProofsRequest::new(); - request2.set_indices(vec![ - ledger_db - .get_tx_out_index_by_hash(&outputs[0].hash()) - .unwrap(), - ledger_db - .get_tx_out_index_by_hash(&outputs[1].hash()) - .unwrap(), - ledger_db - .get_tx_out_index_by_hash(&outputs[2].hash()) - .unwrap(), - ]); + let request2 = api::GetMembershipProofsRequest { + indices: vec![ + ledger_db + .get_tx_out_index_by_hash(&outputs[0].hash()) + .unwrap(), + ledger_db + .get_tx_out_index_by_hash(&outputs[1].hash()) + .unwrap(), + ledger_db + .get_tx_out_index_by_hash(&outputs[2].hash()) + .unwrap(), + ], + ..Default::default() + }; let response2 = client.get_membership_proofs(&request2).unwrap(); assert_eq!(response, response2); // Try with no indices or outputs - let request3 = api::GetMembershipProofsRequest::new(); + let request3 = api::GetMembershipProofsRequest::default(); let response3 = client.get_membership_proofs(&request3).unwrap(); assert!(response3.output_list.is_empty()); // Try with both, we should get an error. - let mut request4 = api::GetMembershipProofsRequest::new(); - request4.set_outputs(RepeatedField::from_vec( - outputs.iter().map(api::external::TxOut::from).collect(), - )); - request4.set_indices(vec![1]); + let request4 = api::GetMembershipProofsRequest { + outputs: outputs.iter().map(api::external::TxOut::from).collect(), + indices: vec![1], + }; assert!(client.get_membership_proofs(&request4).is_err()); } @@ -4755,36 +4892,38 @@ mod test { assert!(!utxos.is_empty()); // Call generate swap. - let mut request = api::GenerateSwapRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_change_subaddress(0); - request.set_input( - utxos - .iter() - .filter(|utxo| utxo.token_id == *Mob::ID) - .map(api::UnspentTxOut::from) - .next() - .unwrap(), - ); - request.set_allow_partial_fill(true); - request.set_counter_value(123); - request.set_counter_token_id(1); - request.set_minimum_fill_value(10); + let request = api::GenerateSwapRequest { + sender_monitor_id: monitor_id.to_vec(), + change_subaddress: 0, + input: Some( + utxos + .iter() + .filter(|utxo| utxo.token_id == *Mob::ID) + .map(api::UnspentTxOut::from) + .next() + .unwrap(), + ), + allow_partial_fill: true, + counter_value: 123, + counter_token_id: 1, + minimum_fill_value: 10, + ..Default::default() + }; // Test the happy flow for MOB -> eUSD, partial fill swap { let response = client.generate_swap(&request).unwrap(); // Sanity test the response. - let sci = response.get_sci(); + let sci = response.sci.as_ref().unwrap(); assert_eq!(sci.tx_out_global_indices.len(), 11); assert_eq!(sci.required_output_amounts.len(), 0); - let tx_in = sci.get_tx_in(); + let tx_in = sci.tx_in.as_ref().unwrap(); assert_eq!(tx_in.ring.len(), 11); - let rules = tx_in.get_input_rules(); + let rules = tx_in.input_rules.as_ref().unwrap(); assert_eq!(rules.required_outputs.len(), 0); assert_eq!(rules.partial_fill_outputs.len(), 1); assert!(rules.partial_fill_change.as_ref().is_some()); @@ -4812,33 +4951,35 @@ mod test { // Test the happy flow for eUSD -> MOB, non partial fill swap { - let mut request = api::GenerateSwapRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_change_subaddress(0); - request.set_input( - utxos - .iter() - .filter(|utxo| utxo.token_id == 1) - .map(api::UnspentTxOut::from) - .next() - .unwrap(), - ); - request.set_counter_value(999_999); - request.set_counter_token_id(0); - request.set_allow_partial_fill(false); - request.set_tombstone(1000); + let request = api::GenerateSwapRequest { + sender_monitor_id: monitor_id.to_vec(), + change_subaddress: 0, + input: Some( + utxos + .iter() + .filter(|utxo| utxo.token_id == 1) + .map(api::UnspentTxOut::from) + .next() + .unwrap(), + ), + allow_partial_fill: false, + counter_value: 999_999, + counter_token_id: 0, + minimum_fill_value: 10, + tombstone: 1000, + }; let response = client.generate_swap(&request).unwrap(); // Sanity test the response. - let sci = response.get_sci(); + let sci = response.sci.as_ref().unwrap(); assert_eq!(sci.tx_out_global_indices.len(), 11); assert_eq!(sci.required_output_amounts.len(), 1); - let tx_in = sci.get_tx_in(); + let tx_in = sci.tx_in.as_ref().unwrap(); assert_eq!(tx_in.ring.len(), 11); - let rules = tx_in.get_input_rules(); + let rules = tx_in.input_rules.as_ref().unwrap(); assert_eq!(rules.required_outputs.len(), 1); assert_eq!(rules.partial_fill_outputs.len(), 0); assert!(rules.partial_fill_change.as_ref().is_none()); @@ -4872,7 +5013,7 @@ mod test { { // No monitor id let mut request = request.clone(); - request.set_sender_monitor_id(vec![]); + request.sender_monitor_id = vec![]; assert!(client.generate_swap(&request).is_err()); } @@ -4888,28 +5029,28 @@ mod test { .unwrap(); let mut request = request.clone(); - request.set_sender_monitor_id(MonitorId::from(&data).to_vec()); + request.sender_monitor_id = MonitorId::from(&data).to_vec(); assert!(client.generate_swap(&request).is_err()); } { // Subaddress index out of range let mut request = request.clone(); - request.set_change_subaddress(data.first_subaddress + data.num_subaddresses + 1); + request.change_subaddress = data.first_subaddress + data.num_subaddresses + 1; assert!(client.generate_swap(&request).is_err()); } { // Junk input let mut request = request.clone(); - request.set_input(api::UnspentTxOut::default()); + request.input = Some(api::UnspentTxOut::default()); assert!(client.generate_swap(&request).is_err()); } { // Counter value of zero is an error let mut request = request.clone(); - request.set_counter_value(0); + request.counter_value = 0; assert!(client.generate_swap(&request).is_err()); } } @@ -4985,61 +5126,69 @@ mod test { ]; // Call generate tx. - let mut request = api::GenerateTxRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_change_subaddress(0); - request.set_input_list(RepeatedField::from_vec( - utxos + let request = api::GenerateTxRequest { + sender_monitor_id: monitor_id.to_vec(), + change_subaddress: 0, + input_list: utxos .iter() .filter(|utxo| utxo.token_id == *Mob::ID) .map(api::UnspentTxOut::from) .collect(), - )); - request.set_outlay_list(RepeatedField::from_vec( - outlays.iter().map(api::Outlay::from).collect(), - )); + outlay_list: outlays.iter().map(api::Outlay::from).collect(), + ..Default::default() + }; // Test the happy flow for MOB. { let response = client.generate_tx(&request).unwrap(); // Sanity test the response. - let tx_proposal = response.get_tx_proposal(); + let tx_proposal = response.tx_proposal.as_ref().unwrap(); let expected_num_inputs: u64 = (outlays.iter().map(|outlay| outlay.value).sum::() / test_utils::DEFAULT_PER_RECIPIENT_AMOUNT) + 1; + assert_eq!(tx_proposal.input_list.len(), expected_num_inputs as usize); assert_eq!( - tx_proposal.get_input_list().len(), - expected_num_inputs as usize - ); - assert_eq!( - tx_proposal.get_tx().get_prefix().get_inputs().len(), + tx_proposal + .tx + .as_ref() + .unwrap() + .prefix + .as_ref() + .unwrap() + .inputs + .len(), expected_num_inputs as usize ); assert_eq!( - tx_proposal.get_outlay_list(), + tx_proposal.outlay_list, request - .get_outlay_list() + .outlay_list .iter() .map(|outlay| api::OutlayV2::new_from_outlay_and_token_id(outlay, *Mob::ID)) .collect::>() ); assert_eq!( - tx_proposal.get_tx().get_prefix().get_outputs().len(), + tx_proposal + .tx + .as_ref() + .unwrap() + .prefix + .as_ref() + .unwrap() + .outputs + .len(), outlays.len() + 1 ); // Extra output for change. - let tx = Tx::try_from(tx_proposal.get_tx()).unwrap(); + let tx = Tx::try_from(tx_proposal.tx.as_ref().unwrap()).unwrap(); // The transaction should contain an output for each outlay, and one for change. assert_eq!(tx.prefix.outputs.len(), outlays.len() + 1); // The transaction should have a confirmation code for each outlay - assert_eq!( - outlays.len(), - tx_proposal.get_outlay_confirmation_numbers().len() - ); + assert_eq!(outlays.len(), tx_proposal.outlay_confirmation_numbers.len()); let change_value = test_utils::DEFAULT_PER_RECIPIENT_AMOUNT - outlays.iter().map(|outlay| outlay.value).sum::() @@ -5094,67 +5243,97 @@ mod test { } // Santity test fee - assert_eq!(tx_proposal.get_fee(), Mob::MINIMUM_FEE); - assert_eq!(tx_proposal.get_tx().get_prefix().fee, Mob::MINIMUM_FEE); + assert_eq!(tx_proposal.fee, Mob::MINIMUM_FEE); + assert_eq!( + tx_proposal + .tx + .as_ref() + .unwrap() + .prefix + .as_ref() + .unwrap() + .fee, + Mob::MINIMUM_FEE + ); // Sanity test tombstone block let num_blocks = ledger_db.num_blocks().unwrap(); assert_eq!( - tx_proposal.get_tx().get_prefix().tombstone_block, + tx_proposal + .tx + .as_ref() + .unwrap() + .prefix + .as_ref() + .unwrap() + .tombstone_block, num_blocks + DEFAULT_NEW_TX_BLOCK_ATTEMPTS ); } // Test the happy flow for TokenId(2) { - let mut request = api::GenerateTxRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_change_subaddress(0); - request.set_input_list(RepeatedField::from_vec( - utxos + let fee = 10_000; + let request = api::GenerateTxRequest { + sender_monitor_id: monitor_id.to_vec(), + change_subaddress: 0, + input_list: utxos .iter() .filter(|utxo| utxo.token_id == 2) .map(api::UnspentTxOut::from) .collect(), - )); - request.set_outlay_list(RepeatedField::from_vec( - outlays.iter().map(api::Outlay::from).collect(), - )); - request.set_token_id(2); - - let fee = 10_000; - request.set_fee(fee); + outlay_list: outlays.iter().map(api::Outlay::from).collect(), + token_id: 2, + fee, + ..Default::default() + }; let response = client.generate_tx(&request).unwrap(); // Sanity test the response. - let tx_proposal = response.get_tx_proposal(); + let tx_proposal = response.tx_proposal.as_ref().unwrap(); - assert_eq!(tx_proposal.get_input_list().len(), 1,); - assert_eq!(tx_proposal.get_tx().get_prefix().get_inputs().len(), 1,); + assert_eq!(tx_proposal.input_list.len(), 1,); + assert_eq!( + tx_proposal + .tx + .as_ref() + .unwrap() + .prefix + .as_ref() + .unwrap() + .inputs + .len(), + 1, + ); assert_eq!( - tx_proposal.get_outlay_list(), + tx_proposal.outlay_list, request - .get_outlay_list() + .outlay_list .iter() .map(|outlay| api::OutlayV2::new_from_outlay_and_token_id(outlay, 2)) .collect::>() ); assert_eq!( - tx_proposal.get_tx().get_prefix().get_outputs().len(), + tx_proposal + .tx + .as_ref() + .unwrap() + .prefix + .as_ref() + .unwrap() + .outputs + .len(), outlays.len() + 1 ); // Extra output for change. - let tx = Tx::try_from(tx_proposal.get_tx()).unwrap(); + let tx = Tx::try_from(tx_proposal.tx.as_ref().unwrap()).unwrap(); // The transaction should contain an output for each outlay, and one for change. assert_eq!(tx.prefix.outputs.len(), outlays.len() + 1); // The transaction should have a confirmation code for each outlay - assert_eq!( - outlays.len(), - tx_proposal.get_outlay_confirmation_numbers().len() - ); + assert_eq!(outlays.len(), tx_proposal.outlay_confirmation_numbers.len()); let change_value = 1_000_000_000_000 - outlays.iter().map(|outlay| outlay.value).sum::() - fee; @@ -5208,13 +5387,30 @@ mod test { } // Santity test fee - assert_eq!(tx_proposal.get_fee(), fee); - assert_eq!(tx_proposal.get_tx().get_prefix().fee, fee); + assert_eq!(tx_proposal.fee, fee); + assert_eq!( + tx_proposal + .tx + .as_ref() + .unwrap() + .prefix + .as_ref() + .unwrap() + .fee, + fee + ); // Sanity test tombstone block let num_blocks = ledger_db.num_blocks().unwrap(); assert_eq!( - tx_proposal.get_tx().get_prefix().tombstone_block, + tx_proposal + .tx + .as_ref() + .unwrap() + .prefix + .as_ref() + .unwrap() + .tombstone_block, num_blocks + DEFAULT_NEW_TX_BLOCK_ATTEMPTS ); } @@ -5223,7 +5419,7 @@ mod test { { // No monitor id let mut request = request.clone(); - request.set_sender_monitor_id(vec![]); + request.sender_monitor_id = vec![]; assert!(client.generate_tx(&request).is_err()); } @@ -5239,21 +5435,21 @@ mod test { .unwrap(); let mut request = request.clone(); - request.set_sender_monitor_id(MonitorId::from(&data).to_vec()); + request.sender_monitor_id = MonitorId::from(&data).to_vec(); assert!(client.generate_tx(&request).is_err()); } { // Subaddress index out of range let mut request = request.clone(); - request.set_change_subaddress(data.first_subaddress + data.num_subaddresses + 1); + request.change_subaddress = data.first_subaddress + data.num_subaddresses + 1; assert!(client.generate_tx(&request).is_err()); } { // Junk input let mut request = request.clone(); - request.mut_input_list().push(api::UnspentTxOut::default()); + request.input_list.push(api::UnspentTxOut::default()); assert!(client.generate_tx(&request).is_err()); } @@ -5261,25 +5457,23 @@ mod test { // Attempt to spend more than we have let num_blocks = ledger_db.num_blocks().unwrap(); let mut request = request.clone(); - request.set_outlay_list(RepeatedField::from_vec(vec![api::Outlay::from(&Outlay { + request.outlay_list = vec![api::Outlay::from(&Outlay { receiver: receiver1.default_subaddress(), value: test_utils::DEFAULT_PER_RECIPIENT_AMOUNT * num_blocks, tx_private_key: None, - })])); + })]; assert!(client.generate_tx(&request).is_err()); } { // Mixing input tokens (utxos has both Mob and TokenId(2)) - let mut request = api::GenerateTxRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_change_subaddress(0); - request.set_input_list(RepeatedField::from_vec( - utxos.iter().map(api::UnspentTxOut::from).collect(), - )); - request.set_outlay_list(RepeatedField::from_vec( - outlays.iter().map(api::Outlay::from).collect(), - )); + let request = api::GenerateTxRequest { + sender_monitor_id: monitor_id.to_vec(), + change_subaddress: 0, + input_list: utxos.iter().map(api::UnspentTxOut::from).collect(), + outlay_list: outlays.iter().map(api::Outlay::from).collect(), + ..Default::default() + }; assert!(client.generate_tx(&request).is_err()); } } @@ -5347,32 +5541,34 @@ mod test { }]; // Call generate tx. - let mut request = api::GenerateTxRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_change_subaddress(0); - request.set_input_list(RepeatedField::from_vec( - utxos + let rth = mc_mobilecoind_api::TransactionMemoRth { + payment_id: Some(transaction_memo_rth::PaymentId::PaymentRequestId(55551)), + ..Default::default() + }; + let request = api::GenerateTxRequest { + sender_monitor_id: monitor_id.to_vec(), + change_subaddress: 0, + input_list: utxos .iter() .filter(|utxo| utxo.token_id == *Mob::ID) .map(api::UnspentTxOut::from) .collect(), - )); - request.set_outlay_list(RepeatedField::from_vec( - outlays.iter().map(api::Outlay::from).collect(), - )); - let mut rth = mc_mobilecoind_api::TransactionMemo_RTH::default(); - rth.set_payment_request_id(55551); - - request.set_memo(mc_mobilecoind_api::TransactionMemo { - transaction_memo: Some( - mc_mobilecoind_api::TransactionMemo_oneof_transaction_memo::rth(rth), - ), + outlay_list: outlays.iter().map(api::Outlay::from).collect(), + memo: Some(mc_mobilecoind_api::TransactionMemo { + transaction_memo: Some(mc_mobilecoind_api::transaction_memo::TransactionMemo::Rth( + rth, + )), + }), ..Default::default() - }); + }; let response = client.generate_tx(&request).unwrap(); - let tx_proposal = response.get_tx_proposal(); - let tx = Tx::try_from(tx_proposal.get_tx()).unwrap(); + let default_tx_proposal = Default::default(); + let tx_proposal = response + .tx_proposal + .as_ref() + .unwrap_or(&default_tx_proposal); + let tx = Tx::try_from(tx_proposal.tx.as_ref().unwrap()).unwrap(); // The transaction should contain two outputs (outlay + change) assert_eq!(tx.prefix.outputs.len(), 2); @@ -5506,18 +5702,20 @@ mod test { // Generate a swap. let generate_swap_response = { - let mut request = api::GenerateSwapRequest::new(); - request.set_sender_monitor_id(originator_monitor_id.to_vec()); - request.set_change_subaddress(0); - request.set_input(offered_input); - request.set_allow_partial_fill(true); - request.set_counter_value(123); - request.set_counter_token_id(1); - request.set_minimum_fill_value(10); + let request = api::GenerateSwapRequest { + sender_monitor_id: originator_monitor_id.to_vec(), + change_subaddress: 0, + input: Some(offered_input), + allow_partial_fill: true, + counter_value: 123, + counter_token_id: 1, + minimum_fill_value: 10, + ..Default::default() + }; client.generate_swap(&request).unwrap() }; let generated_sci = - SignedContingentInput::try_from(generate_swap_response.get_sci()).unwrap(); + SignedContingentInput::try_from(generate_swap_response.sci.as_ref().unwrap()).unwrap(); generated_sci.validate().unwrap(); // Now we will try to build a transaction that incorporates the swap. @@ -5536,39 +5734,57 @@ mod test { .all(|utxo| utxo.value == counterparty_eusd_utxo_value)); // We will try to take one quarter of the offered input. - let mut sci_for_tx = api::SciForTx::new(); - sci_for_tx.set_sci(generate_swap_response.get_sci().clone()); - sci_for_tx.set_partial_fill_value(offered_value / 4); + let sci_for_tx = api::SciForTx { + sci: Some(generate_swap_response.sci.as_ref().unwrap().clone()), + partial_fill_value: offered_value / 4, + }; // Try to add the swap to a mixed transaction - let mut request = api::GenerateMixedTxRequest::new(); - request.set_sender_monitor_id(counterparty_monitor_id.to_vec()); - request.set_change_subaddress(0); - // Only token id 1 is needed to fulfill the other side of the sci - request.set_input_list( - utxos + let mut request = api::GenerateMixedTxRequest { + sender_monitor_id: counterparty_monitor_id.to_vec(), + change_subaddress: 0, + input_list: utxos .iter() .filter(|utxo| utxo.token_id == 1) .map(Into::into) .collect(), - ); - request.set_scis(vec![sci_for_tx].into()); + scis: vec![sci_for_tx], + ..Default::default() + }; let generate_mixed_tx_response = client.generate_mixed_tx(&request).unwrap(); assert_eq!( generate_mixed_tx_response - .get_tx_proposal() - .get_scis() + .tx_proposal + .as_ref() + .unwrap() + .scis .len(), 1 ); let response_sci = SignedContingentInput::try_from( - generate_mixed_tx_response.get_tx_proposal().get_scis()[0].get_sci(), + generate_mixed_tx_response + .tx_proposal + .as_ref() + .unwrap() + .scis[0] + .sci + .as_ref() + .unwrap(), ) .unwrap(); assert_eq!(response_sci, generated_sci); - let tx = Tx::try_from(generate_mixed_tx_response.get_tx_proposal().get_tx()).unwrap(); + let tx = Tx::try_from( + generate_mixed_tx_response + .tx_proposal + .as_ref() + .unwrap() + .tx + .as_ref() + .unwrap(), + ) + .unwrap(); assert_eq!(tx.prefix.outputs.len(), 4); @@ -5613,16 +5829,32 @@ mod test { // Changing the fee token id to 1 should work, and slightly adjust the output // values. - request.set_fee_token_id(1); + request.fee_token_id = 1; let generate_mixed_tx_response = client.generate_mixed_tx(&request).unwrap(); let response_sci = SignedContingentInput::try_from( - generate_mixed_tx_response.get_tx_proposal().get_scis()[0].get_sci(), + generate_mixed_tx_response + .tx_proposal + .as_ref() + .unwrap() + .scis[0] + .sci + .as_ref() + .unwrap(), ) .unwrap(); assert_eq!(response_sci, generated_sci); - let tx = Tx::try_from(generate_mixed_tx_response.get_tx_proposal().get_tx()).unwrap(); + let tx = Tx::try_from( + generate_mixed_tx_response + .tx_proposal + .as_ref() + .unwrap() + .tx + .as_ref() + .unwrap(), + ) + .unwrap(); assert_eq!(tx.prefix.outputs.len(), 4); @@ -5674,16 +5906,32 @@ mod test { // Changing the fee in the request should work, and slightly adjust the output // values. let fee_override = 500_000; - request.set_fee(fee_override); + request.fee = fee_override; let generate_mixed_tx_response = client.generate_mixed_tx(&request).unwrap(); let response_sci = SignedContingentInput::try_from( - generate_mixed_tx_response.get_tx_proposal().get_scis()[0].get_sci(), + generate_mixed_tx_response + .tx_proposal + .as_ref() + .unwrap() + .scis[0] + .sci + .as_ref() + .unwrap(), ) .unwrap(); assert_eq!(response_sci, generated_sci); - let tx = Tx::try_from(generate_mixed_tx_response.get_tx_proposal().get_tx()).unwrap(); + let tx = Tx::try_from( + generate_mixed_tx_response + .tx_proposal + .as_ref() + .unwrap() + .tx + .as_ref() + .unwrap(), + ) + .unwrap(); assert_eq!(tx.prefix.outputs.len(), 4); @@ -5730,17 +5978,15 @@ mod test { assert!(found_originator_change); // Omitting the input list should result in an error - request.clear_input_list(); + request.input_list = vec![]; assert!(client.generate_mixed_tx(&request).is_err()); // Omitting the inputs with token id 1, which is needed, should give an error - request.set_input_list( - utxos - .iter() - .filter(|utxo| utxo.token_id == 0) - .map(Into::into) - .collect(), - ); + request.input_list = utxos + .iter() + .filter(|utxo| utxo.token_id == 0) + .map(Into::into) + .collect(); assert!(client.generate_mixed_tx(&request).is_err()); } @@ -5799,27 +6045,29 @@ mod test { .iter() .filter(|utxo| utxo.token_id == token_id2) .map(Into::into) - .collect::>(); + .collect::>(); assert!(!utxos.is_empty()); // Prepare request - let mut request = api::GenerateBurnRedemptionTxRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_change_subaddress(0); - request.set_input_list(utxos); - request.set_burn_amount(100_000); - request.set_fee(200_000); - request.set_token_id(*token_id2); - request.set_redemption_memo(vec![5u8; BurnRedemptionMemo::MEMO_DATA_LEN]); - request.set_enable_destination_memo(true); + let request = api::GenerateBurnRedemptionTxRequest { + sender_monitor_id: monitor_id.to_vec(), + change_subaddress: 0, + input_list: utxos, + burn_amount: 100_000, + fee: 200_000, + token_id: *token_id2, + redemption_memo: vec![5u8; BurnRedemptionMemo::MEMO_DATA_LEN], + enable_destination_memo: true, + ..Default::default() + }; // Test the happy flow. { let response = client.generate_burn_redemption_tx(&request).unwrap(); // Sanity test the response. - let tx_proposal = response.get_tx_proposal(); - let tx = Tx::try_from(tx_proposal.get_tx()).unwrap(); + let tx_proposal = response.tx_proposal.as_ref().unwrap(); + let tx = Tx::try_from(tx_proposal.tx.as_ref().unwrap()).unwrap(); // Two outputs - change and burn assert_eq!(tx.prefix.outputs.len(), 2); @@ -5890,14 +6138,14 @@ mod test { // Invalid memo data length results in an error. { let mut request = request.clone(); - request.set_redemption_memo(vec![5u8; BurnRedemptionMemo::MEMO_DATA_LEN + 1]); + request.redemption_memo = vec![5u8; BurnRedemptionMemo::MEMO_DATA_LEN + 1]; assert!(client.generate_burn_redemption_tx(&request).is_err()); } // Trying to burn more than we have results in an error. { let mut request = request.clone(); - request.set_burn_amount(1_000_000_000_000 - request.get_fee() + 1); + request.burn_amount = 1_000_000_000_000 - request.fee + 1; assert!(client.generate_burn_redemption_tx(&request).is_err()); } } @@ -5916,8 +6164,9 @@ mod test { let tx_out_pub_key = api::external::CompressedRistretto::from(&block_contents.outputs[0].public_key); - let mut request = api::GetBlockIndexByTxPubKeyRequest::new(); - request.set_tx_public_key(tx_out_pub_key); + let request = api::GetBlockIndexByTxPubKeyRequest { + tx_public_key: Some(tx_out_pub_key), + }; let response = client.get_block_index_by_tx_pub_key(&request).unwrap(); assert_eq!(block_index, response.block); @@ -5969,9 +6218,7 @@ mod test { (&outputs[1].public_key).into(), (&outputs[2].public_key).into(), (&CompressedRistrettoPublic::from(RistrettoPublic::from_random(&mut rng))).into(), - ] - .into(), - ..Default::default() + ], }; let response = client.get_tx_out_results_by_pub_key(&request).unwrap(); @@ -5980,20 +6227,20 @@ mod test { for i in 0..3 { assert_eq!( - response.results[i].tx_out_pubkey.get_ref(), + response.results[i].tx_out_pubkey.as_ref().unwrap(), &request.tx_out_public_keys[i] ); - assert_eq!(response.results[i].result_code, TxOutResultCode::Found); + assert_eq!(response.results[i].result_code(), TxOutResultCode::Found); } assert_eq!( - response.results[3].tx_out_pubkey.get_ref(), + response.results[3].tx_out_pubkey.as_ref().unwrap(), &request.tx_out_public_keys[3] ); - assert_eq!(response.results[3].result_code, TxOutResultCode::NotFound); + assert_eq!(response.results[3].result_code(), TxOutResultCode::NotFound); assert_eq!( - Block::try_from(response.get_latest_block()).unwrap(), + Block::try_from(response.latest_block.as_ref().unwrap()).unwrap(), ledger_db.get_latest_block().unwrap() ); } @@ -6036,19 +6283,19 @@ mod test { assert!(!utxos.is_empty()); // Call generate transfer code ctx. - let mut request = api::GenerateTransferCodeTxRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_change_subaddress(0); - request.set_input_list(RepeatedField::from_vec( - utxos.iter().map(api::UnspentTxOut::from).collect(), - )); - request.set_value(1337); + let request = api::GenerateTransferCodeTxRequest { + sender_monitor_id: monitor_id.to_vec(), + change_subaddress: 0, + input_list: utxos.iter().map(api::UnspentTxOut::from).collect(), + value: 1337, + ..Default::default() + }; let response = client.generate_transfer_code_tx(&request).unwrap(); // Test that the generated transaction can be picked up by mobilecoind. { - let tx_proposal = TxProposal::try_from(response.get_tx_proposal()).unwrap(); + let tx_proposal = TxProposal::try_from(response.tx_proposal.as_ref().unwrap()).unwrap(); let key_images = tx_proposal.tx.key_images(); let outputs = tx_proposal.tx.prefix.outputs; add_txos_and_key_images_to_ledger( @@ -6062,7 +6309,8 @@ mod test { // Use bip39 entropy to construct AccountKey. let mnemonic = - Mnemonic::from_entropy(response.get_bip39_entropy(), Language::English).unwrap(); + Mnemonic::from_entropy(response.bip39_entropy.as_slice(), Language::English) + .unwrap(); let key = mnemonic.derive_slip10_key(0); let account_key = AccountKey::from(key); @@ -6092,7 +6340,7 @@ mod test { assert_eq!(utxo.value, 1337); assert_eq!( utxo.tx_out.public_key, - RistrettoPublic::try_from(response.get_tx_public_key()) + RistrettoPublic::try_from(response.tx_public_key.as_ref().unwrap()) .unwrap() .into() ); @@ -6152,14 +6400,16 @@ mod test { assert!(!utxos.is_empty()); // Call generate optimization tx. - let mut request = api::GenerateOptimizationTxRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); - request.set_subaddress(0); + let request = api::GenerateOptimizationTxRequest { + monitor_id: monitor_id.to_vec(), + subaddress: 0, + ..Default::default() + }; let response = client.generate_optimization_tx(&request).unwrap(); // Sanity test the response. - let tx_proposal = TxProposal::try_from(response.get_tx_proposal()).unwrap(); + let tx_proposal = TxProposal::try_from(response.tx_proposal.as_ref().unwrap()).unwrap(); let expected_num_inputs: usize = MAX_INPUTS as usize; assert_eq!(tx_proposal.utxos.len(), expected_num_inputs); @@ -6246,17 +6496,17 @@ mod test { // Build a request to transfer the first two TxOuts let tx_utxos = utxos[0..2].to_vec(); - let mut request = api::GenerateTxFromTxOutListRequest::new(); - request.set_account_key((&sender).into()); - request.set_input_list(RepeatedField::from_vec( - tx_utxos.iter().map(api::UnspentTxOut::from).collect(), - )); let receiver = AccountKey::random(&mut rng); - request.set_receiver((&receiver.default_subaddress()).into()); - request.set_fee(Mob::MINIMUM_FEE); + let request = api::GenerateTxFromTxOutListRequest { + account_key: Some((&sender).into()), + input_list: tx_utxos.iter().map(api::UnspentTxOut::from).collect(), + receiver: Some((&receiver.default_subaddress()).into()), + fee: Mob::MINIMUM_FEE, + ..Default::default() + }; let response = client.generate_tx_from_tx_out_list(&request).unwrap(); - let tx_proposal = TxProposal::try_from(response.get_tx_proposal()).unwrap(); + let tx_proposal = TxProposal::try_from(response.tx_proposal.as_ref().unwrap()).unwrap(); // We should end up with one output assert_eq!(tx_proposal.tx.prefix.outputs.len(), 1); @@ -6331,26 +6581,25 @@ mod test { ]; // Call generate tx. - let mut request = api::GenerateTxRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_change_subaddress(0); - request.set_input_list(RepeatedField::from_vec( - utxos.iter().map(api::UnspentTxOut::from).collect(), - )); - request.set_outlay_list(RepeatedField::from_vec( - outlays.iter().map(api::Outlay::from).collect(), - )); + let request = api::GenerateTxRequest { + sender_monitor_id: monitor_id.to_vec(), + change_subaddress: 0, + input_list: utxos.iter().map(api::UnspentTxOut::from).collect(), + outlay_list: outlays.iter().map(api::Outlay::from).collect(), + ..Default::default() + }; // Get our propsal which we'll use for the test. let response = client.generate_tx(&request).unwrap(); - let tx_proposal = TxProposal::try_from(response.get_tx_proposal()).unwrap(); + let tx_proposal = TxProposal::try_from(response.tx_proposal.as_ref().unwrap()).unwrap(); let tx = tx_proposal.tx.clone(); let outlay_confirmation_numbers = tx_proposal.outlay_confirmation_numbers.clone(); // Test the happy flow. { - let mut request = api::SubmitTxRequest::new(); - request.set_tx_proposal(api::TxProposal::from(&tx_proposal)); + let request = api::SubmitTxRequest { + tx_proposal: Some(api::TxProposal::from(&tx_proposal)), + }; let response = client.submit_tx(&request).unwrap(); @@ -6381,8 +6630,10 @@ mod test { // Sanity test sender receipt let key_images: Vec = response - .get_sender_tx_receipt() - .get_key_image_list() + .sender_tx_receipt + .as_ref() + .unwrap() + .key_image_list .iter() .map(|key_image| KeyImage::try_from(key_image).unwrap()) .collect(); @@ -6396,19 +6647,16 @@ mod test { } assert_eq!( - response.get_sender_tx_receipt().tombstone, + response.sender_tx_receipt.as_ref().unwrap().tombstone, tx.prefix.tombstone_block ); // Sanity the receiver receipts. - assert_eq!(response.get_receiver_tx_receipt_list().len(), outlays.len()); - for (outlay, receipt) in outlays - .iter() - .zip(response.get_receiver_tx_receipt_list().iter()) - { + assert_eq!(response.receiver_tx_receipt_list.len(), outlays.len()); + for (outlay, receipt) in outlays.iter().zip(response.receiver_tx_receipt_list.iter()) { assert_eq!( outlay.receiver, - PublicAddress::try_from(receipt.get_recipient()).unwrap() + PublicAddress::try_from(receipt.recipient.as_ref().unwrap()).unwrap() ); assert_eq!(receipt.tombstone, tx.prefix.tombstone_block); @@ -6420,9 +6668,9 @@ mod test { } assert_eq!( - response.get_receiver_tx_receipt_list().len() + 1, /* There's a change output - * that is not part of the - * receipts */ + response.receiver_tx_receipt_list.len() + 1, /* There's a change output + * that is not part of the + * receipts */ tx.prefix.outputs.len() ); @@ -6434,12 +6682,13 @@ mod test { .map(|tx_out| tx_out.public_key.to_bytes()) .collect(); - for receipt in response.get_receiver_tx_receipt_list().iter() { - let hash: [u8; 32] = receipt.get_tx_out_hash().try_into().unwrap(); + for receipt in response.receiver_tx_receipt_list.iter() { + let hash: [u8; 32] = receipt.tx_out_hash.as_slice().try_into().unwrap(); assert!(tx_out_hashes.contains(&hash)); - let public_key = - GenericArray::::from_slice(receipt.get_tx_public_key().get_data()); + let public_key = GenericArray::::from_slice( + receipt.tx_public_key.as_ref().unwrap().data.as_slice(), + ); assert!(tx_out_public_keys.contains(public_key)); } @@ -6494,9 +6743,11 @@ mod test { wait_for_monitors(&mobilecoind_db, &ledger_db, &logger); // Get balance for a monitor_id/subaddress index that has a balance. - let mut request = api::GetBalanceRequest::new(); - request.set_monitor_id(id.to_vec()); - request.set_subaddress_index(0); + let request = api::GetBalanceRequest { + monitor_id: id.to_vec(), + subaddress_index: 0, + ..Default::default() + }; let response = client.get_balance(&request).unwrap(); assert_eq!( @@ -6505,9 +6756,11 @@ mod test { ); // Get balance for subaddress with no utxos should return 0. - let mut request = api::GetBalanceRequest::new(); - request.set_monitor_id(id.to_vec()); - request.set_subaddress_index(1); + let request = api::GetBalanceRequest { + monitor_id: id.to_vec(), + subaddress_index: 1, + ..Default::default() + }; let response = client.get_balance(&request).unwrap(); assert_eq!(response.balance, 0); @@ -6516,16 +6769,21 @@ mod test { let mut id2 = id.clone().to_vec(); id2[0] = !id2[0]; - let mut request = api::GetBalanceRequest::new(); - request.set_monitor_id(id2); - request.set_subaddress_index(0); + let request = api::GetBalanceRequest { + monitor_id: id2, + subaddress_index: 0, + ..Default::default() + }; + let response = client.get_balance(&request).unwrap(); assert_eq!(response.balance, 0); // Invalid monitor id should error - let mut request = api::GetBalanceRequest::new(); - request.set_monitor_id(vec![1; 2]); - request.set_subaddress_index(0); + let request = api::GetBalanceRequest { + monitor_id: vec![1; 2], + subaddress_index: 0, + ..Default::default() + }; assert!(client.get_balance(&request).is_err()); } @@ -6585,12 +6843,12 @@ mod test { ]; // Call send payment. - let mut request = api::SendPaymentRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_sender_subaddress(0); - request.set_outlay_list(RepeatedField::from_vec( - outlays.iter().map(api::Outlay::from).collect(), - )); + let request = api::SendPaymentRequest { + sender_monitor_id: monitor_id.to_vec(), + sender_subaddress: 0, + outlay_list: outlays.iter().map(api::Outlay::from).collect(), + ..Default::default() + }; let response = client.send_payment(&request).unwrap(); @@ -6619,13 +6877,15 @@ mod test { let submitted_tx = opt_submitted_tx.unwrap(); assert_eq!( submitted_tx, - Tx::try_from(response.get_tx_proposal().get_tx()).unwrap() + Tx::try_from(response.tx_proposal.as_ref().unwrap().tx.as_ref().unwrap()).unwrap() ); // Sanity test sender receipt let key_images: Vec = response - .get_sender_tx_receipt() - .get_key_image_list() + .sender_tx_receipt + .as_ref() + .unwrap() + .key_image_list .iter() .map(|key_image| KeyImage::try_from(key_image).unwrap()) .collect(); @@ -6639,27 +6899,24 @@ mod test { } assert_eq!( - response.get_sender_tx_receipt().tombstone, + response.sender_tx_receipt.as_ref().unwrap().tombstone, submitted_tx.prefix.tombstone_block ); // Sanity the receiver receipts. - assert_eq!(response.get_receiver_tx_receipt_list().len(), outlays.len()); - for (outlay, receipt) in outlays - .iter() - .zip(response.get_receiver_tx_receipt_list().iter()) - { + assert_eq!(response.receiver_tx_receipt_list.len(), outlays.len()); + for (outlay, receipt) in outlays.iter().zip(response.receiver_tx_receipt_list.iter()) { assert_eq!( outlay.receiver, - PublicAddress::try_from(receipt.get_recipient()).unwrap() + PublicAddress::try_from(receipt.recipient.as_ref().unwrap()).unwrap() ); assert_eq!(receipt.tombstone, submitted_tx.prefix.tombstone_block); } assert_eq!( - response.get_receiver_tx_receipt_list().len() + 1, /* There's a change output that - * is not part of the receipts */ + response.receiver_tx_receipt_list.len() + 1, /* There's a change output that + * is not part of the receipts */ submitted_tx.prefix.outputs.len() ); @@ -6676,17 +6933,18 @@ mod test { .map(|tx_out| tx_out.public_key.to_bytes()) .collect(); - for receipt in response.get_receiver_tx_receipt_list().iter() { - let hash: [u8; 32] = receipt.get_tx_out_hash().try_into().unwrap(); + for receipt in response.receiver_tx_receipt_list.iter() { + let hash: [u8; 32] = receipt.tx_out_hash.as_slice().try_into().unwrap(); assert!(tx_out_hashes.contains(&hash)); - let public_key = - GenericArray::::from_slice(receipt.get_tx_public_key().get_data()); + let public_key = GenericArray::::from_slice( + receipt.tx_public_key.as_ref().unwrap().data.as_slice(), + ); assert!(tx_out_public_keys.contains(public_key)); } // Check that attempted_spend_height got updated for the relevant utxos. - let tx_proposal = TxProposal::try_from(response.get_tx_proposal()).unwrap(); + let tx_proposal = TxProposal::try_from(response.tx_proposal.as_ref().unwrap()).unwrap(); let account_utxos = mobilecoind_db .get_utxos_for_subaddress(&monitor_id, 0) @@ -6773,19 +7031,21 @@ mod test { // Call send payment without a limit on UTXOs - a single large UTXO should be // selected. - let mut request = api::SendPaymentRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_sender_subaddress(0); - request.set_outlay_list(RepeatedField::from_vec( - outlays.iter().map(api::Outlay::from).collect(), - )); + let mut request = api::SendPaymentRequest { + sender_monitor_id: monitor_id.to_vec(), + sender_subaddress: 0, + outlay_list: outlays.iter().map(api::Outlay::from).collect(), + ..Default::default() + }; let response = client.send_payment(&request).unwrap(); // Check which UTXOs were selected - it should be all of them. let selected_utxos: Vec = response - .get_sender_tx_receipt() - .get_key_image_list() + .sender_tx_receipt + .as_ref() + .unwrap() + .key_image_list .iter() .map(|proto_key_image| { let key_image = KeyImage::try_from(proto_key_image).unwrap(); @@ -6799,7 +7059,7 @@ mod test { // Try again, placing a cap at the max UTXO that can be selected. This should // cause send payment to fail. - request.set_max_input_utxo_value(20); + request.max_input_utxo_value = 20; match client.send_payment(&request) { Ok(_) => panic!("Should've returned an error"), Err(GrpcError::RpcFailure(rpc_status)) => { @@ -6812,12 +7072,14 @@ mod test { }; // Trying with a higher limit should work. - request.set_max_input_utxo_value(Mob::MINIMUM_FEE); + request.max_input_utxo_value = Mob::MINIMUM_FEE; let response = client.send_payment(&request).unwrap(); let selected_utxos: Vec = response - .get_sender_tx_receipt() - .get_key_image_list() + .sender_tx_receipt + .as_ref() + .unwrap() + .key_image_list .iter() .map(|proto_key_image| { let key_image = KeyImage::try_from(proto_key_image).unwrap(); @@ -6918,12 +7180,12 @@ mod test { ]; // Call send payment. - let mut request = api::SendPaymentRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_sender_subaddress(0); - request.set_outlay_list(RepeatedField::from_vec( - outlays.iter().map(api::Outlay::from).collect(), - )); + let request = api::SendPaymentRequest { + sender_monitor_id: monitor_id.to_vec(), + sender_subaddress: 0, + outlay_list: outlays.iter().map(api::Outlay::from).collect(), + ..Default::default() + }; let response = client.send_payment(&request).unwrap(); @@ -6952,14 +7214,16 @@ mod test { let submitted_tx = opt_submitted_tx.unwrap(); assert_eq!( submitted_tx, - Tx::try_from(response.get_tx_proposal().get_tx()).unwrap() + Tx::try_from(response.tx_proposal.as_ref().unwrap().tx.as_ref().unwrap()).unwrap() ); // Verify that the first receipient TxOut hint cannot be decrypted with the fog // key, since that one was not going to a fog address. let tx_out_index1 = *(response - .get_tx_proposal() - .get_outlay_index_to_tx_out_index() + .tx_proposal + .as_ref() + .unwrap() + .outlay_index_to_tx_out_index .get(&0) .unwrap()) as usize; let tx_out1 = submitted_tx.prefix.outputs.get(tx_out_index1).unwrap(); @@ -6972,8 +7236,10 @@ mod test { // The second recipient (the fog recipient) should have a valid hint. let tx_out_index2 = *(response - .get_tx_proposal() - .get_outlay_index_to_tx_out_index() + .tx_proposal + .as_ref() + .unwrap() + .outlay_index_to_tx_out_index .get(&1) .unwrap()) as usize; let tx_out2 = submitted_tx.prefix.outputs.get(tx_out_index2).unwrap(); @@ -7044,12 +7310,12 @@ mod test { ]; // Call send payment. - let mut request = api::SendPaymentRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_sender_subaddress(0); - request.set_outlay_list(RepeatedField::from_vec( - outlays.iter().map(api::Outlay::from).collect(), - )); + let request = api::SendPaymentRequest { + sender_monitor_id: monitor_id.to_vec(), + sender_subaddress: 0, + outlay_list: outlays.iter().map(api::Outlay::from).collect(), + ..Default::default() + }; let response = client.send_payment(&request); assert!(response.is_err()); @@ -7097,25 +7363,30 @@ mod test { // Generate b58 address code for this recipient. let receiver_public_address = receiver.default_subaddress(); - let mut wrapper = api::printable::PrintableWrapper::new(); - wrapper.set_public_address((&receiver_public_address).into()); + let wrapper = api::printable::PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress( + (&receiver_public_address).into(), + )), + }; let b58_code = wrapper.b58_encode().unwrap(); // Call pay address code. - let mut request = api::PayAddressCodeRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_sender_subaddress(0); - request.set_receiver_b58_code(b58_code); - request.set_amount(1234); + let request = api::PayAddressCodeRequest { + sender_monitor_id: monitor_id.to_vec(), + sender_subaddress: 0, + receiver_b58_code: b58_code.clone(), + amount: 1234, + ..Default::default() + }; let response = client.pay_address_code(&request).unwrap(); // Sanity the receiver receipt. - assert_eq!(response.get_receiver_tx_receipt_list().len(), 1); + assert_eq!(response.receiver_tx_receipt_list.len(), 1); - let receipt = &response.get_receiver_tx_receipt_list()[0]; + let receipt = &response.receiver_tx_receipt_list[0]; assert_eq!( - receipt.get_recipient(), + receipt.recipient.as_ref().unwrap(), &api::external::PublicAddress::from(&receiver_public_address) ); } @@ -7162,28 +7433,34 @@ mod test { // Generate b58 address code for this recipient. let receiver_public_address = receiver.default_subaddress(); - let mut wrapper = api::printable::PrintableWrapper::new(); - wrapper.set_public_address((&receiver_public_address).into()); + let wrapper = api::printable::PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress( + (&receiver_public_address).into(), + )), + }; let b58_code = wrapper.b58_encode().unwrap(); let test_amount = 345; - let mut request = api::PayAddressCodeRequest::new(); - request.set_sender_monitor_id(monitor_id.to_vec()); - request.set_sender_subaddress(0); - request.set_receiver_b58_code(b58_code); - request.set_amount(test_amount); - request.set_override_change_subaddress(true); - request.set_change_subaddress(1); - // Explicitly set fee so we can check change amount let fee = 1000; - request.set_fee(fee); + let request = api::PayAddressCodeRequest { + sender_monitor_id: monitor_id.to_vec(), + sender_subaddress: 0, + receiver_b58_code: b58_code.clone(), + amount: test_amount, + override_change_subaddress: true, + change_subaddress: 1, + fee, + ..Default::default() + }; let response = client.pay_address_code(&request).unwrap(); let total_value = response - .get_tx_proposal() - .get_input_list() + .tx_proposal + .as_ref() + .unwrap() + .input_list .iter() .map(|utxo| utxo.value) .sum::(); @@ -7262,106 +7539,119 @@ mod test { // Try with just a receiver { // Generate a request code - let mut request = api::CreateRequestCodeRequest::new(); - request.set_receiver(mc_api::external::PublicAddress::from(&receiver)); + let request = api::CreateRequestCodeRequest { + receiver: Some(mc_api::external::PublicAddress::from(&receiver)), + ..Default::default() + }; let response = client.create_request_code(&request).unwrap(); - let b58_code = response.get_b58_code(); + let b58_code = response.b58_code; // Attempt to decode the b58. - let mut request = api::ParseRequestCodeRequest::new(); - request.set_b58_code(b58_code.to_string()); + let request = api::ParseRequestCodeRequest { + b58_code: b58_code.to_string(), + }; let response = client.parse_request_code(&request).unwrap(); // Check that input equals output. assert_eq!( - PublicAddress::try_from(response.get_receiver()).unwrap(), + PublicAddress::try_from(response.receiver.as_ref().unwrap()).unwrap(), receiver ); assert_eq!(response.value, 0); - assert_eq!(response.get_memo(), ""); + assert_eq!(response.memo, ""); } // Try with receiver and value { // Generate a request code - let mut request = api::CreateRequestCodeRequest::new(); - request.set_receiver(mc_api::external::PublicAddress::from(&receiver)); - request.set_value(1234567890); + let request = api::CreateRequestCodeRequest { + receiver: Some(mc_api::external::PublicAddress::from(&receiver)), + value: 1234567890, + ..Default::default() + }; let response = client.create_request_code(&request).unwrap(); - let b58_code = response.get_b58_code(); + let b58_code = response.b58_code; // Attempt to decode it. - let mut request = api::ParseRequestCodeRequest::new(); - request.set_b58_code(b58_code.to_string()); + let request = api::ParseRequestCodeRequest { + b58_code: b58_code.to_string(), + }; let response = client.parse_request_code(&request).unwrap(); // Check that input equals output. assert_eq!( - PublicAddress::try_from(response.get_receiver()).unwrap(), + PublicAddress::try_from(response.receiver.as_ref().unwrap()).unwrap(), receiver ); assert_eq!(response.value, 1234567890); - assert_eq!(response.get_memo(), ""); + assert_eq!(response.memo, ""); } // Try with receiver, value and memo { // Generate a request code - let mut request = api::CreateRequestCodeRequest::new(); - request.set_receiver(mc_api::external::PublicAddress::from(&receiver)); - request.set_value(1234567890); - request.set_memo("hello there".to_owned()); + let request = api::CreateRequestCodeRequest { + receiver: Some(mc_api::external::PublicAddress::from(&receiver)), + value: 1234567890, + memo: "hello there".to_owned(), + ..Default::default() + }; let response = client.create_request_code(&request).unwrap(); - let b58_code = response.get_b58_code(); + let b58_code = response.b58_code; // Attempt to decode it. - let mut request = api::ParseRequestCodeRequest::new(); - request.set_b58_code(b58_code.to_string()); + let request = api::ParseRequestCodeRequest { + b58_code: b58_code.to_string(), + }; let response = client.parse_request_code(&request).unwrap(); // Check that input equals output. assert_eq!( - PublicAddress::try_from(response.get_receiver()).unwrap(), + PublicAddress::try_from(response.receiver.as_ref().unwrap()).unwrap(), receiver ); assert_eq!(response.value, 1234567890); - assert_eq!(response.get_memo(), "hello there"); + assert_eq!(response.memo, "hello there"); } // Try with receiver, value and token id. { // Generate a request code - let mut request = api::CreateRequestCodeRequest::new(); - request.set_receiver(mc_api::external::PublicAddress::from(&receiver)); - request.set_value(1234567890); - request.set_token_id(123); + let request = api::CreateRequestCodeRequest { + receiver: Some(mc_api::external::PublicAddress::from(&receiver)), + value: 1234567890, + token_id: 123, + ..Default::default() + }; let response = client.create_request_code(&request).unwrap(); - let b58_code = response.get_b58_code(); + let b58_code = response.b58_code; // Attempt to decode it. - let mut request = api::ParseRequestCodeRequest::new(); - request.set_b58_code(b58_code.to_string()); + let request = api::ParseRequestCodeRequest { + b58_code: b58_code.to_string(), + }; let response = client.parse_request_code(&request).unwrap(); // Check that input equals output. assert_eq!( - PublicAddress::try_from(response.get_receiver()).unwrap(), + PublicAddress::try_from(response.receiver.as_ref().unwrap()).unwrap(), receiver ); assert_eq!(response.value, 1234567890); - assert_eq!(response.get_token_id(), 123); + assert_eq!(response.token_id, 123); } // Attempting to decode junk data should fail { - let mut request = api::ParseRequestCodeRequest::new(); - request.set_b58_code("junk".to_owned()); + let request = api::ParseRequestCodeRequest { + b58_code: "junk".to_owned(), + }; assert!(client.parse_request_code(&request).is_err()); } @@ -7405,21 +7695,27 @@ mod test { // An invalid request should fail to encode. { - let mut request = api::CreateTransferCodeRequest::new(); - request.set_root_entropy(vec![3u8; 8]); // key is wrong size - request.set_tx_public_key((&tx_public_key).into()); - request.set_memo("memo".to_owned()); + let request = api::CreateTransferCodeRequest { + root_entropy: vec![3u8; 8], // key is wrong size + tx_public_key: Some((&tx_public_key).into()), + memo: "memo".to_owned(), + ..Default::default() + }; assert!(client.create_transfer_code(&request).is_err()); - let mut request = api::CreateTransferCodeRequest::new(); - request.set_root_entropy(vec![4u8; 32]); - request.set_memo("memo".to_owned()); // forgot to set tx_public_key + let request = api::CreateTransferCodeRequest { + root_entropy: vec![4u8; 32], + memo: "memo".to_owned(), + ..Default::default() // forgot to set tx_public_key + }; assert!(client.create_transfer_code(&request).is_err()); // no entropy is being set - let mut request = api::CreateTransferCodeRequest::new(); - request.set_tx_public_key((&tx_public_key).into()); - request.set_memo("memo".to_owned()); + let request = api::CreateTransferCodeRequest { + tx_public_key: Some((&tx_public_key).into()), + memo: "memo".to_owned(), + ..Default::default() + }; assert!(client.create_transfer_code(&request).is_err()); } @@ -7427,28 +7723,32 @@ mod test { // data. { // Encode - let mut request = api::CreateTransferCodeRequest::new(); - request.set_root_entropy(root_entropy.to_vec()); - request.set_tx_public_key((&tx_public_key).into()); - request.set_memo("test memo".to_owned()); + let request = api::CreateTransferCodeRequest { + root_entropy: root_entropy.to_vec(), + tx_public_key: Some((&tx_public_key).into()), + memo: "test memo".to_owned(), + ..Default::default() + }; let response = client.create_transfer_code(&request).unwrap(); - let b58_code = response.get_b58_code(); + let b58_code = response.b58_code; // Decode - let mut request = api::ParseTransferCodeRequest::new(); - request.set_b58_code(b58_code.to_string()); + let request = api::ParseTransferCodeRequest { + b58_code: b58_code.to_string(), + }; let response = client.parse_transfer_code(&request).unwrap(); // Compare - assert_eq!(&root_entropy, response.get_root_entropy()); - assert!(response.get_bip39_entropy().is_empty()); + assert_eq!(&root_entropy, response.root_entropy.as_slice()); + assert!(response.bip39_entropy.is_empty()); assert_eq!( tx_public_key, - CompressedRistrettoPublic::try_from(response.get_tx_public_key()).unwrap() + CompressedRistrettoPublic::try_from(response.tx_public_key.as_ref().unwrap()) + .unwrap() ); - assert_eq!(response.get_memo(), "test memo"); + assert_eq!(response.memo, "test memo"); // check that the utxo that comes back from the code matches the ledger data @@ -7476,7 +7776,7 @@ mod test { // Convert to proto utxo. let proto_utxo: api::UnspentTxOut = (&utxos[0]).into(); - assert_eq!(&proto_utxo, response.get_utxo()); + assert_eq!(&proto_utxo, response.utxo.as_ref().unwrap()); } } @@ -7518,15 +7818,19 @@ mod test { // An invalid request should fail to encode. { - let mut request = api::CreateTransferCodeRequest::new(); - request.set_bip39_entropy(vec![3u8; 8]); // key is wrong size - request.set_tx_public_key((&tx_public_key).into()); - request.set_memo("memo".to_owned()); + let request = api::CreateTransferCodeRequest { + bip39_entropy: vec![3u8; 8], // key is wrong size + tx_public_key: Some((&tx_public_key).into()), + memo: "memo".to_owned(), + ..Default::default() + }; assert!(client.create_transfer_code(&request).is_err()); - let mut request = api::CreateTransferCodeRequest::new(); - request.set_bip39_entropy(vec![4u8; 32]); - request.set_memo("memo".to_owned()); // forgot to set tx_public_key + let request = api::CreateTransferCodeRequest { + bip39_entropy: vec![4u8; 32], + memo: "memo".to_owned(), // forgot to set tx_public_key + ..Default::default() + }; assert!(client.create_transfer_code(&request).is_err()); } @@ -7534,28 +7838,32 @@ mod test { // data. { // Encode - let mut request = api::CreateTransferCodeRequest::new(); - request.set_bip39_entropy(bip39_entropy.to_vec()); - request.set_tx_public_key((&tx_public_key).into()); - request.set_memo("test memo".to_owned()); + let request = api::CreateTransferCodeRequest { + bip39_entropy: bip39_entropy.to_vec(), + tx_public_key: Some((&tx_public_key).into()), + memo: "test memo".to_owned(), + ..Default::default() + }; let response = client.create_transfer_code(&request).unwrap(); - let b58_code = response.get_b58_code(); + let b58_code = response.b58_code; // Decode - let mut request = api::ParseTransferCodeRequest::new(); - request.set_b58_code(b58_code.to_string()); + let request = api::ParseTransferCodeRequest { + b58_code: b58_code.clone(), + }; let response = client.parse_transfer_code(&request).unwrap(); // Compare - assert_eq!(&bip39_entropy, response.get_bip39_entropy()); - assert!(response.get_root_entropy().is_empty()); + assert_eq!(&bip39_entropy, response.bip39_entropy.as_slice()); + assert!(response.root_entropy.is_empty()); assert_eq!( tx_public_key, - CompressedRistrettoPublic::try_from(response.get_tx_public_key()).unwrap() + CompressedRistrettoPublic::try_from(response.tx_public_key.as_ref().unwrap()) + .unwrap() ); - assert_eq!(response.get_memo(), "test memo"); + assert_eq!(response.memo, "test memo"); // check that the utxo that comes back from the code matches the ledger data @@ -7583,7 +7891,7 @@ mod test { // Convert to proto utxo. let proto_utxo: api::UnspentTxOut = (&utxos[0]).into(); - assert_eq!(&proto_utxo, response.get_utxo()); + assert_eq!(&proto_utxo, response.utxo.as_ref().unwrap()); } } @@ -7600,21 +7908,23 @@ mod test { let receiver = AccountKey::random(&mut rng).default_subaddress(); // Generate a request code - let mut request = api::CreateAddressCodeRequest::new(); - request.set_receiver(mc_api::external::PublicAddress::from(&receiver)); + let request = api::CreateAddressCodeRequest { + receiver: Some(mc_api::external::PublicAddress::from(&receiver)), + }; let response = client.create_address_code(&request).unwrap(); - let b58_code = response.get_b58_code(); + let b58_code = response.b58_code; // Attempt to decode it. - let mut request = api::ParseAddressCodeRequest::new(); - request.set_b58_code(b58_code.to_string()); + let request = api::ParseAddressCodeRequest { + b58_code: b58_code.to_string(), + }; let response = client.parse_address_code(&request).unwrap(); // Check that input equals output. assert_eq!( - PublicAddress::try_from(response.get_receiver()).unwrap(), + PublicAddress::try_from(response.receiver.as_ref().unwrap()).unwrap(), receiver ); } @@ -7625,31 +7935,35 @@ mod test { let receiver = AccountKey::random(&mut rng).default_subaddress(); // Generate a request code - let mut request = api::CreateRequestCodeRequest::new(); - request.set_receiver(mc_api::external::PublicAddress::from(&receiver)); - request.set_value(1234567890); - request.set_memo("hello there".to_owned()); + let request = api::CreateRequestCodeRequest { + receiver: Some(mc_api::external::PublicAddress::from(&receiver)), + value: 1234567890, + memo: "hello there".to_owned(), + ..Default::default() + }; let response = client.create_request_code(&request).unwrap(); - let b58_code = response.get_b58_code(); + let b58_code = response.b58_code; // Attempt to decode it. - let mut request = api::ParseAddressCodeRequest::new(); - request.set_b58_code(b58_code.to_string()); + let request = api::ParseAddressCodeRequest { + b58_code: b58_code.to_string(), + }; let response = client.parse_address_code(&request).unwrap(); // Check that input equals output. assert_eq!( - PublicAddress::try_from(response.get_receiver()).unwrap(), + PublicAddress::try_from(response.receiver.as_ref().unwrap()).unwrap(), receiver ); } // Attempting to decode junk data should fail { - let mut request = api::ParseAddressCodeRequest::new(); - request.set_b58_code("junk".to_owned()); + let request = api::ParseAddressCodeRequest { + b58_code: "junk".to_owned(), + }; assert!(client.parse_address_code(&request).is_err()); } @@ -7662,7 +7976,7 @@ mod test { let (ledger_db, _mobilecoind_db, client, _server, _server_conn_manager) = get_testing_environment(BLOCK_VERSION, 3, &[], &[], logger, &mut rng); - let network_status = client.get_network_status(&api::Empty::new()).unwrap(); + let network_status = client.get_network_status(&()).unwrap(); assert_eq!( network_status.network_highest_block_index, @@ -7700,23 +8014,27 @@ mod test { &mut rng, ); - let mut request = api::AddMonitorRequest::new(); - request.set_account_key(mc_api::external::AccountKey::from(&data.account_key)); - request.set_first_subaddress(data.first_subaddress); - request.set_num_subaddresses(data.num_subaddresses); - request.set_first_block(data.first_block); + let request = api::AddMonitorRequest { + account_key: Some((&data.account_key).into()), + first_subaddress: data.first_subaddress, + num_subaddresses: data.num_subaddresses, + first_block: data.first_block, + ..Default::default() + }; // Send request. let response = client.add_monitor(&request).expect("failed to add monitor"); - let monitor_id = response.get_monitor_id(); + let monitor_id = response.monitor_id; // Allow the new monitor to process the ledger. wait_for_monitors(&mobilecoind_db, &ledger_db, &logger); // Verify we have the expected balance. - let mut request = api::GetBalanceRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); - request.set_subaddress_index(0); + let request = api::GetBalanceRequest { + monitor_id: monitor_id.to_vec(), + subaddress_index: 0, + ..Default::default() + }; let response = client.get_balance(&request).unwrap(); assert_eq!( @@ -7727,16 +8045,18 @@ mod test { // Get our UTXOs and force one of them to be spent, since we want to test the // add-remove-add behavior with spent key images in the ledger. - let mut request = api::GetUnspentTxOutListRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); - request.set_subaddress_index(0); + let request = api::GetUnspentTxOutListRequest { + monitor_id: monitor_id.to_vec(), + subaddress_index: 0, + ..Default::default() + }; let response = client .get_unspent_tx_out_list(&request) .expect("failed to get unspent tx out list"); let first_utxo = response.output_list[0].clone(); - let first_key_image = KeyImage::try_from(first_utxo.get_key_image()) + let first_key_image = KeyImage::try_from(first_utxo.key_image.as_ref().unwrap()) .expect("failed covnerting proto keyimage"); let recipient = AccountKey::random(&mut rng).default_subaddress(); @@ -7753,26 +8073,30 @@ mod test { wait_for_monitors(&mobilecoind_db, &ledger_db, &logger); // Verify we have the expected balance. - let mut request = api::GetBalanceRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); - request.set_subaddress_index(0); + let request = api::GetBalanceRequest { + monitor_id: monitor_id.to_vec(), + subaddress_index: 0, + ..Default::default() + }; let response = client.get_balance(&request).unwrap(); assert_eq!(response.balance, orig_balance - first_utxo.value); // Verify we have processed block information for this monitor. - let mut request = api::GetProcessedBlockRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); - request.set_block(0); + let request = api::GetProcessedBlockRequest { + monitor_id: monitor_id.to_vec(), + block: 0, + }; let response = client .get_processed_block(&request) .expect("Failed getting processed block"); - assert_eq!(response.get_tx_outs().len(), 1); + assert_eq!(response.tx_outs.len(), 1); // Remove the monitor. - let mut request = api::RemoveMonitorRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); + let request = api::RemoveMonitorRequest { + monitor_id: monitor_id.to_vec(), + }; client .remove_monitor(&request) .expect("failed to remove monitor"); @@ -7782,34 +8106,38 @@ mod test { assert_eq!(0, monitors_map.len()); // Verify we no longer have processed block information for this monitor. - let mut request = api::GetProcessedBlockRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); - request.set_block(0); + let request = api::GetProcessedBlockRequest { + monitor_id: monitor_id.to_vec(), + block: 0, + }; assert!(client.get_processed_block(&request).is_err()); // Re-add the monitor. - let mut request = api::AddMonitorRequest::new(); - request.set_account_key(mc_api::external::AccountKey::from(&data.account_key)); - request.set_first_subaddress(data.first_subaddress); - request.set_num_subaddresses(data.num_subaddresses); - request.set_first_block(data.first_block); + let request = api::AddMonitorRequest { + account_key: Some((&data.account_key).into()), + first_subaddress: data.first_subaddress, + num_subaddresses: data.num_subaddresses, + first_block: data.first_block, + ..Default::default() + }; let response = client.add_monitor(&request).expect("failed to add monitor"); - assert_eq!(monitor_id, response.get_monitor_id()); + assert_eq!(monitor_id, response.monitor_id); // Allow the new monitor to process the ledger. wait_for_monitors(&mobilecoind_db, &ledger_db, &logger); // Verify we have processed block information for this monitor. - let mut request = api::GetProcessedBlockRequest::new(); - request.set_monitor_id(monitor_id.to_vec()); - request.set_block(0); + let request = api::GetProcessedBlockRequest { + monitor_id: monitor_id.to_vec(), + block: 0, + }; let response = client .get_processed_block(&request) .expect("Failed getting processed block"); - assert_eq!(response.get_tx_outs().len(), 1); + assert_eq!(response.tx_outs.len(), 1); } #[test_with_logger] @@ -7829,9 +8157,7 @@ mod test { ); // Send request. - let response = client - .get_version(&api::Empty::new()) - .expect("Failed to get version"); + let response = client.get_version(&()).expect("Failed to get version"); assert!(!response.version.is_empty()); } } diff --git a/mobilecoind/src/t3_store.rs b/mobilecoind/src/t3_store.rs index 585e8ccd4d..bbe72b93ca 100644 --- a/mobilecoind/src/t3_store.rs +++ b/mobilecoind/src/t3_store.rs @@ -14,7 +14,7 @@ use mc_common::logger::{log, Logger}; use mc_t3_api::TransparentTransaction; use mc_transaction_core::MemoPayload; use mc_transaction_extra::MemoType; -use protobuf::Message; +use prost::Message; use std::sync::Arc; // LMDB Database Names @@ -138,15 +138,14 @@ impl T3Store { } }; - let public_key = mc_t3_api::external::CompressedRistretto { + let public_key = mc_t3_api::external::v1::CompressedRistretto { data: utxo.tx_out.public_key.as_bytes().to_vec(), - ..Default::default() }; let reported_direction = if sender_address_hash == our_short_address_hash { - mc_t3_api::ReportedDirection::REPORTED_DIRECTION_SEND + mc_t3_api::ReportedDirection::Send } else { - mc_t3_api::ReportedDirection::REPORTED_DIRECTION_RECEIVE + mc_t3_api::ReportedDirection::Receive }; let ttx = TransparentTransaction { @@ -154,9 +153,9 @@ impl T3Store { recipient_address_hash: recipient_address_hash.as_ref().to_vec(), token_id: utxo.token_id, amount: utxo.value, - public_key: Some(public_key).into(), + public_key: Some(public_key), public_key_hex: format!("{}", HexFmt(utxo.tx_out.public_key.as_bytes())), - reported_direction, + reported_direction: reported_direction.into(), ..Default::default() }; @@ -180,7 +179,7 @@ impl T3Store { ) -> Result<(), Error> { let index = self.get_transparent_tx_counter(db_txn)?; let index_bytes = index.to_be_bytes(); - let tx_bytes = tx.write_to_bytes()?; + let tx_bytes = tx.encode_to_vec(); db_txn.put( self.index_to_transparent_tx, @@ -229,7 +228,7 @@ impl T3Store { Ok(Some(( first_index, - TransparentTransaction::parse_from_bytes(transparent_tx_bytes)?, + TransparentTransaction::decode(transparent_tx_bytes)?, ))) } diff --git a/mobilecoind/src/test_utils.rs b/mobilecoind/src/test_utils.rs index 1931b0a6de..f4c982c127 100644 --- a/mobilecoind/src/test_utils.rs +++ b/mobilecoind/src/test_utils.rs @@ -19,7 +19,7 @@ use mc_consensus_scp::QuorumSet; use mc_fog_report_validation_test_utils::{FogPubkeyResolver, MockFogResolver}; use mc_ledger_db::{test_utils::recreate_ledger_db, Ledger, LedgerDB}; use mc_ledger_sync::PollingNetworkState; -use mc_mobilecoind_api::{mobilecoind_api_grpc::MobilecoindApiClient, MobilecoindUri}; +use mc_mobilecoind_api::{mobilecoind_api::MobilecoindApiClient, MobilecoindUri}; use mc_rand::{CryptoRng, RngCore}; use mc_transaction_core::{ring_signature::KeyImage, tokens::Mob, Amount, FeeMap, Token, TokenId}; use mc_util_grpc::ConnectionUriGrpcioChannel; diff --git a/mobilecoind/src/transaction_memo.rs b/mobilecoind/src/transaction_memo.rs index 07c0da963b..e0aa2fc6a5 100644 --- a/mobilecoind/src/transaction_memo.rs +++ b/mobilecoind/src/transaction_memo.rs @@ -2,9 +2,7 @@ use mc_account_keys::AccountKey; use mc_api::ConversionError; -use mc_mobilecoind_api::{ - mobilecoind_api, TransactionMemo_RTH_oneof_payment_id, TransactionMemo_oneof_transaction_memo, -}; +use mc_mobilecoind_api::{mobilecoind_api, transaction_memo, transaction_memo_rth}; use mc_transaction_builder::{ BurnRedemptionMemoBuilder, EmptyMemoBuilder, MemoBuilder, RTHMemoBuilder, }; @@ -107,34 +105,30 @@ impl TryFrom<&mobilecoind_api::TransactionMemo> for TransactionMemo { subaddress_index: None, }), - Some(TransactionMemo_oneof_transaction_memo::rth(rth)) => { - let subaddress_index = if rth.has_subaddress_index() { - Some(rth.get_subaddress_index()) - } else { - None - }; + Some(transaction_memo::TransactionMemo::Rth(rth)) => { + let subaddress_index = rth.subaddress_index; match rth.payment_id.as_ref() { None => Ok(TransactionMemo::Rth { subaddress_index }), - Some(TransactionMemo_RTH_oneof_payment_id::payment_intent_id( - payment_intent_id, - )) => Ok(TransactionMemo::RthWithPaymentIntentId { - subaddress_index, - payment_intent_id: *payment_intent_id, - }), - - Some(TransactionMemo_RTH_oneof_payment_id::payment_request_id( - payment_request_id, - )) => Ok(TransactionMemo::RthWithPaymentRequestId { - subaddress_index, - payment_request_id: *payment_request_id, - }), + Some(transaction_memo_rth::PaymentId::PaymentIntentId(payment_intent_id)) => { + Ok(TransactionMemo::RthWithPaymentIntentId { + subaddress_index, + payment_intent_id: *payment_intent_id, + }) + } + + Some(transaction_memo_rth::PaymentId::PaymentRequestId(payment_request_id)) => { + Ok(TransactionMemo::RthWithPaymentRequestId { + subaddress_index, + payment_request_id: *payment_request_id, + }) + } } } - Some(TransactionMemo_oneof_transaction_memo::empty(_)) => Ok(TransactionMemo::Empty), + Some(transaction_memo::TransactionMemo::Empty(_)) => Ok(TransactionMemo::Empty), - Some(TransactionMemo_oneof_transaction_memo::burn_redemption(burn_redemption)) => { + Some(transaction_memo::TransactionMemo::BurnRedemption(burn_redemption)) => { if burn_redemption.memo_data.len() != BurnRedemptionMemo::MEMO_DATA_LEN { return Err(ConversionError::ArrayCastError); } @@ -165,10 +159,7 @@ mod tests { #[test] fn transaction_memo_try_from_rth_default() { let src = mobilecoind_api::TransactionMemo { - transaction_memo: Some(TransactionMemo_oneof_transaction_memo::rth( - mc_mobilecoind_api::TransactionMemo_RTH::default(), - )), - ..Default::default() + transaction_memo: Some(transaction_memo::TransactionMemo::Rth(Default::default())), }; let result = super::TransactionMemo::try_from(&src).unwrap(); assert_eq!( @@ -182,12 +173,13 @@ mod tests { #[test] fn transaction_memo_try_from_rth_explicit_subaddress_index() { for subaddress_index in [0, 123, u64::MAX] { - let mut rth = mc_mobilecoind_api::TransactionMemo_RTH::default(); - rth.set_subaddress_index(subaddress_index); - let src = mobilecoind_api::TransactionMemo { - transaction_memo: Some(TransactionMemo_oneof_transaction_memo::rth(rth)), + let rth = mc_mobilecoind_api::TransactionMemoRth { + subaddress_index: Some(subaddress_index), ..Default::default() }; + let src = mobilecoind_api::TransactionMemo { + transaction_memo: Some(transaction_memo::TransactionMemo::Rth(rth)), + }; let result = super::TransactionMemo::try_from(&src).unwrap(); assert_eq!( @@ -201,12 +193,13 @@ mod tests { #[test] fn transaction_memo_try_from_rth_payment_request_id() { - let mut rth = mc_mobilecoind_api::TransactionMemo_RTH::default(); - rth.set_payment_request_id(123); - let src = mobilecoind_api::TransactionMemo { - transaction_memo: Some(TransactionMemo_oneof_transaction_memo::rth(rth.clone())), + let mut rth = mc_mobilecoind_api::TransactionMemoRth { + payment_id: Some(transaction_memo_rth::PaymentId::PaymentRequestId(123)), ..Default::default() }; + let src = mobilecoind_api::TransactionMemo { + transaction_memo: Some(transaction_memo::TransactionMemo::Rth(rth.clone())), + }; let result = super::TransactionMemo::try_from(&src).unwrap(); assert_eq!( @@ -217,10 +210,9 @@ mod tests { } ); - rth.set_subaddress_index(456); + rth.subaddress_index = Some(456); let src = mobilecoind_api::TransactionMemo { - transaction_memo: Some(TransactionMemo_oneof_transaction_memo::rth(rth)), - ..Default::default() + transaction_memo: Some(transaction_memo::TransactionMemo::Rth(rth)), }; let result = super::TransactionMemo::try_from(&src).unwrap(); @@ -235,12 +227,13 @@ mod tests { #[test] fn transaction_memo_try_from_rth_payment_intent_id() { - let mut rth = mc_mobilecoind_api::TransactionMemo_RTH::default(); - rth.set_payment_intent_id(123); - let src = mobilecoind_api::TransactionMemo { - transaction_memo: Some(TransactionMemo_oneof_transaction_memo::rth(rth.clone())), + let mut rth = mc_mobilecoind_api::TransactionMemoRth { + payment_id: Some(transaction_memo_rth::PaymentId::PaymentIntentId(123)), ..Default::default() }; + let src = mobilecoind_api::TransactionMemo { + transaction_memo: Some(transaction_memo::TransactionMemo::Rth(rth.clone())), + }; let result = super::TransactionMemo::try_from(&src).unwrap(); assert_eq!( @@ -251,10 +244,9 @@ mod tests { } ); - rth.set_subaddress_index(456); + rth.subaddress_index = Some(456); let src = mobilecoind_api::TransactionMemo { - transaction_memo: Some(TransactionMemo_oneof_transaction_memo::rth(rth)), - ..Default::default() + transaction_memo: Some(transaction_memo::TransactionMemo::Rth(rth)), }; let result = super::TransactionMemo::try_from(&src).unwrap(); @@ -270,10 +262,7 @@ mod tests { #[test] fn transaction_memo_try_from_empty() { let src = mobilecoind_api::TransactionMemo { - transaction_memo: Some(TransactionMemo_oneof_transaction_memo::empty( - Default::default(), - )), - ..Default::default() + transaction_memo: Some(transaction_memo::TransactionMemo::Empty(Default::default())), }; let result = super::TransactionMemo::try_from(&src).unwrap(); assert_eq!(result, super::TransactionMemo::Empty); @@ -282,49 +271,41 @@ mod tests { #[test] fn transaction_memo_try_from_burn_redemption() { let src = mobilecoind_api::TransactionMemo { - transaction_memo: Some(TransactionMemo_oneof_transaction_memo::burn_redemption( + transaction_memo: Some(transaction_memo::TransactionMemo::BurnRedemption( Default::default(), )), - ..Default::default() }; let result = super::TransactionMemo::try_from(&src).unwrap_err(); assert_eq!(result, ConversionError::ArrayCastError); - let burn_redemption = mc_mobilecoind_api::TransactionMemo_BurnRedemption { - memo_data: vec![], - ..Default::default() - }; + let burn_redemption = + mc_mobilecoind_api::TransactionMemoBurnRedemption { memo_data: vec![] }; let src = mobilecoind_api::TransactionMemo { - transaction_memo: Some(TransactionMemo_oneof_transaction_memo::burn_redemption( + transaction_memo: Some(transaction_memo::TransactionMemo::BurnRedemption( burn_redemption, )), - ..Default::default() }; let result = super::TransactionMemo::try_from(&src).unwrap_err(); assert_eq!(result, ConversionError::ArrayCastError); - let burn_redemption = mc_mobilecoind_api::TransactionMemo_BurnRedemption { + let burn_redemption = mc_mobilecoind_api::TransactionMemoBurnRedemption { memo_data: vec![1; BurnRedemptionMemo::MEMO_DATA_LEN - 1], - ..Default::default() }; let src = mobilecoind_api::TransactionMemo { - transaction_memo: Some(TransactionMemo_oneof_transaction_memo::burn_redemption( + transaction_memo: Some(transaction_memo::TransactionMemo::BurnRedemption( burn_redemption, )), - ..Default::default() }; let result = super::TransactionMemo::try_from(&src).unwrap_err(); assert_eq!(result, ConversionError::ArrayCastError); - let burn_redemption = mc_mobilecoind_api::TransactionMemo_BurnRedemption { + let burn_redemption = mc_mobilecoind_api::TransactionMemoBurnRedemption { memo_data: vec![1; BurnRedemptionMemo::MEMO_DATA_LEN], - ..Default::default() }; let src = mobilecoind_api::TransactionMemo { - transaction_memo: Some(TransactionMemo_oneof_transaction_memo::burn_redemption( + transaction_memo: Some(transaction_memo::TransactionMemo::BurnRedemption( burn_redemption, )), - ..Default::default() }; let result = super::TransactionMemo::try_from(&src).unwrap(); diff --git a/peers/Cargo.toml b/peers/Cargo.toml index 79296a91af..fa35489b3a 100644 --- a/peers/Cargo.toml +++ b/peers/Cargo.toml @@ -30,9 +30,8 @@ mc-util-uri = { path = "../util/uri" } crossbeam-channel = "0.5" displaydoc = "0.2" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } mockall = "0.12.1" -protobuf = "2.27.1" retry = "2.0" serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } diff --git a/peers/src/connection.rs b/peers/src/connection.rs index 55ca3a6616..60e7ec86b8 100644 --- a/peers/src/connection.rs +++ b/peers/src/connection.rs @@ -9,7 +9,7 @@ use crate::{ }; use core::fmt::{Display, Formatter, Result as FmtResult}; use grpcio::{ChannelBuilder, Environment, Error as GrpcError}; -use mc_attest_api::attest_grpc::AttestedApiClient; +use mc_attest_api::attest::AttestedApiClient; use mc_attest_core::EvidenceKind; use mc_attest_enclave_api::PeerSession; use mc_blockchain_types::{Block, BlockID, BlockIndex}; @@ -22,14 +22,12 @@ use mc_connection::{ Result as ConnectionResult, }; use mc_consensus_api::{ - consensus_common::BlocksRequest, - consensus_common_grpc::BlockchainApiClient, + blockchain, + consensus_common::{BlockchainApiClient, BlocksRequest}, consensus_peer::{ - ConsensusMsg as GrpcConsensusMsg, ConsensusMsgResponse, - GetTxsRequest as GrpcFetchTxsRequest, + get_txs_response::Payload, ConsensusMsg as GrpcConsensusMsg, ConsensusMsgResponse, + ConsensusPeerApiClient, GetTxsRequest as GrpcFetchTxsRequest, }, - consensus_peer_grpc::ConsensusPeerApiClient, - empty::Empty, ConversionError, }; use mc_consensus_enclave_api::{ConsensusEnclave, TxContext, WellFormedEncryptedTx}; @@ -37,7 +35,6 @@ use mc_transaction_core::tx::TxHash; use mc_util_grpc::ConnectionUriGrpcioChannel; use mc_util_serial::{deserialize, serialize}; use mc_util_uri::{ConnectionUri, ConsensusPeerUri as PeerUri}; -use protobuf::RepeatedField; use std::{ cmp::Ordering, hash::{Hash, Hasher}, @@ -208,16 +205,16 @@ impl BlockchainConnection fn fetch_blocks(&mut self, range: Range) -> ConnectionResult> { trace_time!(self.logger, "PeerConnection::get_blocks"); - let mut request = BlocksRequest::new(); - request.set_offset(range.start); - let limit = - u32::try_from(range.end - range.start).or(Err(ConnectionError::RequestTooLarge))?; - request.set_limit(limit); + let request = BlocksRequest { + offset: range.start, + limit: u32::try_from(range.end - range.start) + .or(Err(ConnectionError::RequestTooLarge))?, + }; self.log_attested_call("fetch_blocks", |this| { this.blockchain_api_client.get_blocks(&request) })? - .get_blocks() + .blocks .iter() .map(|proto_block| Block::try_from(proto_block).map_err(ConnectionError::from)) .collect::>>() @@ -226,17 +223,19 @@ impl BlockchainConnection fn fetch_block_ids(&mut self, range: Range) -> ConnectionResult> { trace_time!(self.logger, "PeerConnection::get_blocks"); - let mut request = BlocksRequest::new(); - request.set_offset(range.start); - let limit = - u32::try_from(range.end - range.start).or(Err(ConnectionError::RequestTooLarge))?; - request.set_limit(limit); + let request = BlocksRequest { + offset: range.start, + limit: u32::try_from(range.end - range.start) + .or(Err(ConnectionError::RequestTooLarge))?, + }; + let default_block = blockchain::BlockId::default(); self.attested_call(|this| this.blockchain_api_client.get_blocks(&request))? - .get_blocks() + .blocks .iter() .map(|proto_block| { - BlockID::try_from(proto_block.get_id()).map_err(ConnectionError::from) + BlockID::try_from(proto_block.id.as_ref().unwrap_or(&default_block)) + .map_err(ConnectionError::from) }) .collect::>>() } @@ -246,8 +245,7 @@ impl BlockchainConnection Ok(self .log_attested_call("fetch_block_height", |this| { - this.blockchain_api_client - .get_last_block_info(&Empty::new()) + this.blockchain_api_client.get_last_block_info(&()) })? .index) } @@ -256,8 +254,7 @@ impl BlockchainConnection trace_time!(self.logger, "PeerConnection::fetch_block_info"); let block_info = self.log_attested_call("fetch_block_info", |this| { - this.blockchain_api_client - .get_last_block_info(&Empty::new()) + this.blockchain_api_client.get_last_block_info(&()) })?; Ok(block_info.into()) } @@ -275,9 +272,10 @@ impl ConsensusConnection } fn send_consensus_msg(&mut self, msg: &ConsensusMsg) -> Result { - let mut grpc_msg = GrpcConsensusMsg::default(); - grpc_msg.set_from_responder_id(self.local_node_id.responder_id.to_string()); - grpc_msg.set_payload(serialize(&msg)?); + let grpc_msg = GrpcConsensusMsg { + from_responder_id: self.local_node_id.responder_id.to_string(), + payload: serialize(&msg)?, + }; let response = self.log_attested_call("send_consensus_msg", |this| { this.consensus_api_client.send_consensus_msg(&grpc_msg) @@ -317,43 +315,39 @@ impl ConsensusConnection self.attest()?; } - let mut request = GrpcFetchTxsRequest::new(); - request.set_channel_id(self.channel_id.as_ref().unwrap().as_ref().to_vec()); - request.set_tx_hashes(RepeatedField::from_vec( - hashes.iter().map(|tx| tx.to_vec()).collect(), - )); + let request = GrpcFetchTxsRequest { + channel_id: self.channel_id.as_ref().unwrap().as_ref().to_vec(), + tx_hashes: hashes.iter().map(|tx| tx.to_vec()).collect(), + }; - let mut response = self.log_attested_call("get_txs", |this| { + let response = self.log_attested_call("get_txs", |this| { this.consensus_api_client.get_txs(&request) })?; - if response.has_tx_hashes_not_in_cache() { - let tx_hashes = response - .get_tx_hashes_not_in_cache() - .get_tx_hashes() - .iter() - .map(|tx_hash_bytes| { - TxHash::try_from(&tx_hash_bytes[..]) - .map_err(|_| Error::Conversion(ConversionError::ArrayCastError)) - }) - .collect::, _>>()?; - return Err(Error::TxHashesNotInCache(tx_hashes)); + match response.payload { + Some(Payload::TxHashesNotInCache(not_in_cache)) => { + let tx_hashes = not_in_cache + .tx_hashes + .iter() + .map(|tx_hash_bytes| { + TxHash::try_from(&tx_hash_bytes[..]) + .map_err(|_| Error::Conversion(ConversionError::ArrayCastError)) + }) + .collect::, _>>()?; + Err(Error::TxHashesNotInCache(tx_hashes)) + } + Some(Payload::Success(message)) => Ok(self.enclave.peer_tx_propose(message.into())?), + _ => Err(Error::NotFound), } - - let tx_contexts = self - .enclave - .peer_tx_propose(response.take_success().into())?; - - Ok(tx_contexts) } fn fetch_latest_msg(&mut self) -> Result> { let response = self.log_attested_call("get_latest_msg", |this| { - this.consensus_api_client.get_latest_msg(&Empty::new()) + this.consensus_api_client.get_latest_msg(&()) })?; - if response.get_payload().is_empty() { + if response.payload.is_empty() { Ok(None) } else { - let msg = deserialize::(response.get_payload())?; + let msg = deserialize::(response.payload.as_slice())?; Ok(Some(msg)) } diff --git a/peers/src/threaded_broadcaster.rs b/peers/src/threaded_broadcaster.rs index a8b2726a10..b0e46d0ce6 100644 --- a/peers/src/threaded_broadcaster.rs +++ b/peers/src/threaded_broadcaster.rs @@ -399,7 +399,7 @@ impl PeerThread { let retry_iterator = retry_policy.get_delay_iterator().with_deadline(deadline); match conn.send_consensus_msg(&arc_msg, retry_iterator) { - Ok(resp) => match resp.get_result() { + Ok(resp) => match resp.result() { ConsensusMsgResult::Ok => {} ConsensusMsgResult::UnknownPeer => log::info!( logger, diff --git a/peers/test-utils/Cargo.toml b/peers/test-utils/Cargo.toml index cbf723fcca..7004dfe9a4 100644 --- a/peers/test-utils/Cargo.toml +++ b/peers/test-utils/Cargo.toml @@ -21,7 +21,7 @@ mc-transaction-core = { path = "../../transaction/core" } mc-util-from-random = { path = "../../util/from-random" } mc-util-uri = { path = "../../util/uri" } -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } hex = "0.4" rand = "0.8" rand_hc = "0.3" diff --git a/peers/test-utils/src/lib.rs b/peers/test-utils/src/lib.rs index c44446b5d9..c378a8997e 100644 --- a/peers/test-utils/src/lib.rs +++ b/peers/test-utils/src/lib.rs @@ -199,8 +199,9 @@ impl ConsensusConnection for MockPeerConnection { } locked_state.msgs.push_back(msg.clone()); - let mut resp = ConsensusMsgResponse::new(); - resp.set_result(ConsensusMsgResult::Ok); + let resp = ConsensusMsgResponse { + result: ConsensusMsgResult::Ok.into(), + }; Ok(resp) } diff --git a/t3/api/Cargo.toml b/t3/api/Cargo.toml index cb7eb5270b..60612a3657 100644 --- a/t3/api/Cargo.toml +++ b/t3/api/Cargo.toml @@ -9,8 +9,8 @@ rust-version = { workspace = true } [dependencies] futures = "0.3" -grpcio = "0.13" -protobuf = "2.27.1" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } +prost = { version = "0.11", default-features = false } mc-util-uri = { path = "../../util/uri" } diff --git a/t3/api/proto/external/v1/external.proto b/t3/api/proto/external/v1/external.proto index 7e4def6ab0..dacaa5ebc6 100644 --- a/t3/api/proto/external/v1/external.proto +++ b/t3/api/proto/external/v1/external.proto @@ -50,7 +50,9 @@ message Ed25519Signature { // `account-keys` crate // -// Complete AccountKey, containing the pair of secret keys, which can be used +// Complete AccountKey +// +// Contains the pair of secret keys, which can be used // for spending, and optionally some Fog related info that is used to form // public addresses for accounts that sign up with Fog service. // @@ -100,6 +102,8 @@ message PublicAddress { bytes fog_authority_sig = 5; } +// A compact form of a user's account key +// // A KDF can be used to stretch a 32 byte secret into multiple secret private keys. // The RootIdentity is a compact form of a user's account key, if it has been // derived in this way. This may be useful for e.g. paper wallets. @@ -120,9 +124,10 @@ message RootEntropy { bytes data = 1; } -// A ViewKey is a reduced AccountKey -- it contains the private key necessary to -// view your transactions and see the amounts, but not to send new transactions. -// This concept is part of Cryptonote. +// A ViewKey is a reduced AccountKey +// +// It contains the private key necessary to view your transactions and see the +// amounts, but not to send new transactions. This concept is part of Cryptonote. // In Mobilecoin, all public addresses correspond to subaddresses, and often // the "default subaddress" is used. // The ViewKey similarly corresponds to a particular subaddress. @@ -140,6 +145,7 @@ message ViewKey { // // A 32-byte scalar associated to the ristretto group. +// // This is the same as RistrettoPrivate, but they are used in different places. // TODO: MC-1605 Consider to factor out this type, or just this proto message. message CurveScalar { diff --git a/t3/api/src/lib.rs b/t3/api/src/lib.rs index 7d1dd0ead8..341ed1ffc2 100644 --- a/t3/api/src/lib.rs +++ b/t3/api/src/lib.rs @@ -2,24 +2,20 @@ //! T3 gRPC API. -// workaround for #![allow(box_pointers)] in protobuf generated files. -#![allow(renamed_and_removed_lints)] - use mc_util_uri::{Uri, UriScheme}; mod autogenerated_code { - pub use protobuf::well_known_types::Empty; - - // Needed due to how to the auto-generated code references the Empty message. - pub mod empty { - pub use protobuf::well_known_types::Empty; + pub mod t3_v1 { + include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/t3.v1.rs")); + } + pub mod external { + pub mod v1 { + include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/external.v1.rs")); + } } - - // Include the auto-generated code. - include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/mod.rs")); } -pub use autogenerated_code::{t3::*, *}; +pub use autogenerated_code::{t3_v1::*, *}; pub type T3Uri = Uri; diff --git a/t3/connection/Cargo.toml b/t3/connection/Cargo.toml index e35496cd09..8dbab59c5b 100644 --- a/t3/connection/Cargo.toml +++ b/t3/connection/Cargo.toml @@ -10,8 +10,7 @@ rust-version = { workspace = true } [dependencies] displaydoc = { version = "0.2", default-features = false } futures = "0.3" -grpcio = "0.13" -protobuf = "2.27.1" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } mc-common = { path = "../../common", features = ["log"] } mc-connection = { path = "../../connection" } diff --git a/t3/connection/src/lib.rs b/t3/connection/src/lib.rs index 15a2919af8..27f4f44404 100644 --- a/t3/connection/src/lib.rs +++ b/t3/connection/src/lib.rs @@ -7,7 +7,7 @@ use grpcio::{CallOption, ChannelBuilder, EnvBuilder, MetadataBuilder}; use mc_common::logger::Logger; use mc_connection::Connection; use mc_t3_api::{ - external::CompressedRistretto, t3_grpc::TransactionServiceClient, CreateTransactionRequest, + external::v1::CompressedRistretto, t3_v1::TransactionServiceClient, CreateTransactionRequest, FindTransactionsRequest, ListTransactionsRequest, T3Uri, TestErrorRequest, TransparentTransaction, }; @@ -60,49 +60,49 @@ impl T3Connection { public_keys: Vec, public_key_hex: Vec, ) -> Result, Error> { - let mut request = FindTransactionsRequest::new(); - request.set_address_hashes(address_hashes.into()); - request.set_public_keys(public_keys.into()); - request.set_public_key_hex(public_key_hex.into()); + let request = FindTransactionsRequest { + address_hashes: address_hashes.clone(), + public_keys: public_keys.clone(), + public_key_hex: public_key_hex.clone(), + }; let response = self .transaction_service_client .find_transactions_opt(&request, common_headers_call_option(&self.api_key)); - Ok(response.map(|mut response| response.take_transactions().to_vec())?) + Ok(response.map(|response| response.transactions.to_vec())?) } pub fn list_transactions( &self, created_since: u64, ) -> Result, Error> { - let mut request = ListTransactionsRequest::new(); - request.set_created_since(created_since); + let request = ListTransactionsRequest { created_since }; let response = self .transaction_service_client .list_transactions_opt(&request, common_headers_call_option(&self.api_key)); - Ok(response.map(|mut response| response.take_transactions().to_vec())?) + Ok(response.map(|response| response.transactions.to_vec())?) } pub fn create_transaction( &self, transparent_transaction: TransparentTransaction, ) -> Result { - let mut request = CreateTransactionRequest::new(); - request.set_transaction(transparent_transaction); + let request = CreateTransactionRequest { + transaction: Some(transparent_transaction), + }; let response = self .transaction_service_client .create_transaction_opt(&request, common_headers_call_option(&self.api_key)); - Ok(response.map(|mut response| response.take_transaction())?) + Ok(response.map(|response| response.transaction.unwrap_or_default())?) } pub fn test_error(&self, code: i32) -> Result<(), Error> { - let mut request = TestErrorRequest::new(); - request.set_code(code); + let request = TestErrorRequest { code }; let response = self .transaction_service_client diff --git a/test-vectors/b58-encodings/build.rs b/test-vectors/b58-encodings/build.rs index a94438497c..f86e4e4955 100644 --- a/test-vectors/b58-encodings/build.rs +++ b/test-vectors/b58-encodings/build.rs @@ -1,5 +1,5 @@ use mc_account_keys::{AccountKey, RootIdentity}; -use mc_api::printable::PrintableWrapper; +use mc_api::printable::{printable_wrapper, PrintableWrapper}; use mc_test_vectors_definitions::b58_encodings::*; use mc_util_test_vector::write_jsonl; @@ -9,8 +9,11 @@ fn main() { .map(|n| { let account_key = AccountKey::from(&RootIdentity::from(&[n; 32])); let public_address = account_key.default_subaddress(); - let mut wrapper = PrintableWrapper::new(); - wrapper.set_public_address((&public_address).into()); + let wrapper = PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress( + (&public_address).into(), + )), + }; let b58_encoded = wrapper.b58_encode().unwrap(); B58EncodePublicAddressWithoutFog { view_public_key: public_address.view_public_key().to_bytes(), @@ -32,8 +35,11 @@ fn main() { fog_authority_spki: Vec::new(), }); let public_address = account_key.default_subaddress(); - let mut wrapper = PrintableWrapper::new(); - wrapper.set_public_address((&public_address).into()); + let wrapper = PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress( + (&public_address).into(), + )), + }; let b58_encoded = wrapper.b58_encode().unwrap(); B58EncodePublicAddressWithFog { view_public_key: public_address.view_public_key().to_bytes(), diff --git a/util/b58-decoder/src/bin/main.rs b/util/b58-decoder/src/bin/main.rs index 6ff812fac8..6c4d6e734f 100644 --- a/util/b58-decoder/src/bin/main.rs +++ b/util/b58-decoder/src/bin/main.rs @@ -5,7 +5,10 @@ use clap::Parser; use mc_account_keys::{PublicAddress, ShortAddressHash}; -use mc_api::{external::PublicAddress as PublicAddressProto, printable::PrintableWrapper}; +use mc_api::{ + external::PublicAddress as PublicAddressProto, + printable::{printable_wrapper, PrintableWrapper}, +}; #[derive(Parser)] struct Config { @@ -16,46 +19,40 @@ fn main() { let config = Config::parse(); match PrintableWrapper::b58_decode(config.b58_string) { - Ok(printable_wrapper) => { - if printable_wrapper.has_public_address() { + Ok(decoded_wrapper) => match decoded_wrapper.wrapper.as_ref() { + Some(printable_wrapper::Wrapper::PublicAddress(address)) => { println!("B58 decoded successfully to a PrintableWrapper with a PublicAddress"); - print_public_address(printable_wrapper.get_public_address()); - } else if printable_wrapper.has_payment_request() { + print_public_address(address); + } + Some(printable_wrapper::Wrapper::PaymentRequest(payment_request)) => { println!("B58 decoded successfully to a PrintableWrapper with a PaymentRequest"); - print_public_address(printable_wrapper.get_payment_request().get_public_address()); - println!( - "Value: {}", - printable_wrapper.get_payment_request().get_value() - ); - println!( - "Memo: {}", - printable_wrapper.get_payment_request().get_memo() - ); - } else if printable_wrapper.has_transfer_payload() { + let address = payment_request + .public_address + .as_ref() + .expect("Missing public address"); + print_public_address(address); + println!("Value: {}", payment_request.value); + println!("Memo: {}", payment_request.memo); + } + #[allow(deprecated)] + Some(printable_wrapper::Wrapper::TransferPayload(payload)) => { println!("B58 decoded successfully to a PrintableWrapper with a TransferPayload"); - println!( - "Root entropy: {}", - hex::encode(printable_wrapper.get_transfer_payload().get_root_entropy()) - ); + println!("Root entropy: {}", hex::encode(&payload.root_entropy)); println!( "TxOut public key: {}", hex::encode( - printable_wrapper - .get_transfer_payload() - .get_tx_out_public_key() - .get_data() + &payload + .tx_out_public_key + .as_ref() + .expect("Missing tx_out_public_key") + .data ) ); - println!( - "Memo: {}", - printable_wrapper.get_transfer_payload().get_memo() - ); - println!( - "BIP39 entropy: {}", - hex::encode(printable_wrapper.get_transfer_payload().get_bip39_entropy()) - ); + println!("Memo: {}", payload.memo); + println!("BIP39 entropy: {}", hex::encode(&payload.bip39_entropy)); } - } + _ => {} + }, Err(err) => { println!("Failed decoding b58 into a known object: {err}"); @@ -67,17 +64,29 @@ fn main() { fn print_public_address(pub_addr: &PublicAddressProto) { println!( "View public key: {}", - hex::encode(pub_addr.get_view_public_key().get_data()) + hex::encode( + &pub_addr + .view_public_key + .as_ref() + .expect("Missing view public key") + .data + ) ); println!( "Spend public key: {}", - hex::encode(pub_addr.get_spend_public_key().get_data()) + hex::encode( + &pub_addr + .spend_public_key + .as_ref() + .expect("Missing spend public key") + .data + ) ); - println!("Fog report URL: {}", pub_addr.get_fog_report_url()); - println!("Fog report id: {}", pub_addr.get_fog_report_id()); + println!("Fog report URL: {}", pub_addr.fog_report_url); + println!("Fog report id: {}", pub_addr.fog_report_id); println!( "Fog authority sig: {}", - hex::encode(pub_addr.get_fog_authority_sig()) + hex::encode(&pub_addr.fog_authority_sig) ); let parse_result = PublicAddress::try_from(pub_addr); diff --git a/util/build/grpc/Cargo.toml b/util/build/grpc/Cargo.toml index ed8fe30cee..00a886b12c 100644 --- a/util/build/grpc/Cargo.toml +++ b/util/build/grpc/Cargo.toml @@ -8,6 +8,6 @@ readme = "README.md" rust-version = { workspace = true } [dependencies] +grpcio-compiler = { version = "0.13", default-features = false, features = ["prost-codec"] } mc-util-build-script = { path = "../../build/script" } - -protoc-grpcio = "3.0.0" +prost-build = "0.11" diff --git a/util/build/grpc/src/lib.rs b/util/build/grpc/src/lib.rs index fa586ca3fd..99ec99f713 100644 --- a/util/build/grpc/src/lib.rs +++ b/util/build/grpc/src/lib.rs @@ -2,7 +2,9 @@ #![doc = include_str!("../README.md")] +use grpcio_compiler::prost_codegen::Generator; use mc_util_build_script::Environment; +use prost_build::Config; use std::{ffi::OsStr, fs, path::PathBuf}; /// Compile protobuf files into Rust code, and generate a mod.rs that references @@ -22,8 +24,13 @@ pub fn compile_protos_and_generate_mod_rs(proto_dirs: &[&str], proto_files: &[&s let _ = fs::remove_dir_all(&output_destination); fs::create_dir_all(&output_destination).expect("failed creating output destination"); - // Generate code. - protoc_grpcio::compile_grpc_protos(proto_files, proto_dirs, &output_destination, None) + let mut prost_config = Config::new(); + prost_config.service_generator(Box::new(Generator)); + prost_config.out_dir(output_destination.clone()); + prost_config.btree_map(["."]); + prost_config + .protoc_arg("--experimental_allow_proto3_optional") + .compile_protos(proto_files, proto_dirs) .expect("Failed to compile gRPC definitions!"); // Generate the mod.rs file that includes all the auto-generated code. @@ -32,9 +39,17 @@ pub fn compile_protos_and_generate_mod_rs(proto_dirs: &[&str], proto_files: &[&s .filter_map(|res| res.map(|e| e.path()).ok()) .filter_map(|path| { if path.extension() == Some(OsStr::new("rs")) { + // File names with a . in it are invalid rust module names, so replace . with _ + // and use path attribute. Example: misty_swap.v1 becomes the + // rust module misty_swap_v1 Some(format!( - "pub mod {};", - path.file_stem().unwrap().to_str().unwrap() + "#[path = \"{}\"]\npub mod {};", + path.file_name().unwrap().to_str().unwrap(), + path.file_stem() + .unwrap() + .to_str() + .unwrap() + .replace('.', "_"), )) } else { None diff --git a/util/grpc-admin-tool/Cargo.toml b/util/grpc-admin-tool/Cargo.toml index 8eda2b9abf..f1ddcfc976 100644 --- a/util/grpc-admin-tool/Cargo.toml +++ b/util/grpc-admin-tool/Cargo.toml @@ -16,4 +16,4 @@ mc-util-grpc = { path = "../grpc" } mc-util-uri = { path = "../uri" } clap = { version = "4.5", features = ["derive", "env"] } -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } diff --git a/util/grpc-admin-tool/src/bin/main.rs b/util/grpc-admin-tool/src/bin/main.rs index 0541cd1942..86b123a1fa 100644 --- a/util/grpc-admin-tool/src/bin/main.rs +++ b/util/grpc-admin-tool/src/bin/main.rs @@ -6,7 +6,8 @@ use clap::{Parser, Subcommand}; use grpcio::ChannelBuilder; use mc_util_grpc::{ - admin::SetRustLogRequest, admin_grpc::AdminApiClient, empty::Empty, ConnectionUriGrpcioChannel, + admin::{AdminApiClient, SetRustLogRequest}, + ConnectionUriGrpcioChannel, }; use mc_util_uri::AdminUri; use std::{str::FromStr, sync::Arc}; @@ -56,15 +57,13 @@ fn main() { match config.cmd { Command::Metrics => { let response = client - .get_prometheus_metrics(&Empty::new()) + .get_prometheus_metrics(&()) .expect("failed calling get_prometheus_metrics"); println!("{}", response.metrics); } Command::GetInfo => { - let response = client - .get_info(&Empty::new()) - .expect("failed calling get_info"); + let response = client.get_info(&()).expect("failed calling get_info"); println!("Service name: {}", response.name); println!("Service id: {}", response.id); @@ -74,18 +73,19 @@ fn main() { } Command::SetRustLog { rust_log } => { - let mut request = SetRustLogRequest::new(); - request.set_rust_log(rust_log); + let request = SetRustLogRequest { + rust_log: rust_log.clone(), + }; - let _ = client + client .set_rust_log(&request) .expect("failed calling set_rust_log"); println!("Done."); } Command::TestLogError => { - let _ = client - .test_log_error(&Empty::new()) + client + .test_log_error(&()) .expect("failed calling test_log_error"); println!("Done."); } diff --git a/util/grpc/Cargo.toml b/util/grpc/Cargo.toml index 2874bdb1c2..0f4f7e4976 100644 --- a/util/grpc/Cargo.toml +++ b/util/grpc/Cargo.toml @@ -20,13 +20,13 @@ clap = { version = "4.5", features = ["derive", "env"] } cookie = "0.18" displaydoc = { version = "0.2", default-features = false } futures = "0.3" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec", "boringssl"] } hex = "0.4" hex_fmt = "0.3" hmac = "0.12" lazy_static = "1.4" prometheus = "0.13" -protobuf = "2.27.1" +prost = { version = "0.11", default-features = false } rand = "0.8" retry = "2.0" serde = "1" diff --git a/util/grpc/src/admin_service.rs b/util/grpc/src/admin_service.rs index 8f61277057..589948587d 100644 --- a/util/grpc/src/admin_service.rs +++ b/util/grpc/src/admin_service.rs @@ -3,10 +3,11 @@ //! Customizable implementation of the AdminApi service. use crate::{ - admin::{GetInfoResponse, GetPrometheusMetricsResponse, SetRustLogRequest}, - admin_grpc::{create_admin_api, AdminApi}, + admin::{ + create_admin_api, AdminApi, GetInfoResponse, GetPrometheusMetricsResponse, + SetRustLogRequest, + }, build_info_service::get_build_info, - empty::Empty, rpc_logger, send_result, SVC_COUNTERS, }; use grpcio::{RpcContext, RpcStatus, RpcStatusCode, Service, UnarySink}; @@ -63,7 +64,7 @@ impl AdminService { fn get_prometheus_metrics_impl( &mut self, - _request: Empty, + _request: (), logger: &Logger, ) -> Result { log::trace!(logger, "get_prometheus_metrics_impl"); @@ -73,16 +74,16 @@ impl AdminService { let mut buffer = vec![]; encoder.encode(&metric_families, &mut buffer).unwrap(); - let mut response = GetPrometheusMetricsResponse::new(); - response.set_metrics(String::from_utf8(buffer).map_err(|err| { - RpcStatus::with_message(RpcStatusCode::INTERNAL, format!("from_utf8 failed: {err}")) - })?); - Ok(response) + Ok(GetPrometheusMetricsResponse { + metrics: String::from_utf8(buffer).map_err(|err| { + RpcStatus::with_message(RpcStatusCode::INTERNAL, format!("from_utf8 failed: {err}")) + })?, + }) } fn get_info_impl( &mut self, - _request: Empty, + _request: (), logger: &Logger, ) -> Result { log::trace!(logger, "get_info_impl"); @@ -105,36 +106,32 @@ impl AdminService { let rust_log = env::var("RUST_LOG").unwrap_or_else(|_| "".to_string()); - let mut response = GetInfoResponse::new(); - response.set_name(self.name.clone()); - response.set_id(self.id.clone()); - response.set_build_info_json(build_info_json); - response.set_build_info(build_info); - response.set_config_json(config_json); - response.set_rust_log(rust_log); - Ok(response) + Ok(GetInfoResponse { + name: self.name.clone(), + id: self.id.clone(), + build_info_json, + build_info: Some(build_info), + config_json, + rust_log, + }) } fn set_rust_log_impl( &mut self, request: SetRustLogRequest, logger: &Logger, - ) -> Result { + ) -> Result<(), RpcStatus> { log::info!(logger, "Updating RUST_LOG to '{}'", request.rust_log); env::set_var("RUST_LOG", request.rust_log); mc_common::logger::recreate_app_logger(); - Ok(Empty::new()) + Ok(()) } - fn test_log_error_impl( - &mut self, - _request: Empty, - logger: &Logger, - ) -> Result { + fn test_log_error_impl(&mut self, _request: (), logger: &Logger) -> Result<(), RpcStatus> { log::error!(logger, "Test log message admin admin interface"); - Ok(Empty::new()) + Ok(()) } } @@ -142,7 +139,7 @@ impl AdminApi for AdminService { fn get_prometheus_metrics( &mut self, ctx: RpcContext, - request: Empty, + request: (), sink: UnarySink, ) { let _timer = SVC_COUNTERS.req(&ctx); @@ -156,26 +153,21 @@ impl AdminApi for AdminService { }); } - fn get_info(&mut self, ctx: RpcContext, request: Empty, sink: UnarySink) { + fn get_info(&mut self, ctx: RpcContext, request: (), sink: UnarySink) { let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { send_result(ctx, sink, self.get_info_impl(request, logger), logger) }); } - fn set_rust_log( - &mut self, - ctx: RpcContext, - request: SetRustLogRequest, - sink: UnarySink, - ) { + fn set_rust_log(&mut self, ctx: RpcContext, request: SetRustLogRequest, sink: UnarySink<()>) { let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { send_result(ctx, sink, self.set_rust_log_impl(request, logger), logger) }); } - fn test_log_error(&mut self, ctx: RpcContext, request: Empty, sink: UnarySink) { + fn test_log_error(&mut self, ctx: RpcContext, request: (), sink: UnarySink<()>) { let _timer = SVC_COUNTERS.req(&ctx); mc_common::logger::scoped_global_logger(&rpc_logger(&ctx, &self.logger), |logger| { send_result(ctx, sink, self.test_log_error_impl(request, logger), logger) diff --git a/util/grpc/src/build_info_service.rs b/util/grpc/src/build_info_service.rs index d750aa0e21..d0c43d1cce 100644 --- a/util/grpc/src/build_info_service.rs +++ b/util/grpc/src/build_info_service.rs @@ -3,9 +3,7 @@ //! Implementation of the BuildInfoApi service. use crate::{ - build_info::BuildInfo, - build_info_grpc::{create_build_info_api, BuildInfoApi}, - empty::Empty, + build_info::{create_build_info_api, BuildInfo, BuildInfoApi}, rpc_logger, send_result, SVC_COUNTERS, }; use grpcio::{RpcContext, Service, UnarySink}; @@ -32,21 +30,21 @@ impl BuildInfoService { /// Get the BuildInfo object, by reading from the BuildInfo crate pub fn get_build_info() -> BuildInfo { - let mut build_info = BuildInfo::new(); - build_info.set_git_commit(::mc_util_build_info::git_commit().to_owned()); - build_info.set_profile(::mc_util_build_info::profile().to_owned()); - build_info.set_debug(::mc_util_build_info::debug().to_owned()); - build_info.set_opt_level(::mc_util_build_info::opt_level().to_owned()); - build_info.set_debug_assertions(::mc_util_build_info::debug_assertions().to_owned()); - build_info.set_target_arch(::mc_util_build_info::target_arch().to_owned()); - build_info.set_target_feature(::mc_util_build_info::target_feature().to_owned()); - build_info.set_rustflags(::mc_util_build_info::rustflags().to_owned()); - build_info.set_sgx_mode(::mc_util_build_info::sgx_mode().to_owned()); - build_info + BuildInfo { + git_commit: ::mc_util_build_info::git_commit().to_owned(), + profile: ::mc_util_build_info::profile().to_owned(), + debug: ::mc_util_build_info::debug().to_owned(), + opt_level: ::mc_util_build_info::opt_level().to_owned(), + debug_assertions: ::mc_util_build_info::debug_assertions().to_owned(), + target_arch: ::mc_util_build_info::target_arch().to_owned(), + target_feature: ::mc_util_build_info::target_feature().to_owned(), + rustflags: ::mc_util_build_info::rustflags().to_owned(), + sgx_mode: ::mc_util_build_info::sgx_mode().to_owned(), + } } impl BuildInfoApi for BuildInfoService { - fn get_build_info(&mut self, ctx: RpcContext, _req: Empty, sink: UnarySink) { + fn get_build_info(&mut self, ctx: RpcContext, _req: (), sink: UnarySink) { let _timer = SVC_COUNTERS.req(&ctx); let logger = rpc_logger(&ctx, &self.logger); send_result(ctx, sink, Ok(get_build_info()), &logger); diff --git a/util/grpc/src/health_service.rs b/util/grpc/src/health_service.rs index efa686a6f3..629c4cfdde 100644 --- a/util/grpc/src/health_service.rs +++ b/util/grpc/src/health_service.rs @@ -5,11 +5,9 @@ //! MobileCoin-specific (Ping) extensions. use crate::{ - health_api::{ - HealthCheckRequest, HealthCheckResponse, HealthCheckResponse_ServingStatus, PingRequest, - PingResponse, + grpc_health_v1::{ + create_health, Health, HealthCheckRequest, HealthCheckResponse, PingRequest, PingResponse, }, - health_api_grpc::{create_health, Health}, rpc_logger, send_result, SVC_COUNTERS, }; use futures::prelude::*; @@ -19,9 +17,8 @@ use std::sync::{ atomic::{AtomicBool, Ordering}, Arc, }; - // Re-export the health check status enum for convenience. -pub use crate::health_api::HealthCheckResponse_ServingStatus as HealthCheckStatus; +pub use crate::grpc_health_v1::health_check_response::ServingStatus as HealthCheckStatus; // A prototype of a callback function that receives a service name and returns // it's health status. By defauult, `HealthService` would respond SERVING to all @@ -65,12 +62,13 @@ impl Health for HealthService { let logger = rpc_logger(&ctx, &self.logger); let status = match &self.service_health_check_callback { - None => HealthCheckResponse_ServingStatus::SERVING, - Some(callback) => callback(req.get_service()), + None => HealthCheckStatus::Serving, + Some(callback) => callback(&req.service), }; - let mut resp = HealthCheckResponse::new(); - resp.set_status(status); + let resp = HealthCheckResponse { + status: status.into(), + }; send_result(ctx, sink, Ok(resp), &logger); } @@ -78,8 +76,7 @@ impl Health for HealthService { let _timer = SVC_COUNTERS.req(&ctx); let logger = rpc_logger(&ctx, &self.logger); - let mut resp = PingResponse::new(); - resp.set_data(req.get_data().to_vec()); + let resp = PingResponse { data: req.data }; send_result(ctx, sink, Ok(resp), &logger); } @@ -139,9 +136,9 @@ impl From for ServiceHealthCheckCallback { fn from(src: ReadinessIndicator) -> Self { Arc::new(move |_| -> HealthCheckStatus { if src.ready() { - HealthCheckStatus::SERVING + HealthCheckStatus::Serving } else { - HealthCheckStatus::NOT_SERVING + HealthCheckStatus::NotServing } }) } diff --git a/util/grpc/src/lib.rs b/util/grpc/src/lib.rs index 61038005a7..b7e0294164 100644 --- a/util/grpc/src/lib.rs +++ b/util/grpc/src/lib.rs @@ -5,18 +5,9 @@ //! service and the health check service #![deny(missing_docs)] -// workaround for #![allow(box_pointers)] in protobuf generated files. -#![allow(renamed_and_removed_lints)] +#[allow(missing_docs)] mod autogenerated_code { - pub use protobuf::well_known_types::Empty; - - /// Needed due to how to the auto-generated code references the Empty - /// message. - pub mod empty { - pub use protobuf::well_known_types::Empty; - } - // Include the auto-generated code. include!(concat!(env!("OUT_DIR"), "/protos-auto-gen/mod.rs")); } diff --git a/util/grpc/src/server_cert_reloader.rs b/util/grpc/src/server_cert_reloader.rs index 579f0838e4..7b02b85b6f 100644 --- a/util/grpc/src/server_cert_reloader.rs +++ b/util/grpc/src/server_cert_reloader.rs @@ -140,8 +140,8 @@ impl ServerCredentialsFetcher for ServerCertReloader { mod tests { use super::*; use crate::{ - health_api::PingRequest, health_api_grpc::HealthClient, ConnectionUriGrpcioServer, - HealthService, + grpc_health_v1::{HealthClient, PingRequest}, + ConnectionUriGrpcioServer, HealthService, }; use grpcio::{ ChannelBuilder, ChannelCredentialsBuilder, EnvBuilder, Server, ServerBuilder, @@ -211,30 +211,34 @@ mod tests { // Connect the server whose CN is "www.server1.com" with the correct // certificate. let client1 = create_test_client(&server1_cert, "www.server1.com", port); - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; let reply = client1.ping(&req).expect("rpc"); - assert_eq!(reply.get_data(), vec![1, 2, 3]); + assert_eq!(reply.data, vec![1, 2, 3]); // Connect the server whose CN is "www.server1.com" with a different ssl target // should fail. let client2 = create_test_client(&server1_cert, "www.server2.com", port); - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; assert!(client2.ping(&req).is_err()); // Connect the server whose CN is "www.server1.com" with an incorrect // certificate. let client3 = create_test_client(&server2_cert, "www.server1.com", port); - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; assert!(client3.ping(&req).is_err()); // Connecting with server2/"www.server2.com" should not work until we replace // the certificate and key file. let client4 = create_test_client(&server2_cert, "www.server2.com", port); - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; assert!(client4.ping(&req).is_err()); // Replace server1 certificates with server2. This should trigger the reloading @@ -252,21 +256,23 @@ mod tests { // We should be able to connect using "www.server2.com". let client5 = create_test_client(&server2_cert, "www.server2.com", port); - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let mut req = PingRequest { + data: vec![1, 2, 3], + }; let reply = client5.ping(&req).expect("rpc"); - assert_eq!(reply.get_data(), vec![1, 2, 3]); + assert_eq!(reply.data, vec![1, 2, 3]); // The original client should still be functional. - req.set_data(vec![5, 6, 7]); + req.data = vec![5, 6, 7]; let reply = client1.ping(&req).expect("rpc"); - assert_eq!(reply.get_data(), vec![5, 6, 7]); + assert_eq!(reply.data, vec![5, 6, 7]); // The previous server2 client should also work. - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; let reply = client4.ping(&req).expect("rpc"); - assert_eq!(reply.get_data(), vec![1, 2, 3]); + assert_eq!(reply.data, vec![1, 2, 3]); } #[test_with_logger] @@ -287,10 +293,11 @@ mod tests { // Sanity that the server works. let client1 = create_test_client(&server1_cert, "www.server1.com", port); - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; let reply = client1.ping(&req).expect("rpc"); - assert_eq!(reply.get_data(), vec![1, 2, 3]); + assert_eq!(reply.data, vec![1, 2, 3]); // Replace the certificate file with junk. fs::write(cert_file, "junk").unwrap(); @@ -305,10 +312,11 @@ mod tests { // Server should still respond with the old certificate. let client2 = create_test_client(&server1_cert, "www.server1.com", port); - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; let reply = client2.ping(&req).expect("rpc"); - assert_eq!(reply.get_data(), vec![1, 2, 3]); + assert_eq!(reply.data, vec![1, 2, 3]); } #[test_with_logger] @@ -331,16 +339,18 @@ mod tests { // Sanity that the servers works. let client1 = create_test_client(&server1_cert, "www.server1.com", port1); - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; let reply = client1.ping(&req).expect("rpc"); - assert_eq!(reply.get_data(), vec![1, 2, 3]); + assert_eq!(reply.data, vec![1, 2, 3]); let client2 = create_test_client(&server1_cert, "www.server1.com", port2); - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; let reply = client2.ping(&req).expect("rpc"); - assert_eq!(reply.get_data(), vec![1, 2, 3]); + assert_eq!(reply.data, vec![1, 2, 3]); // Replace server1 certificates with server2. std::fs::write(&cert_file, &server2_cert).unwrap(); @@ -356,16 +366,18 @@ mod tests { // Both servers should now have the new cerficates. let client3 = create_test_client(&server2_cert, "www.server2.com", port1); - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; let reply = client3.ping(&req).expect("rpc"); - assert_eq!(reply.get_data(), vec![1, 2, 3]); + assert_eq!(reply.data, vec![1, 2, 3]); let client4 = create_test_client(&server2_cert, "www.server2.com", port2); - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; let reply = client4.ping(&req).expect("rpc"); - assert_eq!(reply.get_data(), vec![1, 2, 3]); + assert_eq!(reply.data, vec![1, 2, 3]); } #[test_with_logger] @@ -404,10 +416,11 @@ mod tests { // Sanity that the servers works. let client1 = create_test_client(&server1_cert, "www.server1.com", port); - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; let reply = client1.ping(&req).expect("rpc"); - assert_eq!(reply.get_data(), vec![1, 2, 3]); + assert_eq!(reply.data, vec![1, 2, 3]); // Replace server1 certificates with server2. std::fs::write(&cert_file, &server2_cert).unwrap(); @@ -423,15 +436,17 @@ mod tests { // Server should now have the new cerficate. let client2 = create_test_client(&server2_cert, "www.server2.com", port); - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; let reply = client2.ping(&req).expect("rpc"); - assert_eq!(reply.get_data(), vec![1, 2, 3]); + assert_eq!(reply.data, vec![1, 2, 3]); // Original client should still be alive. - let mut req = PingRequest::default(); - req.set_data(vec![1, 2, 3]); + let req = PingRequest { + data: vec![1, 2, 3], + }; let reply = client1.ping(&req).expect("rpc"); - assert_eq!(reply.get_data(), vec![1, 2, 3]); + assert_eq!(reply.data, vec![1, 2, 3]); } } diff --git a/util/keyfile/src/lib.rs b/util/keyfile/src/lib.rs index c547ab8541..f66680c715 100644 --- a/util/keyfile/src/lib.rs +++ b/util/keyfile/src/lib.rs @@ -14,7 +14,7 @@ pub mod keygen; use crate::error::Error; use bip39::Mnemonic; use mc_account_keys::{AccountKey, PublicAddress, RootIdentity}; -use mc_api::printable::PrintableWrapper; +use mc_api::printable::{printable_wrapper, PrintableWrapper}; use std::{ fs::File, io::{Read, Write}, @@ -110,8 +110,9 @@ pub fn write_b58pubfile>( path: P, addr: &PublicAddress, ) -> Result<(), std::io::Error> { - let mut wrapper = PrintableWrapper::new(); - wrapper.set_public_address(addr.into()); + let wrapper = PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress(addr.into())), + }; let data = wrapper.b58_encode().map_err(to_io_error)?; @@ -133,14 +134,14 @@ pub fn read_b58pubfile_data(buffer: &mut R) -> Result(err: E) -> std::io::Error { diff --git a/util/keyfile/tests/b58-length.rs b/util/keyfile/tests/b58-length.rs index 1036c870f6..c5328ba0e3 100644 --- a/util/keyfile/tests/b58-length.rs +++ b/util/keyfile/tests/b58-length.rs @@ -1,5 +1,5 @@ use mc_account_keys::{AccountKey, RootIdentity}; -use mc_api::printable::PrintableWrapper; +use mc_api::printable::{printable_wrapper, PrintableWrapper}; use mc_util_test_helper::{run_with_several_seeds, CryptoRng, RngCore}; // The limit which we require b58 addresses to be less than @@ -29,8 +29,9 @@ fn test_b58pub_length( let acct_key = AccountKey::from(&root_id); let addr = acct_key.default_subaddress(); - let mut wrapper = PrintableWrapper::new(); - wrapper.set_public_address((&addr).into()); + let wrapper = PrintableWrapper { + wrapper: Some(printable_wrapper::Wrapper::PublicAddress((&addr).into())), + }; let data = wrapper.b58_encode().unwrap(); diff --git a/util/metrics/Cargo.toml b/util/metrics/Cargo.toml index c296923b23..c8e6d22006 100644 --- a/util/metrics/Cargo.toml +++ b/util/metrics/Cargo.toml @@ -8,14 +8,14 @@ rust-version = { workspace = true } [features] default = [] -service_metrics = ["dep:grpcio"] +service_metrics = ["dep:grpcio", "dep:prost"] [dependencies] mc-common = { path = "../../common", features = ["log"] } chrono = "0.4" -grpcio = { version = "0.13", optional = true } +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"], optional = true } lazy_static = "1.4" prometheus = "0.13" -protobuf = "2.27.1" +prost = { version = "0.11", optional = true } serde_json = "1.0" diff --git a/util/metrics/src/service_metrics.rs b/util/metrics/src/service_metrics.rs index 20a78316a4..e5c047553d 100644 --- a/util/metrics/src/service_metrics.rs +++ b/util/metrics/src/service_metrics.rs @@ -32,11 +32,9 @@ use grpcio::{RpcContext, RpcStatusCode}; use mc_common::logger::global_log; use prometheus::{ core::{Collector, Desc}, - exponential_buckets, proto::MetricFamily, HistogramOpts, HistogramTimer, HistogramVec, IntCounterVec, Opts, Result, }; -use protobuf::Message; use std::{path::Path, str}; /// Helper that encapsulates boilerplate for tracking prometheus metrics about @@ -63,9 +61,6 @@ pub struct ServiceMetrics { /// Duration of gRPC method calls tracked duration: HistogramVec, - - /// Histogram of message sizes for each gRPC message type tracked - message_size: HistogramVec, } impl Default for ServiceMetrics { fn default() -> Self { @@ -87,8 +82,6 @@ impl Default for ServiceMetrics { impl ServiceMetrics { /// Create a default constructor that initializes all metrics pub fn new>(name: S) -> ServiceMetrics { - let message_size_buckets = exponential_buckets(2.0, 2.0, 22) - .expect("Could not create buckets for message-size histogram"); let name_str = name.into(); ServiceMetrics { @@ -119,15 +112,6 @@ impl ServiceMetrics { &["method"], ) .unwrap(), - message_size: HistogramVec::new( - HistogramOpts::new( - format!("{name_str}_message_size"), - "gRPC message size, in bytes (or close to)", - ) - .buckets(message_size_buckets), - &["message"], - ) - .unwrap(), } } } @@ -197,16 +181,6 @@ impl ServiceMetrics { .inc(); } - /// Tracks gRPC message name and size for aggregation into a Prometheus - /// histogram - pub fn message(&self, message: &M) { - let computed_size = message.compute_size(); - let message_fullname = message.descriptor().full_name(); - self.message_size - .with_label_values(&[message_fullname]) - .observe(f64::from(computed_size)); - } - pub fn register_default(&self) -> Result<()> { prometheus::register(Box::new(self.clone())) } @@ -221,7 +195,6 @@ impl Collector for ServiceMetrics { self.num_error.desc(), self.num_status_code.desc(), self.duration.desc(), - self.message_size.desc(), ] .into_iter() .map(|m| m[0]) @@ -236,7 +209,6 @@ impl Collector for ServiceMetrics { self.num_error.collect(), self.num_status_code.collect(), self.duration.collect(), - self.message_size.collect(), ]; vs.into_iter().fold(vec![], |mut l, v| { diff --git a/util/serial/Cargo.toml b/util/serial/Cargo.toml index 21f4787e20..6bf3a625ba 100644 --- a/util/serial/Cargo.toml +++ b/util/serial/Cargo.toml @@ -13,11 +13,10 @@ rust-version = { workspace = true } # so if anything else in your build plan will activate ser../../std, then mcseri../../std is # required. std = ["serde/std", "serde_cbor/std", "serde_with"] -test_utils = ["protobuf"] +test_utils = [] [dependencies] prost = { version = "0.11", default-features = false, features = ["prost-derive"] } -protobuf = { version = "2.27", optional = true } serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } serde_cbor = { version = "0.11.1", default-features = false, features = ["alloc"] } serde_with = { version = "3.1", default-features = false, features = ["macros"], optional = true } diff --git a/util/serial/src/lib.rs b/util/serial/src/lib.rs index a407f83a52..211c708fd0 100644 --- a/util/serial/src/lib.rs +++ b/util/serial/src/lib.rs @@ -129,23 +129,22 @@ mod json_u64 { #[cfg(feature = "serde_with")] pub use json_u64::JsonU64; -/// Take a prost type and try to roundtrip it through a protobuf type +/// Take one prost type and try to roundtrip it through another prost type #[cfg(feature = "test_utils")] -pub fn round_trip_message(prost_val: &SRC) { +pub fn round_trip_message(prost_val: &SRC) { let prost_bytes = encode(prost_val); - let dest_val = - DEST::parse_from_bytes(&prost_bytes).expect("Parsing protobuf from prost bytes failed"); + let dest_val = DEST::decode(prost_bytes.as_slice()) + .expect("Parsing second prost from first prost bytes failed"); - let protobuf_bytes = dest_val - .write_to_bytes() - .expect("Writing protobuf to bytes failed"); + let protobuf_bytes = dest_val.encode_to_vec(); - let final_val: SRC = decode(&protobuf_bytes).expect("Parsing prost from protobuf bytes failed"); + let final_val: SRC = + decode(&protobuf_bytes).expect("Parsing first prost from second prost bytes failed"); assert_eq!( *prost_val, final_val, - "Round-trip check failed!\nprost: {prost_val:?}\nprotobuf: {final_val:?}" + "Round-trip check failed!\nprost_1: {prost_val:?}\nprost_2: {final_val:?}" ); } diff --git a/watcher/Cargo.toml b/watcher/Cargo.toml index a17109a17b..96541eff64 100644 --- a/watcher/Cargo.toml +++ b/watcher/Cargo.toml @@ -43,7 +43,7 @@ aes-gcm = "0.10.3" clap = { version = "4.5", features = ["derive", "env"] } displaydoc = { version = "0.2", default-features = false } futures = "0.3" -grpcio = "0.13" +grpcio = { version = "0.13", default-features = false, features = ["prost-codec"] } hex = "0.4" lazy_static = "1.4" lmdb-rkv = "0.14.0" diff --git a/watcher/src/attestation_evidence_collector.rs b/watcher/src/attestation_evidence_collector.rs index 637231b2dd..733b3dbf67 100644 --- a/watcher/src/attestation_evidence_collector.rs +++ b/watcher/src/attestation_evidence_collector.rs @@ -8,7 +8,7 @@ use grpcio::{CallOption, ChannelBuilder, Environment, MetadataBuilder}; use mc_attest_ake::{ AuthRequestOutput, ClientInitiate, Start, Transition, UnverifiedAttestationEvidence, }; -use mc_attest_api::{attest::AuthMessage, attest_grpc::AttestedApiClient}; +use mc_attest_api::attest::{AttestedApiClient, AuthMessage}; use mc_attest_core::{EvidenceKind, VerificationReport, VerificationReportData}; use mc_attest_verifier_types::prost; use mc_common::{ diff --git a/watcher/src/bin/main.rs b/watcher/src/bin/main.rs index 4c354c3280..fba3edd48d 100644 --- a/watcher/src/bin/main.rs +++ b/watcher/src/bin/main.rs @@ -57,7 +57,7 @@ fn main() { // Start gRPC server. let health_check_callback: Arc HealthCheckStatus + Sync + Send> = - Arc::new(move |_| HealthCheckStatus::SERVING); + Arc::new(move |_| HealthCheckStatus::Serving); let health_service = HealthService::new(Some(health_check_callback), logger.clone()).into_service(); From e3f080bc285a67a5a1894de7788a6761c3c3e3f4 Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Mon, 28 Apr 2025 17:43:26 -0700 Subject: [PATCH 02/13] Fix some tests --- api/proto/external.proto | 2 +- consensus/service/src/api/client_api_service.rs | 12 ++++++++++-- fog/sample-paykit/src/cached_tx_data/mod.rs | 2 +- mobilecoind-json/src/data_types.rs | 11 +++++++---- mobilecoind/src/service.rs | 9 ++++++++- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/api/proto/external.proto b/api/proto/external.proto index 9cc09ce1d3..2360eb1485 100644 --- a/api/proto/external.proto +++ b/api/proto/external.proto @@ -118,7 +118,7 @@ message RootIdentity { string fog_report_id = 3; // Optional fog authority subjectPublicKeyInfo. // Empty when not in use. - bytes fog_authority_spki = 5; + bytes fog_authority_spki = 4; } // A 32 byte secret used as input key material to derive private keys diff --git a/consensus/service/src/api/client_api_service.rs b/consensus/service/src/api/client_api_service.rs index c8d4c91145..9806475194 100644 --- a/consensus/service/src/api/client_api_service.rs +++ b/consensus/service/src/api/client_api_service.rs @@ -1138,7 +1138,11 @@ mod client_api_tests { match client.propose_mint_config_tx(&(&tx).into()) { Ok(propose_tx_response) => { assert_eq!( - propose_tx_response.result.unwrap().code(), + propose_tx_response + .result + .as_ref() + .unwrap_or(&Default::default()) + .code(), MintValidationResultCode::Ok ); assert_eq!(propose_tx_response.block_count, num_blocks); @@ -1451,7 +1455,11 @@ mod client_api_tests { match client.propose_mint_tx(&(&tx).into()) { Ok(propose_tx_response) => { assert_eq!( - propose_tx_response.result.unwrap().code(), + propose_tx_response + .result + .as_ref() + .unwrap_or(&Default::default()) + .code(), MintValidationResultCode::Ok ); assert_eq!(propose_tx_response.block_count, num_blocks); diff --git a/fog/sample-paykit/src/cached_tx_data/mod.rs b/fog/sample-paykit/src/cached_tx_data/mod.rs index 64084384a0..26e86fd801 100644 --- a/fog/sample-paykit/src/cached_tx_data/mod.rs +++ b/fog/sample-paykit/src/cached_tx_data/mod.rs @@ -1469,7 +1469,7 @@ mod tests { let missed_block_range = common::BlockRange::new(first_index, final_index + 1); let missed_block_ranges = vec![missed_block_range]; - let block_data = (first_index..final_index + 1) + let block_data = (first_index..final_index - 1) .map(|index| fog_ledger::BlockData { index, ..Default::default() diff --git a/mobilecoind-json/src/data_types.rs b/mobilecoind-json/src/data_types.rs index 6ec3704a80..da92afde56 100644 --- a/mobilecoind-json/src/data_types.rs +++ b/mobilecoind-json/src/data_types.rs @@ -693,9 +693,12 @@ impl TryFrom<&JsonTxOut> for mc_api::external::TxOut { data: hex::decode(&src.e_fog_hint) .map_err(|err| format!("Failed to decode e_fog_hint hex: {err}"))?, }; - let e_memo = EncryptedMemo { - data: hex::decode(&src.e_memo) - .map_err(|err| format!("Failed to decode e_memo hex: {err}"))?, + let memo_data = hex::decode(&src.e_memo) + .map_err(|err| format!("Failed to decode e_memo hex: {err}"))?; + let e_memo = if memo_data.is_empty() { + None + } else { + Some(EncryptedMemo { data: memo_data }) }; Ok(mc_api::external::TxOut { @@ -707,7 +710,7 @@ impl TryFrom<&JsonTxOut> for mc_api::external::TxOut { target_key: Some(target_key), public_key: Some(public_key), e_fog_hint: Some(e_fog_hint), - e_memo: Some(e_memo), + e_memo, }) } } diff --git a/mobilecoind/src/service.rs b/mobilecoind/src/service.rs index 2c9b4fe3c5..2b59aba842 100644 --- a/mobilecoind/src/service.rs +++ b/mobilecoind/src/service.rs @@ -3696,7 +3696,14 @@ mod test { assert!(!resp.matched); assert_eq!(resp.value, 0); assert_eq!(resp.token_id, 0); - assert_eq!(resp.shared_secret.unwrap().data.len(), 0); + assert_eq!( + resp.shared_secret + .as_ref() + .unwrap_or(&Default::default()) + .data + .len(), + 0 + ); } #[test_with_logger] From 0fee6ed2910a113d69a73368109d727f5eb3679f Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Fri, 2 May 2025 20:03:44 -0700 Subject: [PATCH 03/13] Fix mint client tests --- consensus/mint-client/src/bin/main.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/consensus/mint-client/src/bin/main.rs b/consensus/mint-client/src/bin/main.rs index 9c13fa8412..5c9b871a1f 100644 --- a/consensus/mint-client/src/bin/main.rs +++ b/consensus/mint-client/src/bin/main.rs @@ -57,7 +57,7 @@ fn main() { // Relying on the success result code being 0, we terminate ourselves in a way // that allows whoever started this binary to easily determine if submitting the // transaction succeeded. - exit(resp.result.unwrap().code); + exit(resp.result.as_ref().unwrap_or(&Default::default()).code); } Commands::GenerateMintConfigTx { @@ -144,7 +144,7 @@ fn main() { // Relying on the success result code being 0, we terminate ourselves in a way // that allows whoever started this binary to easily determine if submitting the // transaction succeeded. - exit(resp.result.unwrap().code); + exit(resp.result.as_ref().unwrap_or(&Default::default()).code); } Commands::GenerateAndSubmitMintTx { @@ -186,7 +186,7 @@ fn main() { // Relying on the success result code being 0, we terminate ourselves in a way // that allows whoever started this binary to easily determine if submitting the // transaction succeeded. - exit(resp.result.unwrap().code); + exit(resp.result.as_ref().unwrap_or(&Default::default()).code); } Commands::GenerateMintTx { @@ -282,7 +282,7 @@ fn main() { // Relying on the success result code being 0, we terminate ourselves in a way // that allows whoever started this binary to easily determine if submitting the // transaction succeeded. - exit(resp.result.unwrap().code); + exit(resp.result.as_ref().unwrap_or(&Default::default()).code); } Commands::SignGovernors { From c62b33c4227651e14083fbc887b085a963b7349a Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Fri, 2 May 2025 20:26:40 -0700 Subject: [PATCH 04/13] Get the mode as an enum --- fog/ingest/client/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fog/ingest/client/src/main.rs b/fog/ingest/client/src/main.rs index 28d34c6e61..574dcbe34d 100644 --- a/fog/ingest/client/src/main.rs +++ b/fog/ingest/client/src/main.rs @@ -221,7 +221,7 @@ fn get_ingress_key_records( fn ingest_summary_to_json(summary: &IngestSummary) -> String { to_string_pretty(&json!({ - "mode": format!("{:?}", summary.mode), + "mode": format!("{:?}", summary.mode()), "next_block_index": summary.next_block_index, "pubkey_expiry_window": summary.pubkey_expiry_window, "ingress_pubkey": hex::encode(&summary.ingress_pubkey.as_ref().expect("Missing ingress public key").data), From c99135ba4c3d5470245130a0b61b58129e52bb3e Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Mon, 12 May 2025 16:25:14 -0700 Subject: [PATCH 05/13] Consolidate some logic with let else --- api/src/convert/archive_block.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/api/src/convert/archive_block.rs b/api/src/convert/archive_block.rs index 06103c4662..bb52b9cccf 100644 --- a/api/src/convert/archive_block.rs +++ b/api/src/convert/archive_block.rs @@ -28,12 +28,8 @@ impl TryFrom<&ArchiveBlock> for BlockData { type Error = ConversionError; fn try_from(src: &ArchiveBlock) -> Result { - if src.block.is_none() { + let Some(archive_block::Block::V1(archive_block_v1)) = src.block.as_ref() else { return Err(ConversionError::ObjectMissing); - } - let archive_block_v1 = match src.block.as_ref() { - Some(archive_block::Block::V1(archive_block_v1)) => archive_block_v1, - _ => return Err(ConversionError::ObjectMissing), }; let block = archive_block_v1 From 5b8f5b1d10d883e34c4705530483933ab6d1e99d Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Sun, 18 May 2025 18:00:28 -0700 Subject: [PATCH 06/13] Add print statment for empty PrintableWrapper when decoding --- util/b58-decoder/src/bin/main.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/util/b58-decoder/src/bin/main.rs b/util/b58-decoder/src/bin/main.rs index 6c4d6e734f..e4d5f887dc 100644 --- a/util/b58-decoder/src/bin/main.rs +++ b/util/b58-decoder/src/bin/main.rs @@ -51,7 +51,10 @@ fn main() { println!("Memo: {}", payload.memo); println!("BIP39 entropy: {}", hex::encode(&payload.bip39_entropy)); } - _ => {} + _ => { + println!("Failed decoding b58, empty PrintableWrapper"); + std::process::exit(1); + } }, Err(err) => { From 5382da5b9a87da96048676aa9ed52074e3a70260 Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Sun, 18 May 2025 18:05:32 -0700 Subject: [PATCH 07/13] Update mobilecoind/src/service.rs Co-authored-by: Eran Rundstein --- mobilecoind/src/service.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/mobilecoind/src/service.rs b/mobilecoind/src/service.rs index 2b59aba842..275a9b59a8 100644 --- a/mobilecoind/src/service.rs +++ b/mobilecoind/src/service.rs @@ -680,12 +680,7 @@ impl Date: Sun, 18 May 2025 18:42:49 -0700 Subject: [PATCH 08/13] Apply suggestions from code review Co-authored-by: Eran Rundstein --- fog/ledger/server/src/router_service.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fog/ledger/server/src/router_service.rs b/fog/ledger/server/src/router_service.rs index 6602919f35..04135f0142 100644 --- a/fog/ledger/server/src/router_service.rs +++ b/fog/ledger/server/src/router_service.rs @@ -122,7 +122,7 @@ where } _ => { let error = rpc_internal_error( - "Inavlid LedgerRequest response", + "Invalid LedgerRequest response", "Cannot provide a check key image response to the client's key image request." .to_string(), &scope_logger, @@ -168,7 +168,7 @@ impl FogKeyImageApi for LedgerRouterService { Some(ledger_response::ResponseData::Auth(auth)) => sink.success(auth), _ => { let error = rpc_internal_error( - "Inavlid LedgerRequest response", + "Invalid LedgerRequest response", "Response to client's auth request did not contain an auth response." .to_string(), &logger, From d0be44da0382ed414792e083e111a19d3ff3e2c2 Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Sun, 18 May 2025 18:48:11 -0700 Subject: [PATCH 09/13] Apply suggestions from code review Co-authored-by: Eran Rundstein --- fog/report/api/test-utils/src/lib.rs | 2 +- fog/view/server/src/router_request_handler.rs | 2 +- mobilecoind-dev-faucet/src/lib.rs | 13 +++++-------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/fog/report/api/test-utils/src/lib.rs b/fog/report/api/test-utils/src/lib.rs index 5f91fb4909..ff9fba0798 100644 --- a/fog/report/api/test-utils/src/lib.rs +++ b/fog/report/api/test-utils/src/lib.rs @@ -2,7 +2,7 @@ use prost::Message as ProstMessage; -/// Take two ProstMessage values . +/// Take two ProstMessage values. /// /// Try to encode the first prost message, decode as the second prost message, /// re-encode that, and decode as first prost again, and check that you got the diff --git a/fog/view/server/src/router_request_handler.rs b/fog/view/server/src/router_request_handler.rs index 159480da1f..4f7d9d4a76 100644 --- a/fog/view/server/src/router_request_handler.rs +++ b/fog/view/server/src/router_request_handler.rs @@ -83,7 +83,7 @@ where } _ => { let rpc_status = rpc_invalid_arg_error( - "Inavlid FogViewRouterRequest request", + "Invalid FogViewRouterRequest request", "Neither the query nor auth fields were set".to_string(), &logger, ); diff --git a/mobilecoind-dev-faucet/src/lib.rs b/mobilecoind-dev-faucet/src/lib.rs index c8be44c6d2..025c2feb21 100644 --- a/mobilecoind-dev-faucet/src/lib.rs +++ b/mobilecoind-dev-faucet/src/lib.rs @@ -229,9 +229,8 @@ impl State { let monitor_printable_wrapper = PrintableWrapper::b58_decode(monitor_b58_address.clone()) .expect("Could not decode b58 address"); - let monitor_public_address = match monitor_printable_wrapper.wrapper { - Some(printable_wrapper::Wrapper::PublicAddress(address)) => address, - _ => panic!("Printable Wrapper did not contain public address"), + let Some(printable_wrapper::Wrapper::PublicAddress(monitor_public_address)) = monitor_printable_wrapper.wrapper else { + panic!("Printable Wrapper did not contain public address"); }; // Get the network minimum fees and compute faucet amounts @@ -272,14 +271,12 @@ impl State { let printable_wrapper = PrintableWrapper::b58_decode(req.b58_address.clone()) .map_err(|err| format!("Could not decode b58 address: {err}"))?; - let public_address = match printable_wrapper.wrapper { - Some(printable_wrapper::Wrapper::PublicAddress(address)) => address, - _ => { + let Some(printable_wrapper::Wrapper::PublicAddress(public_address) = printable_wrapper.wrapper else { return Err(format!( "b58 address '{}' is not a public address", req.b58_address - )) - } + )); + }; }; let token_id = TokenId::from(req.token_id.as_ref()); From 23a67def317b542e9ee7fac186e1428d21d503d4 Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Sun, 18 May 2025 19:01:24 -0700 Subject: [PATCH 10/13] Use Some(Default::default()) --- fog/view/server/src/shard_responses_processor.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fog/view/server/src/shard_responses_processor.rs b/fog/view/server/src/shard_responses_processor.rs index 2697f91baa..2c7d8fbd95 100644 --- a/fog/view/server/src/shard_responses_processor.rs +++ b/fog/view/server/src/shard_responses_processor.rs @@ -117,10 +117,7 @@ mod tests { FogViewStoreScheme::DEFAULT_INSECURE_PORT, ); let successful_response = mc_fog_api::fog_view::MultiViewStoreQueryResponse { - query_response: Some(attest::NonceMessage { - data: vec![], - ..Default::default() - }), + query_response: Some(Default::default()), store_uri: view_uri_string, block_range: Some(mc_fog_api::fog_common::BlockRange::from(&block_range)), status: mc_fog_api::fog_view::MultiViewStoreQueryResponseStatus::Success.into(), From ac2bbb31426213d739030909f6e36d5919079d5a Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Mon, 19 May 2025 08:46:15 -0700 Subject: [PATCH 11/13] Fix brackets for one of the code suggestions --- .../server/src/shard_responses_processor.rs | 1 - mobilecoind-dev-faucet/src/lib.rs | 17 ++++++++++------- mobilecoind/src/service.rs | 13 +++++++------ 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/fog/view/server/src/shard_responses_processor.rs b/fog/view/server/src/shard_responses_processor.rs index 2c7d8fbd95..22d58b58eb 100644 --- a/fog/view/server/src/shard_responses_processor.rs +++ b/fog/view/server/src/shard_responses_processor.rs @@ -97,7 +97,6 @@ mod tests { use super::*; use crate::sharding_strategy::{EpochShardingStrategy, ShardingStrategy}; use grpcio::ChannelBuilder; - use mc_attest_api::attest; use mc_common::logger::test_with_logger; use mc_fog_api::fog_view::FogViewStoreApiClient; use mc_fog_types::common::BlockRange; diff --git a/mobilecoind-dev-faucet/src/lib.rs b/mobilecoind-dev-faucet/src/lib.rs index 025c2feb21..a0adb39b68 100644 --- a/mobilecoind-dev-faucet/src/lib.rs +++ b/mobilecoind-dev-faucet/src/lib.rs @@ -229,7 +229,9 @@ impl State { let monitor_printable_wrapper = PrintableWrapper::b58_decode(monitor_b58_address.clone()) .expect("Could not decode b58 address"); - let Some(printable_wrapper::Wrapper::PublicAddress(monitor_public_address)) = monitor_printable_wrapper.wrapper else { + let Some(printable_wrapper::Wrapper::PublicAddress(monitor_public_address)) = + monitor_printable_wrapper.wrapper + else { panic!("Printable Wrapper did not contain public address"); }; @@ -271,12 +273,13 @@ impl State { let printable_wrapper = PrintableWrapper::b58_decode(req.b58_address.clone()) .map_err(|err| format!("Could not decode b58 address: {err}"))?; - let Some(printable_wrapper::Wrapper::PublicAddress(public_address) = printable_wrapper.wrapper else { - return Err(format!( - "b58 address '{}' is not a public address", - req.b58_address - )); - }; + let Some(printable_wrapper::Wrapper::PublicAddress(public_address)) = + printable_wrapper.wrapper + else { + return Err(format!( + "b58 address '{}' is not a public address", + req.b58_address + )); }; let token_id = TokenId::from(req.token_id.as_ref()); diff --git a/mobilecoind/src/service.rs b/mobilecoind/src/service.rs index 275a9b59a8..88ef7d88cd 100644 --- a/mobilecoind/src/service.rs +++ b/mobilecoind/src/service.rs @@ -680,12 +680,13 @@ impl Date: Mon, 19 May 2025 09:08:40 -0700 Subject: [PATCH 12/13] Update `send_consensus_msg` to handle unknown enum variants --- peers/src/threaded_broadcaster.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/peers/src/threaded_broadcaster.rs b/peers/src/threaded_broadcaster.rs index b0e46d0ce6..b4875b85f6 100644 --- a/peers/src/threaded_broadcaster.rs +++ b/peers/src/threaded_broadcaster.rs @@ -399,13 +399,21 @@ impl PeerThread { let retry_iterator = retry_policy.get_delay_iterator().with_deadline(deadline); match conn.send_consensus_msg(&arc_msg, retry_iterator) { - Ok(resp) => match resp.result() { - ConsensusMsgResult::Ok => {} - ConsensusMsgResult::UnknownPeer => log::info!( + Ok(resp) => match ConsensusMsgResult::from_i32(resp.result) { + Some(ConsensusMsgResult::Ok) => {} + Some(ConsensusMsgResult::UnknownPeer) => log::info!( logger, "Peer {}: does not accept broadcast messages from unknown peers", conn ), + None => { + log::info!( + logger, + "Peer {}: returned unknown result: {:?}", + conn, + resp.result + ); + } }, Err(err) => { log::error!( From f1ee926430ec540aa661c365780b700ca6272adc Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Mon, 19 May 2025 09:15:19 -0700 Subject: [PATCH 13/13] Update MintvalidationResult conversion to better handle unknown variants --- consensus/api/src/conversions.rs | 40 ++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/consensus/api/src/conversions.rs b/consensus/api/src/conversions.rs index 7ed23dcbd6..2091119957 100644 --- a/consensus/api/src/conversions.rs +++ b/consensus/api/src/conversions.rs @@ -163,43 +163,53 @@ impl TryInto for MintValidationResult { type Error = String; fn try_into(self) -> Result { - match self.code() { - MintValidationResultCode::Ok => { + match MintValidationResultCode::from_i32(self.code) { + Some(MintValidationResultCode::Ok) => { Err("Ok value cannot be converted into MintValidationError".to_string()) } - MintValidationResultCode::InvalidBlockVersion => { + Some(MintValidationResultCode::InvalidBlockVersion) => { Ok(MintValidationError::InvalidBlockVersion( BlockVersion::try_from(self.block_version).map_err(|err| err.to_string())?, )) } - MintValidationResultCode::InvalidTokenId => { + Some(MintValidationResultCode::InvalidTokenId) => { Ok(MintValidationError::InvalidTokenId(self.token_id.into())) } - MintValidationResultCode::InvalidNonceLength => Ok( + Some(MintValidationResultCode::InvalidNonceLength) => Ok( MintValidationError::InvalidNonceLength(self.nonce_length as usize), ), - MintValidationResultCode::InvalidSignerSet => Ok(MintValidationError::InvalidSignerSet), - MintValidationResultCode::InvalidSignature => Ok(MintValidationError::InvalidSignature), - MintValidationResultCode::TombstoneBlockExceeded => { + Some(MintValidationResultCode::InvalidSignerSet) => { + Ok(MintValidationError::InvalidSignerSet) + } + Some(MintValidationResultCode::InvalidSignature) => { + Ok(MintValidationError::InvalidSignature) + } + Some(MintValidationResultCode::TombstoneBlockExceeded) => { Ok(MintValidationError::TombstoneBlockExceeded) } - MintValidationResultCode::TombstoneBlockTooFar => { + Some(MintValidationResultCode::TombstoneBlockTooFar) => { Ok(MintValidationError::TombstoneBlockTooFar) } - MintValidationResultCode::Unknown => Ok(MintValidationError::Unknown), - MintValidationResultCode::AmountExceedsMintLimit => { + Some(MintValidationResultCode::Unknown) => Ok(MintValidationError::Unknown), + Some(MintValidationResultCode::AmountExceedsMintLimit) => { Ok(MintValidationError::AmountExceedsMintLimit) } - MintValidationResultCode::NoGovernors => Ok(MintValidationError::NoGovernors( + Some(MintValidationResultCode::NoGovernors) => Ok(MintValidationError::NoGovernors( TokenId::from(self.token_id), )), - MintValidationResultCode::NonceAlreadyUsed => Ok(MintValidationError::NonceAlreadyUsed), - MintValidationResultCode::NoMatchingMintConfig => { + Some(MintValidationResultCode::NonceAlreadyUsed) => { + Ok(MintValidationError::NonceAlreadyUsed) + } + Some(MintValidationResultCode::NoMatchingMintConfig) => { Ok(MintValidationError::NoMatchingMintConfig) } - MintValidationResultCode::MintingToFogNotSupported => { + Some(MintValidationResultCode::MintingToFogNotSupported) => { Ok(MintValidationError::MintingToFogNotSupported) } + None => Err(format!( + "Unknown code value ({}) cannot be converted into MintValidationError", + self.code + )), } } }