Skip to content

Commit

Permalink
wallet: split off ListProTxCoins to allow supplying your own set
Browse files Browse the repository at this point in the history
  • Loading branch information
kwvg committed Jan 29, 2025
1 parent 0972dfe commit 8ba0f27
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 50 deletions.
2 changes: 1 addition & 1 deletion src/interfaces/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class Chain
virtual bool hasChainLock(int height, const uint256& hash) = 0;

//! Return list of MN Collateral from outputs
virtual std::vector<COutPoint> listMNCollaterials(const std::vector<std::pair<const CTransactionRef&, unsigned int>>& outputs) = 0;
virtual std::vector<COutPoint> listMNCollaterials(const std::vector<std::pair<const CTransactionRef&, uint32_t>>& outputs) = 0;
//! Return whether node has the block and optionally return block metadata
//! or contents.
virtual bool findBlock(const uint256& hash, const FoundBlock& block={}) = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class Wallet
virtual void listLockedCoins(std::vector<COutPoint>& outputs) = 0;

//! List protx coins.
virtual void listProTxCoins(std::vector<COutPoint>& vOutpts) = 0;
virtual std::vector<COutPoint> listProTxCoins() = 0;

//! Create transaction.
virtual CTransactionRef createTransaction(const std::vector<CRecipient>& recipients,
Expand Down
2 changes: 1 addition & 1 deletion src/node/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ class ChainImpl : public Chain
if (m_node.llmq_ctx == nullptr || m_node.llmq_ctx->clhandler == nullptr) return false;
return m_node.llmq_ctx->clhandler->HasChainLock(height, hash);
}
std::vector<COutPoint> listMNCollaterials(const std::vector<std::pair<const CTransactionRef&, unsigned int>>& outputs) override
std::vector<COutPoint> listMNCollaterials(const std::vector<std::pair<const CTransactionRef&, uint32_t>>& outputs) override
{
const CBlockIndex *tip = WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip());
CDeterministicMNList mnList{};
Expand Down
4 changes: 1 addition & 3 deletions src/qt/masternodelist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,7 @@ void MasternodeList::updateDIP3List()

