From 6ed14d69edda4df2fdef6bf97b6e4681dfc1e30a Mon Sep 17 00:00:00 2001 From: baidang201 Date: Thu, 13 Feb 2020 12:15:37 +0800 Subject: [PATCH] add mit domain certificate support --- .../explorer/extensions/base_helper.hpp | 13 +++++--- src/lib/blockchain/validate_transaction.cpp | 17 +++++++++- src/lib/explorer/extensions/base_helper.cpp | 12 +++++-- .../extensions/commands/registermit.cpp | 32 ++++++++++++++++++- 4 files changed, 65 insertions(+), 9 deletions(-) diff --git a/include/metaverse/explorer/extensions/base_helper.hpp b/include/metaverse/explorer/extensions/base_helper.hpp index 74eb90c5f..d5344e27b 100644 --- a/include/metaverse/explorer/extensions/base_helper.hpp +++ b/include/metaverse/explorer/extensions/base_helper.hpp @@ -302,7 +302,8 @@ class BCX_API base_transfer_common receiver_record::list&& receiver_list, uint64_t fee, std::string&& symbol, std::string&& from, std::string&& change, uint32_t locktime = 0, uint32_t sequence = bc::max_input_sequence, - exclude_range_t exclude_etp_range = {0, 0}) + exclude_range_t exclude_etp_range = {0, 0}, + std::set&& payment_domain_set = std::set()) : blockchain_{blockchain} , symbol_{std::move(symbol)} , from_{std::move(from)} @@ -312,6 +313,7 @@ class BCX_API base_transfer_common , locktime_(locktime) , sequence_(sequence) , exclude_etp_range_(exclude_etp_range) + , payment_domain_set_(std::move(payment_domain_set)) { }; @@ -392,6 +394,7 @@ class BCX_API base_transfer_common uint8_t unspent_did_{0}; uint8_t payment_mit_{0}; uint8_t unspent_mit_{0}; + std::set payment_domain_set_; std::vector receiver_list_; std::vector from_list_; uint32_t locktime_; @@ -410,10 +413,11 @@ class BCX_API base_transfer_helper : public base_transfer_common std::string&& change = std::string(""), uint32_t locktime = 0, uint32_t sequence = bc::max_input_sequence, - exclude_range_t exclude_etp_range = {0, 0}) + exclude_range_t exclude_etp_range = {0, 0}, + std::set&& payment_domain_set = std::set()) : base_transfer_common(blockchain, std::move(receiver_list), fee, std::move(symbol), std::move(from), - std::move(change), locktime, sequence, exclude_etp_range) + std::move(change), locktime, sequence, exclude_etp_range, std::move(payment_domain_set)) , cmd_{cmd} , name_{std::move(name)} , passwd_{std::move(passwd)} @@ -769,11 +773,12 @@ class BCX_API registering_mit : public base_transfer_helper registering_mit(command& cmd, bc::blockchain::block_chain_impl& blockchain, std::string&& name, std::string&& passwd, std::string&& from, std::string&& symbol, std::map&& mit_map, + std::set&& payment_domain_set, receiver_record::list&& receiver_list, uint64_t fee, uint32_t locktime = 0) : base_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd), std::move(from), std::move(receiver_list), - fee, std::move(symbol), "", locktime) + fee, std::move(symbol), "", locktime, bc::max_input_sequence, {0,0}, std::move(payment_domain_set)) , mit_map_(mit_map) {} diff --git a/src/lib/blockchain/validate_transaction.cpp b/src/lib/blockchain/validate_transaction.cpp index 7798f1dae..acdf04299 100644 --- a/src/lib/blockchain/validate_transaction.cpp +++ b/src/lib/blockchain/validate_transaction.cpp @@ -953,6 +953,7 @@ code validate_transaction::check_asset_mit_transaction() const std::string asset_address; uint64_t num_mit_transfer = 0; uint64_t num_mit_register = 0; + std::string cert_owner; for (auto& output : tx.outputs) { if (output.is_asset_mit_register()) { @@ -992,6 +993,20 @@ code validate_transaction::check_asset_mit_transaction() const return error::mit_register_error; } } + else if (output.is_asset_cert()) { + asset_cert&& cert_info = output.get_asset_cert(); + if (cert_info.get_type() == asset_cert_ns::domain) { + if (!check_same(cert_owner, cert_info.get_owner())) { + return error::mit_register_error; + } + } + else { + log::debug(LOG_BLOCKCHAIN) << "MIT: " + << " the cert is not domain. " + << cert_info.get_type() << " != " << asset_cert_ns::domain; + return error::mit_register_error; + } + } else if (!output.is_message()) { log::debug(LOG_BLOCKCHAIN) << "MIT: illegal output, " << asset_symbol << " : " << output.to_string(1); @@ -2026,7 +2041,7 @@ bool validate_transaction::check_asset_certs(const transaction& tx) const has_asset_issue = true; } } - else if (!output.is_etp() && !output.is_message()) { + else if (!output.is_etp() && !output.is_message() && !output.is_asset_mit_register()) { // asset cert transfer tx only related to asset_cert and etp output log::debug(LOG_BLOCKCHAIN) << "cert tx mix other illegal output"; return false; diff --git a/src/lib/explorer/extensions/base_helper.cpp b/src/lib/explorer/extensions/base_helper.cpp index 6db0d3c7b..587f58f26 100644 --- a/src/lib/explorer/extensions/base_helper.cpp +++ b/src/lib/explorer/extensions/base_helper.cpp @@ -1131,9 +1131,15 @@ void base_transfer_common::sync_fetchutxo( // check cert symbol if (cert_type == asset_cert_ns::domain) { - auto&& domain = asset_cert::get_domain(symbol_); - if (domain != asset_symbol) - continue; + if (symbol_.size() > 0) { + auto&& domain = asset_cert::get_domain(symbol_); + if (domain != asset_symbol) + continue; + } else { + if (payment_domain_set_.find(asset_symbol) == payment_domain_set_.end()) { + continue; + } + } } else if (cert_type == asset_cert_ns::witness) { auto&& primary = asset_cert::get_primary_witness_symbol(symbol_); diff --git a/src/lib/explorer/extensions/commands/registermit.cpp b/src/lib/explorer/extensions/commands/registermit.cpp index 90f5a9d0f..2844bc2a3 100644 --- a/src/lib/explorer/extensions/commands/registermit.cpp +++ b/src/lib/explorer/extensions/commands/registermit.cpp @@ -133,9 +133,39 @@ console_result registermit::invoke (Json::Value& jv_output, throw address_dismatch_account_exception{"target did does not match account. " + to_did}; } + std::string cert_symbol; + chain::asset_cert_type cert_type = asset_cert_ns::none; + std::set payment_domain_set; + // receiver std::vector receiver; for (auto& pair : mit_map) { + // domain cert check + auto&& domain = chain::asset_cert::get_domain(pair.first); + if (chain::asset_cert::is_valid_domain(domain)) { + bool exist = blockchain.is_asset_cert_exist(domain, asset_cert_ns::domain); + if (exist) { + // if domain cert exists then check whether it belongs to the account. + auto cert = blockchain.get_account_asset_cert(auth_.name, domain, asset_cert_ns::domain); + if (cert) { + cert_symbol = domain; + cert_type = cert->get_type(); + + payment_domain_set.insert(domain); + receiver.push_back( + { + to_address, cert_symbol, 0, 0, cert_type, + utxo_attach_type::asset_cert, + chain::attachment("", to_did) + }); + } + else { + throw asset_cert_notfound_exception{ + "Domain cert " + pair.first + " exists on the blockchain and is not owned by " + auth_.name}; + } + } + } + receiver.push_back( { to_address, pair.first, 0, 0, 0, @@ -147,7 +177,7 @@ console_result registermit::invoke (Json::Value& jv_output, auto helper = registering_mit( *this, blockchain, std::move(auth_.name), std::move(auth_.auth), - std::move(to_address), "", std::move(mit_map), + std::move(to_address), "", std::move(mit_map), std::move(payment_domain_set), std::move(receiver), argument_.fee); helper.exec();