This commit is contained in:
Sergio Chouhy 2026-07-31 19:10:07 -03:00
parent 9ccf21b0ac
commit f9e517766a
4 changed files with 92 additions and 17 deletions

8
flake.lock generated
View File

@ -2716,17 +2716,17 @@
"rust-rapidsnark": "rust-rapidsnark"
},
"locked": {
"lastModified": 1785414238,
"narHash": "sha256-SNo5ZvmzB39HMgY+f0a93XoNA92e/T5Ki9Gho62COWY=",
"lastModified": 1785659324,
"narHash": "sha256-xtC9Qksgp3f3ZEDdhLuM0DegelFl4EW20jqSmhqHeHQ=",
"owner": "logos-blockchain",
"repo": "logos-execution-zone",
"rev": "f58cde1a2251c20cf418a561ad974a8c64ab2393",
"rev": "15144ddb8437f48cdce32908e122dbb7eea68399",
"type": "github"
},
"original": {
"owner": "logos-blockchain",
"ref": "v0.2.1",
"repo": "logos-execution-zone",
"rev": "f58cde1a2251c20cf418a561ad974a8c64ab2393",
"type": "github"
}
},

View File

@ -4,7 +4,7 @@
inputs = {
logos-module-builder.url = "github:logos-co/logos-module-builder";
nix-bundle-lgx.url = "github:logos-co/nix-bundle-lgx";
logos-execution-zone.url = "github:logos-blockchain/logos-execution-zone?rev=f58cde1a2251c20cf418a561ad974a8c64ab2393";
logos-execution-zone.url = "github:logos-blockchain/logos-execution-zone?ref=v0.2.1";
};
outputs = inputs@{ logos-module-builder, ... }:

View File

