diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 17b6749a..e8272e50 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -650,19 +650,28 @@ namespace currency bool r = derive_public_key_from_target_address(self.account_address, tx_sec_key, output_index, out_eph_public_key, derivation); CHECK_AND_ASSERT_MES(r, false, "failed to derive_public_key_from_target_address"); htlc.pkey_refund = out_eph_public_key; - //we use deterministic origin, to make possible access origin on different wallets copies - std::string hltc_origin = generate_origin_for_htlc(htlc.pkey_redeem, htlc.pkey_refund, self); - //calculate hash - if (htlc.flags&CURRENCY_TXOUT_HTLC_FLAGS_HASH_TYPE_MASK) + if (de.htlc_hash == null_hash) { - htlc.htlc_hash = crypto::sha256_hash(hltc_origin.data(), hltc_origin.size()); + //we use deterministic origin, to make possible access origin on different wallets copies + std::string hltc_origin = generate_origin_for_htlc(htlc.pkey_redeem, htlc.pkey_refund, self); + + //calculate hash + if (htlc.flags&CURRENCY_TXOUT_HTLC_FLAGS_HASH_TYPE_MASK) + { + htlc.htlc_hash = crypto::sha256_hash(hltc_origin.data(), hltc_origin.size()); + } + else + { + crypto::hash160 h160 = crypto::RIPEMD160_hash(hltc_origin.data(), hltc_origin.size()); + std::memcpy(&htlc.htlc_hash, &h160, sizeof(h160)); + } } else { - crypto::hash160 h160 = crypto::RIPEMD160_hash(hltc_origin.data(), hltc_origin.size()); - std::memcpy(&htlc.htlc_hash, &h160, sizeof(h160)); + htlc.htlc_hash = de.htlc_hash; } + } else if (target_keys.size() == 1) { diff --git a/src/currency_core/currency_format_utils_transactions.h b/src/currency_core/currency_format_utils_transactions.h index bc94083b..9028d0cc 100644 --- a/src/currency_core/currency_format_utils_transactions.h +++ b/src/currency_core/currency_format_utils_transactions.h @@ -53,11 +53,12 @@ namespace currency uint64_t amount_to_provide; //amount money that provided by initial creator of tx, used with partially created transactions uint64_t unlock_time; bool htlc; //if this flag is set, then creating htlc out, unlock_time -> number of blocks that htlc proposal is active + crypto::hash htlc_hash; - tx_destination_entry() : amount(0), minimum_sigs(0), amount_to_provide(0), unlock_time(0), htlc(false){} - tx_destination_entry(uint64_t a, const account_public_address& ad) : amount(a), addr(1, ad), minimum_sigs(0), amount_to_provide(0), unlock_time(0), htlc(false){} - tx_destination_entry(uint64_t a, const account_public_address& ad, uint64_t ut) : amount(a), addr(1, ad), minimum_sigs(0), amount_to_provide(0), unlock_time(ut), htlc(false){} - tx_destination_entry(uint64_t a, const std::list& addr) : amount(a), addr(addr), minimum_sigs(addr.size()), amount_to_provide(0), unlock_time(0), htlc(false){} + tx_destination_entry() : amount(0), minimum_sigs(0), amount_to_provide(0), unlock_time(0), htlc(false), htlc_hash(null_hash){} + tx_destination_entry(uint64_t a, const account_public_address& ad) : amount(a), addr(1, ad), minimum_sigs(0), amount_to_provide(0), unlock_time(0), htlc(false), htlc_hash(null_hash) {} + tx_destination_entry(uint64_t a, const account_public_address& ad, uint64_t ut) : amount(a), addr(1, ad), minimum_sigs(0), amount_to_provide(0), unlock_time(ut), htlc(false), htlc_hash(null_hash) {} + tx_destination_entry(uint64_t a, const std::list& addr) : amount(a), addr(addr), minimum_sigs(addr.size()), amount_to_provide(0), unlock_time(0), htlc(false), htlc_hash(null_hash) {} BEGIN_SERIALIZE_OBJECT() FIELD(amount) @@ -66,6 +67,7 @@ namespace currency FIELD(amount_to_provide) FIELD(unlock_time) FIELD(htlc) + FIELD(htlc_hash) END_SERIALIZE() }; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 85dba890..01eb6486 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4012,7 +4012,7 @@ void wallet2::send_escrow_proposal(const bc_services::contract_private_details& print_tx_sent_message(tx, "(from multisig)", fee); } //---------------------------------------------------------------------------------------------------- -void wallet2::create_htlc_proposal(uint64_t amount, const currency::account_public_address& addr, uint64_t lock_blocks_count, currency::transaction &tx) +void wallet2::create_htlc_proposal(uint64_t amount, const currency::account_public_address& addr, uint64_t lock_blocks_count, currency::transaction &tx, const crypto::hash& htlc_hash) { std::vector extra; std::vector attachments; @@ -4022,6 +4022,7 @@ void wallet2::create_htlc_proposal(uint64_t amount, const currency::account_publ dst.back().addr.push_back(addr); dst.back().amount = amount; dst.back().htlc = true; + dst.back().htlc_hash = htlc_hash; dst.back().unlock_time = 740; //about 12 hours transaction result_tx = AUTO_VAL_INIT(result_tx); @@ -4051,7 +4052,13 @@ void wallet2::get_list_of_active_htlc(bool only_redeem_txs, std::list& htlcs); void redeem_htlc(const crypto::hash& htlc_tx_id, const std::string& origin); diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index fe79adf4..4e8fa6cd 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -64,7 +64,7 @@ namespace tools std::string to_string() const { std::ostringstream ss; - ss << m_loc << ':' << typeid(*this).name() << ": " << Base::what(); + ss << m_loc << ':' << typeid(*this).name() << "[" << m_error_code << "]: " << Base::what(); return ss.str(); } @@ -74,6 +74,13 @@ namespace tools return m_what.c_str(); } + wallet_error_base(std::string&& loc, const std::string& message, const std::string& error_code) + : Base(message) + , m_loc(loc) + , m_error_code(error_code) + { + } + protected: wallet_error_base(std::string&& loc, const std::string& message) : Base(message) @@ -81,8 +88,10 @@ namespace tools { } + private: std::string m_loc; + std::string m_error_code; mutable std::string m_what; }; //---------------------------------------------------------------------------------------------------- @@ -662,6 +671,20 @@ if (!(cond)) tools::error::throw_wallet_ex(std::string(__FILE__ ":" STRINGIZE(__LINE__)), ## __VA_ARGS__); \ } + + +//#define THROW_IF_FALSE_WALLET_EX_MES(cond, err_type, mess, ...) +#define WLT_THROW_IF_FALSE_WITH_CODE(cond, mess, error_code) \ +if (!(cond)) \ +{ \ + exception_handler(); \ + std::stringstream ss; \ + ss << std::endl << mess; \ + LOG_ERROR(#cond << ". THROW EXCEPTION: " << error_code << ss.str()); \ + tools::error::throw_wallet_ex(std::string(__FILE__ ":" STRINGIZE(__LINE__)), ss.str(), error_code); \ +} + + #define THROW_IF_FALSE_WALLET_EX_MES(cond, err_type, mess, ...) \ if (!(cond)) \ { \