From aa87e354641bd1672b89807e3effbd7f9e35ea82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex?= Date: Fri, 26 Jun 2026 20:59:13 +0000 Subject: [PATCH] chore(dependencies): Update to use LB better errors (#47) * Adapt module to OperationStatus result-like update. * Prettify. * Update flake. --- flake.lock | 8 +- flake.nix | 2 +- src/logos_blockchain_module.cpp | 188 +++++++++++--------------- src/logos_blockchain_module.h | 2 +- tests/mocks/mock_logos_blockchain.cpp | 69 +++++----- tests/stubs/logos_blockchain.h | 24 +++- tests/test_blockchain.cpp | 9 +- 7 files changed, 151 insertions(+), 151 deletions(-) diff --git a/flake.lock b/flake.lock index 5c51f8d..f0098b2 100644 --- a/flake.lock +++ b/flake.lock @@ -98,16 +98,16 @@ "rust-rapidsnark": "rust-rapidsnark" }, "locked": { - "lastModified": 1782472464, - "narHash": "sha256-cAutgFKnxPX6S/EuXgzM8/e/NOkVFOq60P8Pv0EUAH4=", + "lastModified": 1782491660, + "narHash": "sha256-F+dkzPyOP1zLat3CKV4BqxLN9ZQnS03gEOgijshVmmc=", "owner": "logos-blockchain", "repo": "logos-blockchain", - "rev": "fb326a3acef3cbee621cbe488099bc2359373edb", + "rev": "56a74d2bbd5d1e2079af114c304dfdf22335c4de", "type": "github" }, "original": { "owner": "logos-blockchain", - "ref": "0.1.3-rc.13", + "ref": "56a74d2bbd5d1e2079af114c304dfdf22335c4de", "repo": "logos-blockchain", "type": "github" } diff --git a/flake.nix b/flake.nix index d81c3ff..6ab4351 100644 --- a/flake.nix +++ b/flake.nix @@ -4,7 +4,7 @@ inputs = { logos-module-builder.url = "github:logos-co/logos-module-builder?ref=92ef691ea72844134f6c68fb447d37f855fc9690"; # https://github.com/logos-blockchain/logos-blockchain/commit/58d71393cb7c5e8d425f54b09f2f28e0d9905fdc - logos-blockchain.url = "github:logos-blockchain/logos-blockchain?ref=0.1.3-rc.13"; + logos-blockchain.url = "github:logos-blockchain/logos-blockchain?ref=56a74d2bbd5d1e2079af114c304dfdf22335c4de"; }; outputs = inputs@{ logos-module-builder, ... }: diff --git a/src/logos_blockchain_module.cpp b/src/logos_blockchain_module.cpp index 3c7a40b..6f93f43 100644 --- a/src/logos_blockchain_module.cpp +++ b/src/logos_blockchain_module.cpp @@ -17,6 +17,19 @@ using json = nlohmann::json; // Define static member LogosBlockchainModule* LogosBlockchainModule::s_instance = nullptr; +namespace operation_status { + // Takes the Rust-allocated message out of an OperationStatus and frees it. + std::string take_message(OperationStatus& status) { + std::string message; + if (status.message) { + message = status.message; + (void)free_cstring(status.message); + status.message = nullptr; + } + return message; + } +} // namespace operation_status + // Shorthands for building StdLogosResult values. namespace result { StdLogosResult ok() { @@ -31,6 +44,13 @@ namespace result { StdLogosResult err(std::string message) { return {false, {}, std::move(message)}; } + + StdLogosResult from_operation_status(OperationStatus& status) { + if (is_ok(&status)) { + return ok(); + } + return err(operation_status::take_message(status)); + } } // namespace result namespace { @@ -269,7 +289,7 @@ LogosBlockchainModule::~LogosBlockchainModule() { // Lifecycle -StdLogosResult LogosBlockchainModule::generate_user_config(const std::string& json_args) { +StdLogosResult LogosBlockchainModule::generate_user_config(const std::string& json_args) const { json parsed_args; try { parsed_args = json::parse(json_args); @@ -287,8 +307,7 @@ StdLogosResult LogosBlockchainModule::generate_user_config(const std::string& js // standalone callers omit the flag and keep their own paths (or the node // defaults). Any path the caller set explicitly is left untouched. bool use_persistence_paths = false; - if (const auto it = parsed_args.find("use_persistence_paths"); - it != parsed_args.end() && it->is_boolean()) { + if (const auto it = parsed_args.find("use_persistence_paths"); it != parsed_args.end() && it->is_boolean()) { use_persistence_paths = it->get(); } parsed_args.erase("use_persistence_paths"); // not an FFI field @@ -299,9 +318,8 @@ StdLogosResult LogosBlockchainModule::generate_user_config(const std::string& js const fs::path base(persistence); // Only fill a path the caller didn't pin (non-empty string wins). const auto set_if_absent = [&parsed_args](const char* key, const std::string& value) { - const bool provided = parsed_args.contains(key) - && parsed_args[key].is_string() - && !parsed_args[key].get().empty(); + const bool provided = parsed_args.contains(key) && parsed_args[key].is_string() && + !parsed_args[key].get().empty(); if (!provided) parsed_args[key] = value; }; @@ -316,8 +334,8 @@ StdLogosResult LogosBlockchainModule::generate_user_config(const std::string& js // as relative to the base; a missing output defaults to // "/user_config.yaml". fs::path output_rel = "user_config.yaml"; - if (parsed_args.contains("output") && parsed_args["output"].is_string() - && !parsed_args["output"].get().empty()) { + if (parsed_args.contains("output") && parsed_args["output"].is_string() && + !parsed_args["output"].get().empty()) { const fs::path given(localPathFromFileUrl(parsed_args["output"].get())); const fs::path rel = given.relative_path(); output_rel = rel.empty() ? given.filename() : rel; @@ -334,7 +352,8 @@ StdLogosResult LogosBlockchainModule::generate_user_config(const std::string& js } else { fprintf( stderr, - "generate_user_config: use_persistence_paths requested but no instance persistence path is set; leaving paths unchanged.\n" + "generate_user_config: use_persistence_paths requested but no instance persistence path is set; " + "leaving paths unchanged.\n" ); } } @@ -349,10 +368,9 @@ StdLogosResult LogosBlockchainModule::generate_user_config(const std::string& js const OwnedGenerateConfigArgs owned_args(parsed_args); - const OperationStatus status = ::generate_user_config(owned_args.ffi_args); + OperationStatus status = ::generate_user_config(owned_args.ffi_args); if (!is_ok(&status)) { - fprintf(stderr, "Failed to generate user config. Error: %d\n", status); - return result::err("Failed to generate user config."); + return result::err(operation_status::take_message(status)); } return result::ok(resolved_output); @@ -384,28 +402,19 @@ StdLogosResult LogosBlockchainModule::start(const std::string& config_path, cons const char* deployment_ptr = deployment_path.empty() ? nullptr : deployment_path.c_str(); auto [value, error] = start_lb_node(config_path_ptr, deployment_ptr); - fprintf(stderr, "Start node returned with value and error.\n"); if (!is_ok(&error)) { - fprintf(stderr, "Failed to start the node. Error: %d\n", error); - return result::err("Failed to start the node."); + return result::err(operation_status::take_message(error)); } node = value; - fprintf(stderr, "The node was started successfully.\n"); if (!node) { - fprintf(stderr, "Could not subscribe to block events: The node is not running.\n"); return result::err("Could not subscribe to block events: the node is not running."); } s_instance = this; - const OperationStatus subscribe_status = subscribe_to_new_blocks(node, on_new_block_callback); - if (!is_ok(&subscribe_status)) { - fprintf(stderr, "Failed to subscribe to new blocks. Error: %d\n", subscribe_status); - return result::err("Failed to subscribe to new blocks."); - } - - return result::ok(); + OperationStatus subscribe_status = subscribe_to_new_blocks(node, on_new_block_callback); + return result::from_operation_status(subscribe_status); } StdLogosResult LogosBlockchainModule::stop() { @@ -416,11 +425,9 @@ StdLogosResult LogosBlockchainModule::stop() { s_instance = nullptr; - const OperationStatus status = stop_node(node); - if (is_ok(&status)) { - fprintf(stderr, "The node was stopped successfully.\n"); - } else { - fprintf(stderr, "Could not stop the node. Error: %d\n", status); + OperationStatus status = stop_node(node); + if (!is_ok(&status)) { + fprintf(stderr, "Could not stop the node: %s\n", operation_status::take_message(status).c_str()); } node = nullptr; @@ -436,12 +443,8 @@ StdLogosResult LogosBlockchainModule::update_user_config( const std::string config = localPathFromFileUrl(user_config_path); const std::string keystore = localPathFromFileUrl(keystore_path); - const OperationStatus status = ::update_user_config(config.c_str(), keystore.c_str()); - if (!is_ok(&status)) { - fprintf(stderr, "Failed to update user config. Error: %d\n", status); - return result::err("Failed to update user config."); - } - return result::ok(); + OperationStatus status = ::update_user_config(config.c_str(), keystore.c_str()); + return result::from_operation_status(status); } StdLogosResult LogosBlockchainModule::migrate_user_config( @@ -451,12 +454,8 @@ StdLogosResult LogosBlockchainModule::migrate_user_config( const std::string output = localPathFromFileUrl(output_path); const std::string keystore = localPathFromFileUrl(keystore_path); - const OperationStatus status = ::migrate_user_config(output.c_str(), keystore.c_str()); - if (!is_ok(&status)) { - fprintf(stderr, "Failed to migrate user config. Error: %d\n", status); - return result::err("Failed to migrate user config."); - } - return result::ok(); + OperationStatus status = ::migrate_user_config(output.c_str(), keystore.c_str()); + return result::from_operation_status(status); } StdLogosResult LogosBlockchainModule::migrate_user_config_0_1_2( @@ -468,13 +467,8 @@ StdLogosResult LogosBlockchainModule::migrate_user_config_0_1_2( const std::string old_config = localPathFromFileUrl(old_config_path); const std::string keystore = localPathFromFileUrl(keystore_path); - const OperationStatus status = - ::migrate_user_config_0_1_2(new_config.c_str(), old_config.c_str(), keystore.c_str()); - if (!is_ok(&status)) { - fprintf(stderr, "Failed to migrate 0.1.2 config. Error: %d\n", status); - return result::err("Failed to migrate 0.1.2 config."); - } - return result::ok(); + OperationStatus status = ::migrate_user_config_0_1_2(new_config.c_str(), old_config.c_str(), keystore.c_str()); + return result::from_operation_status(status); } StdLogosResult LogosBlockchainModule::participate( @@ -488,13 +482,8 @@ StdLogosResult LogosBlockchainModule::participate( const std::string output = localPathFromFileUrl(output_dir); const char* external_address_ptr = external_address.empty() ? nullptr : external_address.c_str(); - const OperationStatus status = - ::participate(config.c_str(), keystore.c_str(), output.c_str(), external_address_ptr); - if (!is_ok(&status)) { - fprintf(stderr, "Failed to generate participation data. Error: %d\n", status); - return result::err("Failed to generate participation data."); - } - return result::ok(); + OperationStatus status = ::participate(config.c_str(), keystore.c_str(), output.c_str(), external_address_ptr); + return result::from_operation_status(status); } // Keystore @@ -516,14 +505,13 @@ StdLogosResult LogosBlockchainModule::generate_key( auto [value, error] = ::generate_key(config.c_str(), keystore.c_str(), type, key_title_ptr); if (!is_ok(&error)) { - fprintf(stderr, "Failed to generate key. Error: %d\n", error); - return result::err("Failed to generate key: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } const std::string out(value); - const OperationStatus free_status = free_cstring(value); + OperationStatus free_status = free_cstring(value); if (!is_ok(&free_status)) { - fprintf(stderr, "Failed to free key id string. Error: %d\n", free_status); + fprintf(stderr, "Failed to free key id string: %s\n", operation_status::take_message(free_status).c_str()); } return result::ok(out); } @@ -545,12 +533,8 @@ StdLogosResult LogosBlockchainModule::add_key( const std::string keystore = localPathFromFileUrl(keystore_path); const char* key_title_ptr = key_title.empty() ? nullptr : key_title.c_str(); - const OperationStatus status = ::add_key(config.c_str(), keystore.c_str(), type, key_hex.c_str(), key_title_ptr); - if (!is_ok(&status)) { - fprintf(stderr, "Failed to add key. Error: %d\n", status); - return result::err("Failed to add key."); - } - return result::ok(); + OperationStatus status = ::add_key(config.c_str(), keystore.c_str(), type, key_hex.c_str(), key_title_ptr); + return result::from_operation_status(status); } StdLogosResult LogosBlockchainModule::remove_key( @@ -561,12 +545,8 @@ StdLogosResult LogosBlockchainModule::remove_key( const std::string config = localPathFromFileUrl(user_config_path); const std::string keystore = localPathFromFileUrl(keystore_path); - const OperationStatus status = ::remove_key(config.c_str(), keystore.c_str(), key_title.c_str()); - if (!is_ok(&status)) { - fprintf(stderr, "Failed to remove key. Error: %d\n", status); - return result::err("Failed to remove key."); - } - return result::ok(); + OperationStatus status = ::remove_key(config.c_str(), keystore.c_str(), key_title.c_str()); + return result::from_operation_status(status); } // Identity @@ -576,14 +556,13 @@ StdLogosResult LogosBlockchainModule::get_peer_id(const std::string& config_path auto [value, error] = ::get_peer_id(config.c_str()); if (!is_ok(&error)) { - fprintf(stderr, "Failed to get peer id. Error: %d\n", error); - return result::err("Failed to get peer id: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } const std::string out(value); - const OperationStatus free_status = free_cstring(value); + OperationStatus free_status = free_cstring(value); if (!is_ok(&free_status)) { - fprintf(stderr, "Failed to free peer id string. Error: %d\n", free_status); + fprintf(stderr, "Failed to free peer id string: %s\n", operation_status::take_message(free_status).c_str()); } return result::ok(out); } @@ -603,7 +582,7 @@ StdLogosResult LogosBlockchainModule::wallet_get_balance(const std::string& addr auto [value, error] = get_balance(node, bytes.data(), nullptr); if (!is_ok(&error)) { - return result::err("Failed to get balance: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } return result::ok(std::to_string(value)); @@ -671,7 +650,7 @@ StdLogosResult LogosBlockchainModule::wallet_transfer_funds( auto [value, error] = transfer_funds(node, &args); if (!is_ok(&error)) { - return result::err("Failed to transfer funds: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } return result::ok(bytes_to_hex(reinterpret_cast(&value), ADDRESS_BYTES)); } @@ -683,8 +662,7 @@ StdLogosResult LogosBlockchainModule::wallet_get_known_addresses() const { } auto [value, error] = get_known_addresses(node); if (!is_ok(&error)) { - fprintf(stderr, "Failed to get known addresses. Error: %d\n", error); - return result::err("Failed to get known addresses: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } std::vector out; for (size_t i = 0; i < value.len; ++i) { @@ -694,9 +672,9 @@ StdLogosResult LogosBlockchainModule::wallet_get_known_addresses() const { out.push_back(bytes_to_hex(ptr, ADDRESS_BYTES)); } } - const OperationStatus free_status = free_known_addresses(value); + OperationStatus free_status = free_known_addresses(value); if (!is_ok(&free_status)) { - fprintf(stderr, "Failed to free known addresses. Error: %d\n", free_status); + fprintf(stderr, "Failed to free known addresses: %s\n", operation_status::take_message(free_status).c_str()); } fprintf( stderr, @@ -732,7 +710,7 @@ StdLogosResult LogosBlockchainModule::wallet_get_notes( auto [value, error] = get_wallet_notes(node, address_bytes.data(), optional_tip); if (!is_ok(&error)) { - return result::err("Failed to get wallet notes: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } json obj; @@ -748,9 +726,9 @@ StdLogosResult LogosBlockchainModule::wallet_get_notes( } obj["notes"] = std::move(notes); - const OperationStatus free_status = free_wallet_notes(value); + OperationStatus free_status = free_wallet_notes(value); if (!is_ok(&free_status)) { - fprintf(stderr, "Failed to free wallet notes. Error: %d\n", free_status); + fprintf(stderr, "Failed to free wallet notes: %s\n", operation_status::take_message(free_status).c_str()); } return result::ok(obj.dump()); } @@ -762,7 +740,7 @@ StdLogosResult LogosBlockchainModule::leader_claim() const { auto [value, error] = ::leader_claim(node); if (!is_ok(&error)) { - return result::err("Failed to claim leader rewards: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } return result::ok(bytes_to_hex(reinterpret_cast(&value), TX_HASH_BYTES)); @@ -827,7 +805,7 @@ StdLogosResult LogosBlockchainModule::channel_deposit( auto [value, error] = ::channel_deposit(node, &args); if (!is_ok(&error)) { - return result::err("Failed to deposit into channel: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } return result::ok(bytes_to_hex(reinterpret_cast(&value), ADDRESS_BYTES)); } @@ -923,7 +901,7 @@ StdLogosResult LogosBlockchainModule::channel_deposit_with_notes( auto [value, error] = ::channel_deposit_with_notes(node, &args); if (!is_ok(&error)) { - return result::err("Failed to deposit into channel: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } return result::ok(bytes_to_hex(reinterpret_cast(&value), ADDRESS_BYTES)); } @@ -935,7 +913,7 @@ StdLogosResult LogosBlockchainModule::wallet_get_claimable_vouchers() const { auto [value, error] = get_claimable_vouchers(node, nullptr); if (!is_ok(&error)) { - return result::err("Failed to get claimable vouchers: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } json obj; @@ -950,9 +928,9 @@ StdLogosResult LogosBlockchainModule::wallet_get_claimable_vouchers() const { }); } - const OperationStatus free_status = free_claimable_vouchers(value); + OperationStatus free_status = free_claimable_vouchers(value); if (!is_ok(&free_status)) { - fprintf(stderr, "Failed to free claimable vouchers. Error: %d\n", free_status); + fprintf(stderr, "Failed to free claimable vouchers: %s\n", operation_status::take_message(free_status).c_str()); } return result::ok(obj.dump()); @@ -1001,7 +979,7 @@ StdLogosResult LogosBlockchainModule::blend_join_as_core_node( locators_ptrs.size() ); if (!is_ok(&error)) { - return result::err("Failed to join as core node: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } std::string declaration_id = bytes_to_hex(reinterpret_cast(&value), sizeof(value)); @@ -1023,14 +1001,13 @@ StdLogosResult LogosBlockchainModule::get_block(const std::string& header_id_hex auto [value, error] = ::get_block(node, reinterpret_cast(bytes.data())); if (!is_ok(&error)) { - fprintf(stderr, "Failed to get block. Error: %d\n", error); - return result::err("Failed to get block: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } std::string out(value); - const OperationStatus free_status = free_cstring(value); + OperationStatus free_status = free_cstring(value); if (!is_ok(&free_status)) { - fprintf(stderr, "Failed to free block string. Error: %d\n", free_status); + fprintf(stderr, "Failed to free block string: %s\n", operation_status::take_message(free_status).c_str()); } return result::ok(std::move(out)); } @@ -1042,14 +1019,13 @@ StdLogosResult LogosBlockchainModule::get_blocks(const uint64_t from_slot, const auto [value, error] = ::get_blocks(node, from_slot, to_slot); if (!is_ok(&error)) { - fprintf(stderr, "Failed to get blocks. Error: %d\n", error); - return result::err("Failed to get blocks: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } std::string out(value); - const OperationStatus free_status = free_cstring(value); + OperationStatus free_status = free_cstring(value); if (!is_ok(&free_status)) { - fprintf(stderr, "Failed to free blocks string. Error: %d\n", free_status); + fprintf(stderr, "Failed to free blocks string: %s\n", operation_status::take_message(free_status).c_str()); } return result::ok(std::move(out)); } @@ -1066,14 +1042,13 @@ StdLogosResult LogosBlockchainModule::get_transaction(const std::string& tx_hash auto [value, error] = ::get_transaction(node, reinterpret_cast(bytes.data())); if (!is_ok(&error)) { - fprintf(stderr, "Failed to get transaction. Error: %d\n", error); - return result::err("Failed to get transaction: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } std::string out(value); - const OperationStatus free_status = free_cstring(value); + OperationStatus free_status = free_cstring(value); if (!is_ok(&free_status)) { - fprintf(stderr, "Failed to free transaction string. Error: %d\n", free_status); + fprintf(stderr, "Failed to free transaction string: %s\n", operation_status::take_message(free_status).c_str()); } return result::ok(std::move(out)); } @@ -1087,8 +1062,7 @@ StdLogosResult LogosBlockchainModule::get_cryptarchia_info() const { auto [value, error] = ::get_cryptarchia_info(node); if (!is_ok(&error)) { - fprintf(stderr, "Failed to get cryptarchia info. Error: %d\n", error); - return result::err("Failed to get cryptarchia info: " + std::to_string(error)); + return result::err(operation_status::take_message(error)); } json obj; @@ -1098,9 +1072,9 @@ StdLogosResult LogosBlockchainModule::get_cryptarchia_info() const { obj["height"] = static_cast(value->height); obj["mode"] = (value->mode == State::Online) ? "Online" : "Bootstrapping"; - const OperationStatus free_status = free_cryptarchia_info(value); + OperationStatus free_status = free_cryptarchia_info(value); if (!is_ok(&free_status)) { - fprintf(stderr, "Failed to free cryptarchia info. Error: %d\n", free_status); + fprintf(stderr, "Failed to free cryptarchia info: %s\n", operation_status::take_message(free_status).c_str()); } return result::ok(obj.dump()); } diff --git a/src/logos_blockchain_module.h b/src/logos_blockchain_module.h index d1959a4..22cf848 100644 --- a/src/logos_blockchain_module.h +++ b/src/logos_blockchain_module.h @@ -34,7 +34,7 @@ public: // state/storage/logs path always wins; output is always re-anchored under the // base when flagged. On success the result value is the path the config was // written to — pass it straight to start(). - [[nodiscard]] StdLogosResult generate_user_config(const std::string& json_args); + [[nodiscard]] StdLogosResult generate_user_config(const std::string& json_args) const; [[nodiscard]] static StdLogosResult update_user_config( const std::string& user_config_path, const std::string& keystore_path diff --git a/tests/mocks/mock_logos_blockchain.cpp b/tests/mocks/mock_logos_blockchain.cpp index 233cfaa..c0d61e7 100644 --- a/tests/mocks/mock_logos_blockchain.cpp +++ b/tests/mocks/mock_logos_blockchain.cpp @@ -27,10 +27,17 @@ static uint8_t s_mockAddr3[32]; static uint8_t* s_mockAddrs[] = { s_mockAddr0, s_mockAddr1, s_mockAddr2, s_mockAddr3 }; static ClaimableVoucher s_mockClaimableVouchers[4]; +static OperationStatus make_status(int code) { + OperationStatus s; + s.code = static_cast(code); + s.message = code != 0 ? strdup("mock error") : nullptr; + return s; +} + extern "C" { bool is_ok(const OperationStatus* status) { - return status && *status == 0; + return status && status->code == OperationStatusCode_Ok; } OperationStatus generate_user_config(GenerateConfigArgs args) { @@ -39,7 +46,7 @@ OperationStatus generate_user_config(GenerateConfigArgs args) { g_lastGeneratedStatePath = args.state_path ? args.state_path : ""; g_lastGeneratedStoragePath = args.storage_path ? args.storage_path : ""; g_lastGeneratedLogsPath = args.logs_path ? args.logs_path : ""; - return LOGOS_CMOCK_RETURN(int, "generate_user_config"); + return make_status(LOGOS_CMOCK_RETURN(int, "generate_user_config")); } NodeResult start_lb_node(const char* config_path, const char* deployment) { @@ -47,23 +54,23 @@ NodeResult start_lb_node(const char* config_path, const char* deployment) { int ok = LOGOS_CMOCK_RETURN(int, "start_lb_node"); NodeResult result; result.value = ok ? reinterpret_cast(&s_fakeNode) : nullptr; - result.error = ok ? 0 : 1; + result.error = make_status(ok ? 0 : 1); return result; } OperationStatus stop_node(LogosBlockchainNode* node) { LOGOS_CMOCK_RECORD("stop_node"); - return 0; + return make_status(0); } OperationStatus update_user_config(const char* user_config_path, const char* keystore_path) { LOGOS_CMOCK_RECORD("update_user_config"); - return LOGOS_CMOCK_RETURN(int, "update_user_config"); + return make_status(LOGOS_CMOCK_RETURN(int, "update_user_config")); } OperationStatus migrate_user_config(const char* output_path, const char* keystore_path) { LOGOS_CMOCK_RECORD("migrate_user_config"); - return LOGOS_CMOCK_RETURN(int, "migrate_user_config"); + return make_status(LOGOS_CMOCK_RETURN(int, "migrate_user_config")); } OperationStatus migrate_user_config_0_1_2( @@ -72,7 +79,7 @@ OperationStatus migrate_user_config_0_1_2( const char* keystore_path) { LOGOS_CMOCK_RECORD("migrate_user_config_0_1_2"); - return LOGOS_CMOCK_RETURN(int, "migrate_user_config_0_1_2"); + return make_status(LOGOS_CMOCK_RETURN(int, "migrate_user_config_0_1_2")); } OperationStatus participate( @@ -82,7 +89,7 @@ OperationStatus participate( const char* external_address) { LOGOS_CMOCK_RECORD("participate"); - return LOGOS_CMOCK_RETURN(int, "participate"); + return make_status(LOGOS_CMOCK_RETURN(int, "participate")); } StringResult generate_key( @@ -95,7 +102,7 @@ StringResult generate_key( StringResult result; const char* id = LOGOS_CMOCK_RETURN_STRING("generate_key"); result.value = id ? strdup(id) : nullptr; - result.error = LOGOS_CMOCK_RETURN(int, "generate_key_error"); + result.error = make_status(LOGOS_CMOCK_RETURN(int, "generate_key_error")); return result; } @@ -107,7 +114,7 @@ OperationStatus add_key( const char* key_title) { LOGOS_CMOCK_RECORD("add_key"); - return LOGOS_CMOCK_RETURN(int, "add_key"); + return make_status(LOGOS_CMOCK_RETURN(int, "add_key")); } OperationStatus remove_key( @@ -116,7 +123,7 @@ OperationStatus remove_key( const char* key_title) { LOGOS_CMOCK_RECORD("remove_key"); - return LOGOS_CMOCK_RETURN(int, "remove_key"); + return make_status(LOGOS_CMOCK_RETURN(int, "remove_key")); } StringResult get_peer_id(const char* config_path) { @@ -124,20 +131,20 @@ StringResult get_peer_id(const char* config_path) { StringResult result; const char* id = LOGOS_CMOCK_RETURN_STRING("get_peer_id"); result.value = id ? strdup(id) : nullptr; - result.error = LOGOS_CMOCK_RETURN(int, "get_peer_id_error"); + result.error = make_status(LOGOS_CMOCK_RETURN(int, "get_peer_id_error")); return result; } OperationStatus subscribe_to_new_blocks(LogosBlockchainNode* node, BlockCallback callback) { LOGOS_CMOCK_RECORD("subscribe_to_new_blocks"); - return LOGOS_CMOCK_RETURN(int, "subscribe_to_new_blocks"); + return make_status(LOGOS_CMOCK_RETURN(int, "subscribe_to_new_blocks")); } BalanceResult get_balance(LogosBlockchainNode* node, const uint8_t* address, const void* reserved) { LOGOS_CMOCK_RECORD("get_balance"); BalanceResult result; result.value = static_cast(LOGOS_CMOCK_RETURN(int, "get_balance_value")); - result.error = LOGOS_CMOCK_RETURN(int, "get_balance_error"); + result.error = make_status(LOGOS_CMOCK_RETURN(int, "get_balance_error")); return result; } @@ -145,7 +152,7 @@ TransferHashResult transfer_funds(LogosBlockchainNode* node, const TransferFunds LOGOS_CMOCK_RECORD("transfer_funds"); TransferHashResult result; memset(result.value, 0xAB, sizeof(Hash)); - result.error = LOGOS_CMOCK_RETURN(int, "transfer_funds_error"); + result.error = make_status(LOGOS_CMOCK_RETURN(int, "transfer_funds_error")); return result; } @@ -153,7 +160,7 @@ FfiLeaderClaimResult leader_claim(LogosBlockchainNode* node) { LOGOS_CMOCK_RECORD("leader_claim"); FfiLeaderClaimResult result; memset(result.value, 0xEF, sizeof(TxHash)); - result.error = LOGOS_CMOCK_RETURN(int, "leader_claim_error"); + result.error = make_status(LOGOS_CMOCK_RETURN(int, "leader_claim_error")); return result; } @@ -161,7 +168,7 @@ KnownAddressesResult get_known_addresses(LogosBlockchainNode* node) { LOGOS_CMOCK_RECORD("get_known_addresses"); KnownAddressesResult result; int err = LOGOS_CMOCK_RETURN(int, "get_known_addresses_error"); - result.error = err; + result.error = make_status(err); if (err == 0) { int count = LOGOS_CMOCK_RETURN(int, "get_known_addresses_count"); if (count > 4) count = 4; @@ -180,14 +187,14 @@ KnownAddressesResult get_known_addresses(LogosBlockchainNode* node) { OperationStatus free_known_addresses(KnownAddresses addrs) { LOGOS_CMOCK_RECORD("free_known_addresses"); - return 0; + return make_status(0); } FfiClaimableVouchersResult get_claimable_vouchers(LogosBlockchainNode* node, const HeaderId* optional_tip) { LOGOS_CMOCK_RECORD("get_claimable_vouchers"); FfiClaimableVouchersResult result; int err = LOGOS_CMOCK_RETURN(int, "get_claimable_vouchers_error"); - result.error = err; + result.error = make_status(err); if (err == 0) { int count = LOGOS_CMOCK_RETURN(int, "get_claimable_vouchers_count"); if (count > 4) count = 4; @@ -208,7 +215,7 @@ FfiClaimableVouchersResult get_claimable_vouchers(LogosBlockchainNode* node, con OperationStatus free_claimable_vouchers(ClaimableVouchers vouchers) { LOGOS_CMOCK_RECORD("free_claimable_vouchers"); - return 0; + return make_status(0); } // Wallet-notes mock storage (up to 4 notes) @@ -223,7 +230,7 @@ FfiWalletNotesResult get_wallet_notes( FfiWalletNotesResult result; memset(&result.value, 0, sizeof(WalletNotes)); int err = LOGOS_CMOCK_RETURN(int, "get_wallet_notes_error"); - result.error = err; + result.error = make_status(err); if (err == 0) { int count = LOGOS_CMOCK_RETURN(int, "get_wallet_notes_count"); if (count > 4) count = 4; @@ -241,14 +248,14 @@ FfiWalletNotesResult get_wallet_notes( OperationStatus free_wallet_notes(WalletNotes notes) { LOGOS_CMOCK_RECORD("free_wallet_notes"); - return 0; + return make_status(0); } FfiChannelDepositResult channel_deposit(LogosBlockchainNode* node, const ChannelDepositArguments* arguments) { LOGOS_CMOCK_RECORD("channel_deposit"); FfiChannelDepositResult result; memset(result.value, 0xBC, sizeof(Hash)); - result.error = LOGOS_CMOCK_RETURN(int, "channel_deposit_error"); + result.error = make_status(LOGOS_CMOCK_RETURN(int, "channel_deposit_error")); return result; } @@ -259,7 +266,7 @@ FfiChannelDepositResult channel_deposit_with_notes( LOGOS_CMOCK_RECORD("channel_deposit_with_notes"); FfiChannelDepositResult result; memset(result.value, 0xDE, sizeof(Hash)); - result.error = LOGOS_CMOCK_RETURN(int, "channel_deposit_with_notes_error"); + result.error = make_status(LOGOS_CMOCK_RETURN(int, "channel_deposit_with_notes_error")); return result; } @@ -274,7 +281,7 @@ BlendHashResult blend_join_as_core_node( LOGOS_CMOCK_RECORD("blend_join_as_core_node"); BlendHashResult result; memset(result.value, 0xCD, sizeof(Hash)); - result.error = LOGOS_CMOCK_RETURN(int, "blend_join_as_core_node_error"); + result.error = make_status(LOGOS_CMOCK_RETURN(int, "blend_join_as_core_node_error")); return result; } @@ -283,7 +290,7 @@ StringResult get_block(LogosBlockchainNode* node, const HeaderId* header_id) { StringResult result; const char* json = LOGOS_CMOCK_RETURN_STRING("get_block"); result.value = json ? strdup(json) : nullptr; - result.error = LOGOS_CMOCK_RETURN(int, "get_block_error"); + result.error = make_status(LOGOS_CMOCK_RETURN(int, "get_block_error")); return result; } @@ -292,7 +299,7 @@ StringResult get_blocks(LogosBlockchainNode* node, uint64_t from_slot, uint64_t StringResult result; const char* json = LOGOS_CMOCK_RETURN_STRING("get_blocks"); result.value = json ? strdup(json) : nullptr; - result.error = LOGOS_CMOCK_RETURN(int, "get_blocks_error"); + result.error = make_status(LOGOS_CMOCK_RETURN(int, "get_blocks_error")); return result; } @@ -301,7 +308,7 @@ StringResult get_transaction(LogosBlockchainNode* node, const TxHash* tx_hash) { StringResult result; const char* json = LOGOS_CMOCK_RETURN_STRING("get_transaction"); result.value = json ? strdup(json) : nullptr; - result.error = LOGOS_CMOCK_RETURN(int, "get_transaction_error"); + result.error = make_status(LOGOS_CMOCK_RETURN(int, "get_transaction_error")); return result; } @@ -315,19 +322,19 @@ CryptarchiaInfoResult get_cryptarchia_info(LogosBlockchainNode* node) { memset(s_fakeCryptarchiaInfo.lib, 0xEE, 32); memset(s_fakeCryptarchiaInfo.tip, 0xFF, 32); result.value = &s_fakeCryptarchiaInfo; - result.error = LOGOS_CMOCK_RETURN(int, "get_cryptarchia_info_error"); + result.error = make_status(LOGOS_CMOCK_RETURN(int, "get_cryptarchia_info_error")); return result; } OperationStatus free_cryptarchia_info(CryptarchiaInfo* info) { LOGOS_CMOCK_RECORD("free_cryptarchia_info"); - return 0; + return make_status(0); } OperationStatus free_cstring(char* s) { LOGOS_CMOCK_RECORD("free_cstring"); free(s); - return 0; + return make_status(0); } } // extern "C" diff --git a/tests/stubs/logos_blockchain.h b/tests/stubs/logos_blockchain.h index d9caee1..13477ca 100644 --- a/tests/stubs/logos_blockchain.h +++ b/tests/stubs/logos_blockchain.h @@ -21,8 +21,28 @@ typedef Hash NoteId; // Opaque node handle typedef struct LogosBlockchainNode LogosBlockchainNode; -// Operation status (0 = OK) -typedef int OperationStatus; +// Operation status code (0 = OK) +typedef enum OperationStatusCode { + OperationStatusCode_Ok = 0, + OperationStatusCode_NotFound = 1, + OperationStatusCode_NullPointer = 2, + OperationStatusCode_RelayError = 3, + OperationStatusCode_ChannelSendError = 4, + OperationStatusCode_ChannelReceiveError = 5, + OperationStatusCode_ServiceError = 6, + OperationStatusCode_RuntimeError = 7, + OperationStatusCode_DynError = 8, + OperationStatusCode_InitializationError = 9, + OperationStatusCode_StopError = 10, + OperationStatusCode_ConfigurationError = 11, + OperationStatusCode_ValidationError = 12, +} OperationStatusCode; + +// Operation status: code + Rust-allocated error message (free with free_cstring). +typedef struct { + OperationStatusCode code; + char* message; +} OperationStatus; // Consensus state enum typedef enum { Bootstrapping, Online } State; diff --git a/tests/test_blockchain.cpp b/tests/test_blockchain.cpp index 24b2a0e..ad2512f 100644 --- a/tests/test_blockchain.cpp +++ b/tests/test_blockchain.cpp @@ -662,7 +662,6 @@ LOGOS_TEST(leader_claim_returns_error_on_ffi_failure) { StdLogosResult result = module->leader_claim(); LOGOS_ASSERT_FALSE(result.success); - LOGOS_ASSERT_TRUE(contains(result.error, "Failed to claim leader rewards")); delete module; } @@ -707,7 +706,7 @@ LOGOS_TEST(channel_deposit_returns_error_on_ffi_failure) { StdLogosResult result = module->channel_deposit(VALID_HEX, VALID_HEX, "100", "", ""); LOGOS_ASSERT_FALSE(result.success); - LOGOS_ASSERT_TRUE(contains(result.error, "Failed to deposit into channel")); + LOGOS_ASSERT_TRUE(contains(result.error, "mock error")); delete module; } @@ -829,7 +828,7 @@ LOGOS_TEST(wallet_get_notes_returns_error_on_ffi_failure) { StdLogosResult result = module->wallet_get_notes(VALID_HEX, ""); LOGOS_ASSERT_FALSE(result.success); - LOGOS_ASSERT_TRUE(contains(result.error, "Failed to get wallet notes")); + LOGOS_ASSERT_TRUE(contains(result.error, "mock error")); delete module; } @@ -874,7 +873,7 @@ LOGOS_TEST(channel_deposit_with_notes_returns_error_on_ffi_failure) { StdLogosResult result = module->channel_deposit_with_notes( VALID_HEX, {VALID_HEX}, "", VALID_HEX, {VALID_HEX}, "0", ""); LOGOS_ASSERT_FALSE(result.success); - LOGOS_ASSERT_TRUE(contains(result.error, "Failed to deposit into channel")); + LOGOS_ASSERT_TRUE(contains(result.error, "mock error")); delete module; } @@ -1022,7 +1021,7 @@ LOGOS_TEST(wallet_get_claimable_vouchers_returns_error_on_ffi_failure) { StdLogosResult result = module->wallet_get_claimable_vouchers(); LOGOS_ASSERT_FALSE(result.success); - LOGOS_ASSERT_TRUE(contains(result.error, "Failed to get claimable vouchers")); + LOGOS_ASSERT_TRUE(contains(result.error, "mock error")); delete module; }