feat(leader): expose leader reward claim (#31)

This commit is contained in:
Andrus Salumets 2026-06-15 15:53:24 +02:00 committed by GitHub
parent 138f792c75
commit fc1439cf16
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 69 additions and 6 deletions

8
flake.lock generated
View File

@ -24,16 +24,16 @@
"rust-rapidsnark": "rust-rapidsnark"
},
"locked": {
"lastModified": 1781288172,
"narHash": "sha256-4anGBb7slL6WfMCGlI4BmLAjim7kQOMD/qv4FCPJwII=",
"lastModified": 1781525456,
"narHash": "sha256-SOH9dY1Jg8JmfqMWMZ9YzbGQgWL+ifJ4z+8tHW/4zWs=",
"owner": "logos-blockchain",
"repo": "logos-blockchain",
"rev": "86e24cfd985b6341e96bba76ecad36ff379bd243",
"rev": "4efdf816e2a3d1447096c3f64c9e230769eb4ecb",
"type": "github"
},
"original": {
"owner": "logos-blockchain",
"ref": "86e24cfd985b6341e96bba76ecad36ff379bd243",
"ref": "4efdf816e2a3d1447096c3f64c9e230769eb4ecb",
"repo": "logos-blockchain",
"type": "github"
}

View File

@ -3,8 +3,8 @@
inputs = {
logos-module-builder.url = "github:logos-co/logos-module-builder";
# v0.1.3-rc.10-compatible + rust-rapidsnark nix fixes + cli commands
logos-blockchain.url = "github:logos-blockchain/logos-blockchain?ref=86e24cfd985b6341e96bba76ecad36ff379bd243";
# v0.1.3-rc.10-compatible + rust-rapidsnark nix fixes + cli commands + leader_claim C binding
logos-blockchain.url = "github:logos-blockchain/logos-blockchain?ref=4efdf816e2a3d1447096c3f64c9e230769eb4ecb";
};
outputs = inputs@{ logos-module-builder, ... }:

View File

@ -29,6 +29,7 @@ namespace {
// Use the C API type Hash (from logos_blockchain.h) to define address/hash byte size.
constexpr int ADDRESS_BYTES = sizeof(Hash);
constexpr int TX_HASH_BYTES = sizeof(TxHash);
constexpr int ADDRESS_HEX_LEN = ADDRESS_BYTES * 2;
std::vector<uint8_t> parse_address_hex(const std::string& address_hex) {
@ -612,6 +613,19 @@ std::vector<std::string> LogosBlockchainModule::wallet_get_known_addresses() {
return out;
}
std::string LogosBlockchainModule::leader_claim() {
if (!node) {
return "Error: The node is not running.";
}
auto [value, error] = ::leader_claim(node);
if (!is_ok(&error)) {
return "Error: Failed to claim leader rewards: " + std::to_string(error);
}
return bytes_to_hex(reinterpret_cast<const uint8_t*>(&value), TX_HASH_BYTES);
}
// Blend
std::string LogosBlockchainModule::blend_join_as_core_node(

View File

@ -75,6 +75,7 @@ public:
const std::string& optional_tip_hex
);
std::vector<std::string> wallet_get_known_addresses();
std::string leader_claim();
// Blend
std::string blend_join_as_core_node(

View File

@ -135,6 +135,14 @@ TransferHashResult transfer_funds(LogosBlockchainNode* node, const TransferFunds
return result;
}
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");
return result;
}
KnownAddressesResult get_known_addresses(LogosBlockchainNode* node) {
LOGOS_CMOCK_RECORD("get_known_addresses");
KnownAddressesResult result;

View File

@ -83,6 +83,7 @@ typedef struct {
typedef struct { LogosBlockchainNode* value; OperationStatus error; } NodeResult;
typedef struct { uint64_t value; OperationStatus error; } BalanceResult;
typedef struct { Hash value; OperationStatus error; } TransferHashResult;
typedef struct { TxHash value; OperationStatus error; } FfiLeaderClaimResult;
typedef struct { KnownAddresses value; OperationStatus error; } KnownAddressesResult;
typedef struct { Hash value; OperationStatus error; } BlendHashResult;
typedef struct { char* value; OperationStatus error; } StringResult;
@ -136,6 +137,7 @@ StringResult get_peer_id(const char* config_path);
// Wallet
BalanceResult get_balance(LogosBlockchainNode* node, const uint8_t* address, const void* reserved);
TransferHashResult transfer_funds(LogosBlockchainNode* node, const TransferFundsArguments* args);
FfiLeaderClaimResult leader_claim(LogosBlockchainNode* node);
KnownAddressesResult get_known_addresses(LogosBlockchainNode* node);
OperationStatus free_known_addresses(KnownAddresses addrs);

View File

@ -147,6 +147,14 @@ LOGOS_TEST(wallet_transfer_funds_without_node_returns_error) {
LOGOS_ASSERT_TRUE(contains(result, "not running"));
}
LOGOS_TEST(leader_claim_without_node_returns_error) {
auto t = LogosTestContext("blockchain_module");
LogosBlockchainModule module;
std::string result = module.leader_claim();
LOGOS_ASSERT_TRUE(starts_with(result, "Error:"));
LOGOS_ASSERT_TRUE(contains(result, "not running"));
}
LOGOS_TEST(wallet_get_known_addresses_without_node_returns_empty) {
auto t = LogosTestContext("blockchain_module");
LogosBlockchainModule module;
@ -496,6 +504,36 @@ LOGOS_TEST(wallet_transfer_funds_returns_error_on_ffi_failure) {
delete module;
}
LOGOS_TEST(leader_claim_returns_tx_hash) {
auto t = LogosTestContext("blockchain_module");
TempDir tmpDir;
auto* module = createStartedModule(t, tmpDir);
LOGOS_ASSERT_TRUE(module != nullptr);
t.mockCFunction("leader_claim_error").returns(0);
std::string result = module->leader_claim();
LOGOS_ASSERT_FALSE(starts_with(result, "Error:"));
LOGOS_ASSERT_EQ(static_cast<int>(result.length()), 64);
LOGOS_ASSERT_TRUE(starts_with(result, "ef"));
LOGOS_ASSERT(t.cFunctionCalled("leader_claim"));
delete module;
}
LOGOS_TEST(leader_claim_returns_error_on_ffi_failure) {
auto t = LogosTestContext("blockchain_module");
TempDir tmpDir;
auto* module = createStartedModule(t, tmpDir);
LOGOS_ASSERT_TRUE(module != nullptr);
t.mockCFunction("leader_claim_error").returns(1);
std::string result = module->leader_claim();
LOGOS_ASSERT_TRUE(starts_with(result, "Error:"));
LOGOS_ASSERT_TRUE(contains(result, "Failed to claim leader rewards"));
delete module;
}
LOGOS_TEST(wallet_transfer_funds_single_sender_via_vector) {
auto t = LogosTestContext("blockchain_module");
TempDir tmpDir;