diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cryptonote_basic/asset_types.cpp | 43 | ||||
| -rw-r--r-- | src/cryptonote_basic/asset_types.h | 12 |
2 files changed, 55 insertions, 0 deletions
diff --git a/src/cryptonote_basic/asset_types.cpp b/src/cryptonote_basic/asset_types.cpp index aa17b359f..b193ec141 100644 --- a/src/cryptonote_basic/asset_types.cpp +++ b/src/cryptonote_basic/asset_types.cpp @@ -456,6 +456,24 @@ namespace assets return true; } + bool validate_transaction_extension_carrier( + const transaction_extension& extension, + network_type expected_network, + const crypto::hash& expected_prefix_hash, + std::string* error) + { + if (expected_network != MAINNET && expected_network != TESTNET && expected_network != STAGENET) + return fail(error, "asset transaction carrier validation requires an explicit network"); + if (expected_prefix_hash == crypto::null_hash) + return fail(error, "expected native transaction prefix commitment is zero"); + if (extension.network != expected_network) + return fail(error, "asset transaction extension is for another network"); + if (extension.carrier_prefix_hash != expected_prefix_hash) + return fail(error, "asset transaction extension carrier commitment mismatch"); + std::vector<uint8_t> canonical; + return encode_transaction_extension(extension, canonical, error); + } + bool asset_registry::apply_issuance( const issuance_descriptor& descriptor, const crypto::signature& issuer_signature, @@ -534,6 +552,31 @@ namespace assets return true; } + bool asset_registry::apply_block_extensions( + const std::vector<transaction_extension>& extensions, + const std::vector<crypto::hash>& carrier_prefix_hashes, + network_type expected_network, + uint64_t height, + std::vector<crypto::hash>& asset_ids, + std::string* error) + { + if (extensions.size() != carrier_prefix_hashes.size()) + return fail(error, "asset extension and carrier commitment counts differ"); + std::vector<issuance_payload> issuances; + issuances.reserve(extensions.size()); + for (size_t index = 0; index < extensions.size(); ++index) + { + const transaction_extension& extension = extensions[index]; + if (!validate_transaction_extension_carrier( + extension, expected_network, carrier_prefix_hashes[index], error)) + return false; + if (extension.operation != transaction_operation::issuance) + return fail(error, "unsupported asset block operation"); + issuances.push_back(extension.issuance); + } + return apply_block_issuances(issuances, height, asset_ids, error); + } + void asset_registry::detach(uint64_t height) { for (auto it = records_.begin(); it != records_.end();) diff --git a/src/cryptonote_basic/asset_types.h b/src/cryptonote_basic/asset_types.h index 5b2bf6006..81cbcd65d 100644 --- a/src/cryptonote_basic/asset_types.h +++ b/src/cryptonote_basic/asset_types.h @@ -96,6 +96,11 @@ namespace assets bool encode_transaction_extension(const transaction_extension& extension, std::vector<uint8_t>& encoded, std::string* error = nullptr); bool decode_transaction_extension(const std::vector<uint8_t>& encoded, transaction_extension& extension, std::string* error = nullptr); bool derive_transaction_extension_id(const transaction_extension& extension, crypto::hash& extension_id, std::string* error = nullptr); + bool validate_transaction_extension_carrier( + const transaction_extension& extension, + network_type expected_network, + const crypto::hash& expected_prefix_hash, + std::string* error = nullptr); struct asset_record { @@ -124,6 +129,13 @@ namespace assets uint64_t height, std::vector<crypto::hash>& asset_ids, std::string* error = nullptr); + bool apply_block_extensions( + const std::vector<transaction_extension>& extensions, + const std::vector<crypto::hash>& carrier_prefix_hashes, + network_type expected_network, + uint64_t height, + std::vector<crypto::hash>& asset_ids, + std::string* error = nullptr); void detach(uint64_t height); bool contains(const crypto::hash& asset_id) const; const asset_record* find(const crypto::hash& asset_id) const; |
