Skip to content

Commit

Permalink
pos: Rework legacy key generation for descriptor wallets
Browse files Browse the repository at this point in the history
  • Loading branch information
lateminer committed Sep 14, 2024
1 parent 675fa22 commit fea7838
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 26 deletions.
32 changes: 19 additions & 13 deletions src/node/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ void BlockAssembler::resetBlock()
nFees = 0;
}

std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, bool* pfPoSCancel, int64_t* pFees)
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, bool* pfPoSCancel, int64_t* pFees, CTxDestination destination)
{
const auto time_start{SteadyClock::now()};

Expand Down Expand Up @@ -225,7 +225,7 @@ std::unique_ptr<CBlockTemplate> 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();
Expand Down Expand Up @@ -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<wallet::AddressPurpose>& _purpose) {
if (_is_change) return;
if (_label == label)
dest = _dest;
});

if (std::get_if<CNoDestination>(&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<std::pair<const CWalletTx*, unsigned int> > vCoins;
CCoinControl coincontrol;
Expand Down Expand Up @@ -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<CBlockTemplate> 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)
{
Expand Down
2 changes: 1 addition & 1 deletion src/node/miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet = nullptr, bool* pfPoSCancel = nullptr, int64_t* pFees = 0);
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet = nullptr, bool* pfPoSCancel = nullptr, int64_t* pFees = 0, CTxDestination destination = CNoDestination());

inline static std::optional<int64_t> m_last_block_num_txs{};
inline static std::optional<int64_t> m_last_block_weight{};
Expand Down
13 changes: 2 additions & 11 deletions src/wallet/staking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ bool SelectCoinsForStaking(const CWallet& wallet, CAmount& nTargetValue, std::se

// peercoin: create coin stake transaction
typedef std::vector<unsigned char> 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();
Expand Down Expand Up @@ -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<valtype> vSolutionsTmp;
CScript scriptPubKeyTmp = GetScriptForDestination(dest);
CScript scriptPubKeyTmp = GetScriptForDestination(destination);
Solver(scriptPubKeyTmp, vSolutionsTmp);
std::unique_ptr<SigningProvider> provider = wallet.GetSolvingProvider(scriptPubKeyTmp);
if (!provider) {
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/staking.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::pair<const CWalletTx *, unsigned int> > &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

Expand Down

0 comments on commit fea7838

Please sign in to comment.