diff --git a/src/node/miner.cpp b/src/node/miner.cpp index 876607e761..b1acd06fec 100644 --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -138,7 +138,7 @@ void BlockAssembler::resetBlock() nFees = 0; } -std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, bool* pfPoSCancel, int64_t* pFees) +std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, bool* pfPoSCancel, int64_t* pFees, CTxDestination destination) { const auto time_start{SteadyClock::now()}; @@ -225,7 +225,7 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc int64_t nSearchTime = txCoinStake.nTime; // search to current time if (nSearchTime > nLastCoinStakeSearchTime) { - if (wallet::CreateCoinStake(*pwallet, pblock->nBits, 1, txCoinStake, nFees)) { + if (wallet::CreateCoinStake(*pwallet, pblock->nBits, 1, txCoinStake, nFees, destination)) { if (txCoinStake.nTime >= pindexPrev->GetMedianTimePast()+1) { // Make the coinbase tx empty in case of proof of stake coinbaseTx.vout[0].SetEmpty(); @@ -651,20 +651,26 @@ void PoSMiner(CWallet *pwallet) unsigned int nExtraNonce = 0; - OutputType output_type = pwallet->m_default_change_type ? *pwallet->m_default_change_type : pwallet->m_default_address_type; - ReserveDestination reservedest(pwallet, output_type); CTxDestination dest; // Compute timeout for pos as sqrt(numUTXO) unsigned int pos_timio; { LOCK2(pwallet->cs_wallet, cs_main); - auto op_dest = reservedest.GetReservedDestination(true); - - if (!op_dest) - throw std::runtime_error("Error: Keypool ran out, please call keypoolrefill first."); - - dest = *op_dest; + const std::string label = "Staking Legacy Address"; + pwallet->ForEachAddrBookEntry([&](const CTxDestination& _dest, const std::string& _label, bool _is_change, const std::optional& _purpose) { + if (_is_change) return; + if (_label == label) + dest = _dest; + }); + + if (std::get_if(&dest)) { + // create mintkey address + auto op_dest = pwallet->GetNewDestination(OutputType::LEGACY, label); + if (!op_dest) + throw std::runtime_error("Error: Keypool ran out, please call keypoolrefill first."); + dest = *op_dest; + } std::vector > vCoins; CCoinControl coincontrol; @@ -703,15 +709,15 @@ void PoSMiner(CWallet *pwallet) // Create new block // CBlockIndex* pindexPrev = pwallet->chain().getTip(); - bool fPoSCancel = false; - CScript scriptPubKey = GetScriptForDestination(dest); + bool fPoSCancel{false}; + int64_t pFees{0}; CBlock *pblock; std::unique_ptr pblocktemplate; { LOCK2(pwallet->cs_wallet, cs_main); try { - pblocktemplate = BlockAssembler{pwallet->chain().chainman().ActiveChainstate(), &pwallet->chain().mempool()}.CreateNewBlock(scriptPubKey, pwallet, &fPoSCancel); + pblocktemplate = BlockAssembler{pwallet->chain().chainman().ActiveChainstate(), &pwallet->chain().mempool()}.CreateNewBlock(GetScriptForDestination(dest), pwallet, &fPoSCancel, &pFees, dest); } catch (const std::runtime_error &e) { diff --git a/src/node/miner.h b/src/node/miner.h index 53ea28702b..e47637fbe8 100644 --- a/src/node/miner.h +++ b/src/node/miner.h @@ -188,7 +188,7 @@ class BlockAssembler explicit BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool, const Options& options); /** Construct a new block template with coinbase to scriptPubKeyIn */ - std::unique_ptr CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet = nullptr, bool* pfPoSCancel = nullptr, int64_t* pFees = 0); + std::unique_ptr CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet = nullptr, bool* pfPoSCancel = nullptr, int64_t* pFees = 0, CTxDestination destination = CNoDestination()); inline static std::optional m_last_block_num_txs{}; inline static std::optional m_last_block_weight{}; diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 97d58dd6b4..bedbfd9266 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -97,7 +97,6 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model) // Blackcoin: hide SegWit address types before SegWit activation if (!(model->wallet().getDefaultAddressType() == OutputType::LEGACY)) { - add_address_type(OutputType::P2SH_SEGWIT, tr("Base58 (P2SH-SegWit)"), tr("Generates an address compatible with older wallets.")); add_address_type(OutputType::BECH32, tr("Bech32 (SegWit)"), tr("Generates a native segwit address (BIP-173). Some old wallets don't support it.")); if (model->wallet().taprootEnabled()) { add_address_type(OutputType::BECH32M, tr("Bech32m (Taproot)"), tr("Bech32m (BIP-350) is an upgrade to Bech32, wallet support is still limited.")); diff --git a/src/wallet/rpc/addresses.cpp b/src/wallet/rpc/addresses.cpp index e617663f97..daf4c4f3f8 100644 --- a/src/wallet/rpc/addresses.cpp +++ b/src/wallet/rpc/addresses.cpp @@ -54,6 +54,8 @@ RPCHelpMan getnewaddress() throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[1].get_str())); } else if (parsed.value() == OutputType::BECH32M && pwallet->GetLegacyScriptPubKeyMan()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Legacy wallets cannot provide bech32m addresses"); + } else if (parsed.value() == OutputType::P2SH_SEGWIT) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "P2SH_SEGWIT addresses are not welcome"); } output_type = parsed.value(); } diff --git a/src/wallet/staking.cpp b/src/wallet/staking.cpp index affade7e84..d2a6ca08e7 100644 --- a/src/wallet/staking.cpp +++ b/src/wallet/staking.cpp @@ -245,7 +245,7 @@ bool SelectCoinsForStaking(const CWallet& wallet, CAmount& nTargetValue, std::se // peercoin: create coin stake transaction typedef std::vector valtype; -bool CreateCoinStake(CWallet& wallet, unsigned int nBits, int64_t nSearchInterval, CMutableTransaction& txNew, CAmount& nFees) +bool CreateCoinStake(CWallet& wallet, unsigned int nBits, int64_t nSearchInterval, CMutableTransaction& txNew, CAmount& nFees, CTxDestination destination) { bool fAllowWatchOnly = wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS); CBlockIndex* pindexPrev = wallet.chain().getTip(); @@ -355,17 +355,8 @@ bool CreateCoinStake(CWallet& wallet, unsigned int nBits, int64_t nSearchInterva scriptPubKeyOut = scriptPubKeyKernel; else if (whichType == TxoutType::WITNESS_V0_KEYHASH || whichType == TxoutType::WITNESS_V1_TAPROOT) // pay to witness keyhash { - // prepare reserve destination in case we need to use it for handling non legacy inputs - CTxDestination dest; - ReserveDestination reservedest(&wallet, OutputType::LEGACY); - auto op_dest = reservedest.GetReservedDestination(true); - if (!op_dest) { - LogPrintf("Error: Keypool ran out, please call keypoolrefill first.\n"); - break; - } - dest = *op_dest; std::vector vSolutionsTmp; - CScript scriptPubKeyTmp = GetScriptForDestination(dest); + CScript scriptPubKeyTmp = GetScriptForDestination(destination); Solver(scriptPubKeyTmp, vSolutionsTmp); std::unique_ptr provider = wallet.GetSolvingProvider(scriptPubKeyTmp); if (!provider) { diff --git a/src/wallet/staking.h b/src/wallet/staking.h index a0c58003d4..2b4074835e 100644 --- a/src/wallet/staking.h +++ b/src/wallet/staking.h @@ -24,7 +24,7 @@ void AvailableCoinsForStaking(const CWallet& wallet, const CCoinControl* coinControl = nullptr, const CoinFilterParams& params = {}) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet); bool SelectCoinsForStaking(const CWallet& wallet, CAmount& nTargetValue, std::set > &setCoinsRet, CAmount& nValueRet); -bool CreateCoinStake(CWallet& wallet, unsigned int nBits, int64_t nSearchInterval, CMutableTransaction& tx, CAmount& nFees); +bool CreateCoinStake(CWallet& wallet, unsigned int nBits, int64_t nSearchInterval, CMutableTransaction& tx, CAmount& nFees, CTxDestination destination); } // namespace wallet diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4ad41d873d..1de80460d1 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1075,8 +1075,8 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const TxState& state, const } } - // Mark inactive coinbase transactions and their descendants as abandoned - if (wtx.IsCoinBase() && wtx.isInactive()) { + // Mark inactive coinbase and coinstake transactions and their descendants as abandoned + if ((wtx.IsCoinBase() || wtx.IsCoinStake()) && wtx.isInactive()) { std::vector txs{&wtx}; TxStateInactive inactive_state = TxStateInactive{/*abandoned=*/true};