std::set<COutPoint> setOutpts;
if (walletModel && ui->checkBoxMyMasternodesOnly->isChecked()) {
std::vector<COutPoint> vOutpts;
walletModel->wallet().listProTxCoins(vOutpts);
for (const auto& outpt : vOutpts) {
for (const auto& outpt : walletModel->wallet().listProTxCoins()) {
setOutpts.emplace(outpt);
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/rpc/evo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1390,10 +1390,8 @@ static RPCHelpMan protx_list()
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid height specified");
}

std::vector<COutPoint> vOutpts;
wallet->ListProTxCoins(vOutpts);
std::set<COutPoint> setOutpts;
for (const auto& outpt : vOutpts) {
for (const auto& outpt : wallet->ListProTxCoins()) {
setOutpts.emplace(outpt);
}

Expand Down
4 changes: 2 additions & 2 deletions src/wallet/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,10 @@ class WalletImpl : public Wallet
LOCK(m_wallet->cs_wallet);
return m_wallet->ListLockedCoins(outputs);
}
void listProTxCoins(std::vector<COutPoint>& outputs) override
std::vector<COutPoint> listProTxCoins() override
{
LOCK(m_wallet->cs_wallet);
return m_wallet->ListProTxCoins(outputs);
return m_wallet->ListProTxCoins();
}
CTransactionRef createTransaction(const std::vector<CRecipient>& recipients,
const CCoinControl& coin_control,
Expand Down
68 changes: 30 additions & 38 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -922,18 +922,16 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const CWalletTx::Confirmatio
wtx.nTimeSmart = ComputeTimeSmart(wtx);
AddToSpends(hash, &batch);

std::vector<std::pair<const CTransactionRef&, unsigned int>> outputs;
for(unsigned int i = 0; i < wtx.tx->vout.size(); ++i) {
std::set<COutPoint> candidates;
for (unsigned int i = 0; i < wtx.tx->vout.size(); ++i) {
if (IsMine(wtx.tx->vout[i]) && !IsSpent(hash, i)) {
setWalletUTXO.insert(COutPoint(hash, i));
outputs.emplace_back(wtx.tx, i);
candidates.emplace(hash, i);
}
}
// TODO: refactor duplicated code between CWallet::AddToWallet and CWallet::AutoLockMasternodeCollaterals
if (m_chain) {
for (const auto& outPoint : m_chain->listMNCollaterials(outputs)) {
LockCoin(outPoint, &batch);
}
for (const auto& utxo : ListProTxCoins(candidates)) {
LockCoin(utxo, &batch);
}
}

Expand All @@ -951,21 +949,19 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const CWalletTx::Confirmatio
assert(wtx.m_confirm.block_height == confirm.block_height);
}

std::vector<std::pair<const CTransactionRef&, unsigned int>> outputs;
for(unsigned int i = 0; i < wtx.tx->vout.size(); ++i) {
std::set<COutPoint> candidates;
for (unsigned int i = 0; i < wtx.tx->vout.size(); ++i) {
if (IsMine(wtx.tx->vout[i]) && !IsSpent(hash, i)) {
bool new_utxo = setWalletUTXO.insert(COutPoint(hash, i)).second;
if (new_utxo) {
outputs.emplace_back(wtx.tx, i);
candidates.emplace(hash, i);
fUpdated = true;
}
}
}
// TODO: refactor duplicated code with case fInstertedNew
if (m_chain) {
for (const auto& outPoint : m_chain->listMNCollaterials(outputs)) {
LockCoin(outPoint);
}
for (const auto& utxo : ListProTxCoins(candidates)) {
LockCoin(utxo, &batch);
}
}

Expand Down Expand Up @@ -4056,20 +4052,18 @@ DBErrors CWallet::LoadWallet()
// This avoids accidental spending of collaterals. They can still be unlocked manually if a spend is really intended.
void CWallet::AutoLockMasternodeCollaterals()
{
if (!m_chain) return;

std::vector<std::pair<const CTransactionRef&, unsigned int>> outputs;

std::set<COutPoint> candidates;
LOCK(cs_wallet);
for (const auto& pair : mapWallet) {
for (unsigned int i = 0; i < pair.second.tx->vout.size(); ++i) {
if (IsMine(pair.second.tx->vout[i]) && !IsSpent(pair.first, i)) {
outputs.emplace_back(pair.second.tx, i);
for (const auto& [txid, wtx] : mapWallet) {
for (unsigned int i = 0; i < wtx.tx->vout.size(); ++i) {
if (IsMine(wtx.tx->vout[i]) && !IsSpent(txid, i)) {
candidates.emplace(txid, i);
}
}
}
for (const auto& outPoint : m_chain->listMNCollaterials(outputs)) {
LockCoin(outPoint);
WalletBatch batch(GetDatabase());
for (const auto& utxo : ListProTxCoins(candidates)) {
LockCoin(utxo, &batch);
}
}

Expand Down Expand Up @@ -4512,24 +4506,22 @@ void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts) const
}
}

void CWallet::ListProTxCoins(std::vector<COutPoint>& vOutpts) const
{
// TODO: refactor duplicated code between CWallet::AutoLockMasternodeCollaterals and CWallet::ListProTxCoins
if (!m_chain) {
vOutpts.clear();
return;
}
std::vector<std::pair<const CTransactionRef&, unsigned int>> outputs;
std::vector<COutPoint> CWallet::ListProTxCoins() const { return ListProTxCoins(setWalletUTXO); }

std::vector<COutPoint> CWallet::ListProTxCoins(const std::set<COutPoint>& utxos) const
{
AssertLockHeld(cs_wallet);
for (const auto &o : setWalletUTXO) {
auto it = mapWallet.find(o.hash);
if (it != mapWallet.end()) {
const auto &ptx = it->second;
outputs.emplace_back(ptx.tx, o.n);

if (!m_chain) return std::vector<COutPoint>();

std::vector<std::pair<const CTransactionRef&, /*index=*/uint32_t>> candidates;
for (const auto& output : utxos) {
if (auto it = mapWallet.find(output.hash); it != mapWallet.end()) {
const auto& [hash, wtx] = *it;
candidates.emplace_back(wtx.tx, output.n);
}
}
vOutpts = m_chain->listMNCollaterials(outputs);
return m_chain->listMNCollaterials(candidates);
}

/** @} */ // end of Actions
Expand Down
3 changes: 2 additions & 1 deletion src/wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,8 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
bool UnlockCoin(const COutPoint& output, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool UnlockAllCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void ListLockedCoins(std::vector<COutPoint>& vOutpts) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void ListProTxCoins(std::vector<COutPoint>& vOutpts) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
std::vector<COutPoint> ListProTxCoins() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
std::vector<COutPoint> ListProTxCoins(const std::set<COutPoint>& utxos) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);

/*
* Rescan abort properties
Expand Down

0 comments on commit 8ba0f27

Please sign in to comment.