aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cryptonote_basic/asset_types.cpp43
-rw-r--r--src/cryptonote_basic/asset_types.h12
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;