diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index c1c69f25..17d411d2 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -216,7 +216,7 @@ namespace currency decompose_amount_into_digits(block_reward, DEFAULT_DUST_THRESHOLD, [&out_amounts](uint64_t a_chunk) { out_amounts.push_back(a_chunk); }, [&out_amounts](uint64_t a_dust) { out_amounts.push_back(a_dust); }); - CHECK_AND_ASSERT_MES(1 <= max_outs, false, "max_out must be non-zero"); + CHECK_AND_ASSERT_MES(2 <= max_outs, false, "max_out must be greather than 1"); while (max_outs < out_amounts.size()) { out_amounts[out_amounts.size() - 2] += out_amounts.back(); @@ -271,26 +271,16 @@ namespace currency { if (tx.version > TRANSACTION_VERSION_PRE_HF4 /* && stake is zarcanum */) { - // TODO: add Zarcanum part - //txin_zc_input stake_input = AUTO_VAL_INIT(stake_input); - //stake_input.key_offsets.push_back(pe.g_index); - //stake_input.k_image = pe.keyimage; + // just placeholders, they will be filled in wallet2::prepare_and_sign_pos_block() tx.vin.emplace_back(std::move(txin_zc_input())); - //reserve place for ring signature tx.signatures.emplace_back(std::move(zarcanum_sig())); } else { // old fashioned non-hidden amount direct spend PoS scheme - txin_to_key stake_input; - stake_input.amount = pe.amount; - stake_input.key_offsets.push_back(pe.g_index); - stake_input.k_image = pe.keyimage; - tx.vin.push_back(stake_input); - //reserve place for ring signature - NLSAG_sig nlsag; - nlsag.s.resize(stake_input.key_offsets.size()); - tx.signatures.push_back(nlsag); // consider using emplace_back and avoid copying + // just placeholders, they will be filled in wallet2::prepare_and_sign_pos_block() + tx.vin.emplace_back(std::move(txin_to_key())); + tx.signatures.emplace_back(std::move(NLSAG_sig())); } } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index ba0f215a..d90e1554 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3666,13 +3666,20 @@ bool wallet2::prepare_and_sign_pos_block(const mining_context& cxt, currency::bl // old PoS with non-hidden amounts WLT_CHECK_AND_ASSERT_MES(b.miner_tx.vin[0].type() == typeid(currency::txin_gen), false, "Wrong input 0 type in transaction: " << b.miner_tx.vin[0].type().name()); WLT_CHECK_AND_ASSERT_MES(b.miner_tx.vin[1].type() == typeid(currency::txin_to_key), false, "Wrong input 1 type in transaction: " << b.miner_tx.vin[1].type().name()); - auto& txin = boost::get(b.miner_tx.vin[1]); - txin.k_image = pe.keyimage; + WLT_CHECK_AND_ASSERT_MES(b.miner_tx.signatures.size() == 1 && b.miner_tx.signatures[0].type() == typeid(NLSAG_sig), false, "wrong sig prepared in a PoS block"); + WLT_CHECK_AND_ASSERT_MES(stake_out_v.type() == typeid(tx_out_bare), false, "unexpected stake output type: " << stake_out_v.type().name() << ", expected: tx_out_bare"); + const tx_out_bare& stake_out = boost::get(stake_out_v); + WLT_CHECK_AND_ASSERT_MES(stake_out.target.type() == typeid(txout_to_key), false, "unexpected stake output target type: " << stake_out.target.type().name() << ", expected: txout_to_key"); + - WLT_CHECK_AND_ASSERT_MES(b.miner_tx.signatures.size() == 1 && - b.miner_tx.signatures[0].type() == typeid(NLSAG_sig) && - boost::get(b.miner_tx.signatures[0]).s.size() == txin.key_offsets.size(), - false, "Wrong signatures amount in coinbase transacton"); + NLSAG_sig& sig = boost::get(b.miner_tx.signatures[0]); + txin_to_key& stake_input = boost::get(b.miner_tx.vin[1]); + const txout_to_key& stake_out_target = boost::get(stake_out.target); + + stake_input.k_image = pe.keyimage; + stake_input.amount = pe.amount; + stake_input.key_offsets.push_back(pe.g_index); + sig.s.resize(1); //derive secret key crypto::key_derivation pos_coin_derivation = AUTO_VAL_INIT(pos_coin_derivation); @@ -3693,21 +3700,19 @@ bool wallet2::prepare_and_sign_pos_block(const mining_context& cxt, currency::bl // get stake output pub key (stealth address) for ring signature generation std::vector keys_ptrs; - TRY_ENTRY() - keys_ptrs.push_back(&boost::get(boost::get(stake_out_v).target).key); - CATCH_ENTRY_CUSTOM("wallet2::prepare_and_sign_pos_block", { LOG_PRINT_RED_L0("unable to get output's pub key because of the exception"); }, false); + keys_ptrs.push_back(&stake_out_target.key); crypto::generate_ring_signature(block_hash, - txin.k_image, + stake_input.k_image, keys_ptrs, derived_secret_ephemeral_key, 0, - &boost::get(b.miner_tx.signatures[0]).s[0]); + &sig.s[0]); - WLT_LOG_L4("GENERATED RING SIGNATURE: block_id " << block_hash - << "txin.k_image" << txin.k_image + WLT_LOG_L4("GENERATED RING SIGNATURE for PoS block coinbase: block_id " << block_hash + << "txin.k_image" << stake_input.k_image << "key_ptr:" << *keys_ptrs[0] - << "signature:" << boost::get(b.miner_tx.signatures[0]).s); + << "signature:" << sig.s); return true; }