@ -212,28 +212,31 @@ bool jsonToFfiPrivateAccountKeys(const std::string& json, FfiPrivateAccountKeys*
if (doc.is_discarded() || !doc.is_object())
return false;
if (doc.contains(JsonKeys::NullifierPublicKey) && doc[JsonKeys::NullifierPublicKey].is_string()) {
if (!hexToBytes32(doc[JsonKeys::NullifierPublicKey].get<std::string>(), &output_keys->nullifier_public_key))
return false;
}
// Nullifier public key is mandatory: a missing/wrong-typed value must not fall back to zero.
if (!doc.contains(JsonKeys::NullifierPublicKey) || !doc[JsonKeys::NullifierPublicKey].is_string())
return false;
if (!hexToBytes32(doc[JsonKeys::NullifierPublicKey].get<std::string>(), &output_keys->nullifier_public_key))
return false;
output_keys->viewing_public_key = nullptr;
output_keys->viewing_public_key_len = 0;
if (doc.contains(JsonKeys::ViewingPublicKey)) {
if (!doc[JsonKeys::ViewingPublicKey].is_string())
return false;
if (doc.contains(JsonKeys::ViewingPublicKey) && doc[JsonKeys::ViewingPublicKey].is_string()) {
std::vector<uint8_t> buffer;
if (!hexToBytes(doc[JsonKeys::ViewingPublicKey].get<std::string>(), buffer))
return false;
if (buffer.empty()) {
output_keys->viewing_public_key = nullptr;
output_keys->viewing_public_key_len = 0;
} else {
if (!buffer.empty()) {
auto* data = static_cast<uint8_t*>(malloc(buffer.size()));
if (!data)
return false;
memcpy(data, buffer.data(), buffer.size());
output_keys->viewing_public_key = data;
output_keys->viewing_public_key_len = buffer.size();
}
} else {
output_keys->viewing_public_key = nullptr;
output_keys->viewing_public_key_len = 0;
}
return true;

View File

@ -288,6 +288,68 @@ LOGOS_TEST(transfer_shielded_invalid_keys_json_error) {
LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_transfer_shielded"));
}
// A missing nullifier_public_key must not succeed with a zero key.
LOGOS_TEST(transfer_shielded_missing_nullifier_key_error) {
auto t = LogosTestContext("logos_execution_zone");
LEZCoreModule module;
const nlohmann::json obj = parseObject(module.transfer_shielded(VALID_ID, "{}", VALID_U128));
LOGOS_ASSERT_FALSE(obj["success"].get<bool>());
LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_transfer_shielded"));
}
LOGOS_TEST(transfer_shielded_misspelled_nullifier_key_error) {
auto t = LogosTestContext("logos_execution_zone");
LEZCoreModule module;
const std::string keysJson = std::string("{\"nullifierPublicKey\":\"") + std::string(64, 'a') + "\"}";
const nlohmann::json obj = parseObject(module.transfer_shielded(VALID_ID, keysJson, VALID_U128));
LOGOS_ASSERT_FALSE(obj["success"].get<bool>());
LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_transfer_shielded"));
}
LOGOS_TEST(transfer_shielded_abbreviated_nullifier_key_error) {
auto t = LogosTestContext("logos_execution_zone");
LEZCoreModule module;
const std::string keysJson = std::string("{\"nullifier_pubkey\":\"") + std::string(64, 'a') + "\"}";
const nlohmann::json obj = parseObject(module.transfer_shielded(VALID_ID, keysJson, VALID_U128));
LOGOS_ASSERT_FALSE(obj["success"].get<bool>());
LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_transfer_shielded"));
}
LOGOS_TEST(transfer_shielded_nullifier_key_omitted_viewing_key_only_error) {
auto t = LogosTestContext("logos_execution_zone");
LEZCoreModule module;
const std::string keysJson = std::string("{\"viewing_public_key\":\"") + std::string(64, 'a') + "\"}";
const nlohmann::json obj = parseObject(module.transfer_shielded(VALID_ID, keysJson, VALID_U128));
LOGOS_ASSERT_FALSE(obj["success"].get<bool>());
LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_transfer_shielded"));
}
LOGOS_TEST(transfer_shielded_nullifier_key_wrong_type_error) {
auto t = LogosTestContext("logos_execution_zone");
LEZCoreModule module;
const std::string keysJson = "{\"nullifier_public_key\": 12345}";
const nlohmann::json obj = parseObject(module.transfer_shielded(VALID_ID, keysJson, VALID_U128));
LOGOS_ASSERT_FALSE(obj["success"].get<bool>());
LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_transfer_shielded"));
}
// A non-string viewing_public_key must be rejected, not treated as absent.
LOGOS_TEST(transfer_shielded_viewing_key_wrong_type_error) {
auto t = LogosTestContext("logos_execution_zone");
LEZCoreModule module;
const std::string keysJson = std::string("{\"nullifier_public_key\":\"") + std::string(64, 'a')
+ "\",\"viewing_public_key\": 12345}";
const nlohmann::json obj = parseObject(module.transfer_shielded(VALID_ID, keysJson, VALID_U128));
LOGOS_ASSERT_FALSE(obj["success"].get<bool>());
LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_transfer_shielded"));
}
LOGOS_TEST(transfer_shielded_success_json) {
auto t = LogosTestContext("logos_execution_zone");
LEZCoreModule module;
@ -335,6 +397,16 @@ LOGOS_TEST(transfer_shielded_without_identifier_uses_random_nonzero_identifier)
LOGOS_ASSERT_FALSE(memcmp(first, second, sizeof(first)) == 0);
}
// transfer_private shares the same parser, so it must reject a missing key too.
LOGOS_TEST(transfer_private_missing_nullifier_key_error) {
auto t = LogosTestContext("logos_execution_zone");
LEZCoreModule module;
const nlohmann::json obj = parseObject(module.transfer_private(VALID_ID, "{}", VALID_U128));
LOGOS_ASSERT_FALSE(obj["success"].get<bool>());
LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_transfer_private"));
}
// transfer_private mirrors transfer_shielded's identifier handling exactly (see above).
LOGOS_TEST(transfer_private_with_identifier_forwards_it_unchanged) {
auto t = LogosTestContext("logos_execution_zone");