diff options
| author | Monzero Build System <builds@monzero.org> | 2026-08-15 22:10:25 +0100 |
|---|---|---|
| committer | Monzero Build System <builds@monzero.org> | 2026-08-15 22:10:25 +0100 |
| commit | 98b57835312d2e729eb3527be24e86002a41e202 (patch) | |
| tree | bd41bcac9274b1e3aed4fb8520efec0c2efe717e /tests/unit_tests | |
| parent | f4b7631ee2c13c936ca44b658423612ecba16f3c (diff) | |
| download | monzero-core-98b57835312d2e729eb3527be24e86002a41e202.tar.gz monzero-core-98b57835312d2e729eb3527be24e86002a41e202.tar.xz monzero-core-98b57835312d2e729eb3527be24e86002a41e202.zip | |
Define detached asset transaction extensions
Diffstat (limited to 'tests/unit_tests')
| -rw-r--r-- | tests/unit_tests/asset_types.cpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/tests/unit_tests/asset_types.cpp b/tests/unit_tests/asset_types.cpp index 270f8100e..5f196301d 100644 --- a/tests/unit_tests/asset_types.cpp +++ b/tests/unit_tests/asset_types.cpp @@ -184,6 +184,74 @@ TEST(asset_types, issuance_payload_rejects_tampering_and_signature_shape_errors) EXPECT_FALSE(cryptonote::assets::encode_issuance_payload(payload, encoded, &error)); } +TEST(asset_types, detached_transaction_extension_is_canonical_and_network_bound) +{ + crypto::public_key issuer_public{}; + crypto::secret_key issuer_secret{}; + crypto::generate_keys(issuer_public, issuer_secret); + + cryptonote::assets::transaction_extension original; + original.network = cryptonote::TESTNET; + original.carrier_prefix_hash.data[0] = 0x7a; + original.issuance.descriptor = make_descriptor(cryptonote::TESTNET); + original.issuance.descriptor.issuer_key = issuer_public; + original.issuance.issuer_signature = authorize( + original.issuance.descriptor, issuer_public, issuer_secret); + + std::vector<uint8_t> encoded; + ASSERT_TRUE(cryptonote::assets::encode_transaction_extension(original, encoded)); + cryptonote::assets::transaction_extension decoded; + ASSERT_TRUE(cryptonote::assets::decode_transaction_extension(encoded, decoded)); + EXPECT_EQ(original.network, decoded.network); + EXPECT_EQ(original.operation, decoded.operation); + EXPECT_EQ(original.carrier_prefix_hash, decoded.carrier_prefix_hash); + + crypto::hash first{}; + crypto::hash second{}; + ASSERT_TRUE(cryptonote::assets::derive_transaction_extension_id(original, first)); + ASSERT_TRUE(cryptonote::assets::derive_transaction_extension_id(decoded, second)); + EXPECT_EQ(first, second); + + decoded.carrier_prefix_hash.data[0] ^= 1; + ASSERT_TRUE(cryptonote::assets::derive_transaction_extension_id(decoded, second)); + EXPECT_NE(first, second); +} + +TEST(asset_types, detached_transaction_extension_rejects_malformed_or_unbound_data) +{ + crypto::public_key issuer_public{}; + crypto::secret_key issuer_secret{}; + crypto::generate_keys(issuer_public, issuer_secret); + + cryptonote::assets::transaction_extension extension; + extension.network = cryptonote::STAGENET; + extension.carrier_prefix_hash.data[0] = 1; + extension.issuance.descriptor = make_descriptor(cryptonote::STAGENET); + extension.issuance.descriptor.issuer_key = issuer_public; + extension.issuance.issuer_signature = authorize( + extension.issuance.descriptor, issuer_public, issuer_secret); + + std::vector<uint8_t> encoded; + ASSERT_TRUE(cryptonote::assets::encode_transaction_extension(extension, encoded)); + cryptonote::assets::transaction_extension decoded; + std::string error; + for (size_t size = 0; size < encoded.size(); ++size) + { + const std::vector<uint8_t> truncated(encoded.begin(), encoded.begin() + size); + EXPECT_FALSE(cryptonote::assets::decode_transaction_extension(truncated, decoded, &error)) + << "accepted truncated extension size " << size; + } + + extension.carrier_prefix_hash = crypto::null_hash; + EXPECT_FALSE(cryptonote::assets::encode_transaction_extension(extension, encoded, &error)); + extension.carrier_prefix_hash.data[0] = 1; + extension.network = cryptonote::TESTNET; + EXPECT_FALSE(cryptonote::assets::encode_transaction_extension(extension, encoded, &error)); + extension.network = cryptonote::STAGENET; + extension.operation = static_cast<cryptonote::assets::transaction_operation>(2); + EXPECT_FALSE(cryptonote::assets::encode_transaction_extension(extension, encoded, &error)); +} + TEST(asset_types, network_domain_separation) { auto mainnet = make_descriptor(cryptonote::MAINNET); |
