Skip to content

Commit 5862a0b

Browse files
committed
Segwit light for spending coins.
Handle segwit-light properly when spending coins, either for staking or normal transactions in the wallet. Depending on when a transaction was confirmed, we need to make sure to include the right outpoint (with txid or bare txid) in the transaction spending an output. This is done through a custom UTXO hasher used in the wallet, which specifically works for CWalletTx.
1 parent b4d0b06 commit 5862a0b

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

divi/src/primitives/transaction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ class CTransaction
139139

140140
CTransaction& operator=(const CTransaction& tx);
141141

142+
virtual ~CTransaction() = default;
143+
142144
ADD_SERIALIZE_METHODS;
143145

144146
template <typename Stream, typename Operation>

divi/src/wallet.cpp

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "checkpoints.h"
1313
#include <chain.h>
1414
#include <chainparams.h>
15+
#include "ForkActivation.h"
1516
#include "net.h"
1617
#include "script/script.h"
1718
#include "script/sign.h"
@@ -175,17 +176,42 @@ std::set<CTxDestination> AddressBookManager::GetAccountAddresses(std::string str
175176
namespace
176177
{
177178

178-
/** Dummy UTXO hasher for the wallet. For now, this just always returns
179-
* the normal txid, but we will later change it to return the proper hash
180-
* for a WalletTx. */
179+
/** UTXO hasher for wallet transactions. It uses the transaction's known block
180+
* hash (from CMerkleTx) to determine the activation state of segwit light. */
181181
class WalletUtxoHasher : public TransactionUtxoHasher
182182
{
183183

184+
private:
185+
186+
const I_MerkleTxConfirmationNumberCalculator& confirmationNumberCalculator_;
187+
const CChain& chainActive_;
188+
184189
public:
185190

191+
WalletUtxoHasher(const I_MerkleTxConfirmationNumberCalculator& calc, const CChain& chain)
192+
: confirmationNumberCalculator_(calc), chainActive_(chain)
193+
{}
194+
186195
OutputHash GetUtxoHash(const CTransaction& tx) const override
187196
{
188-
return OutputHash(tx.GetHash());
197+
const CMerkleTx* mtx = dynamic_cast<const CMerkleTx*>(&tx);
198+
assert(mtx != nullptr);
199+
200+
const auto conf = confirmationNumberCalculator_.FindConfirmedBlockIndexAndDepth(*mtx);
201+
const CBlockIndex* pindexBlock = conf.first;
202+
203+
/* If the transaction is not yet confirmed in a block, we use the current
204+
tip to determine the segwit-light activation status. This is not
205+
perfect around the activation time, but there is nothing we can do
206+
in that case anyway. Mempool and wallet discourage spending unconfirmed
207+
outputs around the segwit-light fork anyway. */
208+
if (conf.second <= 0)
209+
pindexBlock = chainActive_.Tip();
210+
211+
assert(pindexBlock != nullptr);
212+
const ActivationState as(pindexBlock);
213+
214+
return OutputHash(as.IsActive(Fork::SegwitLight) ? mtx->GetBareTxid() : mtx->GetHash());
189215
}
190216

191217
};
@@ -210,7 +236,7 @@ CWallet::CWallet(const CChain& chain, const BlockMap& blockMap
210236
, transactionRecord_(new WalletTransactionRecord(cs_wallet,strWalletFile) )
211237
, outputTracker_( new SpentOutputTracker(*transactionRecord_,*confirmationNumberCalculator_) )
212238
, pwalletdbEncryption()
213-
, utxoHasher(new WalletUtxoHasher() )
239+
, utxoHasher(new WalletUtxoHasher(*confirmationNumberCalculator_, chain) )
214240
, orderedTransactionIndex()
215241
, nWalletVersion(FEATURE_BASE)
216242
, nWalletMaxVersion(FEATURE_BASE)
@@ -3094,4 +3120,4 @@ void CWallet::LockFully()
30943120
LOCK(cs_wallet);
30953121
walletStakingOnly = false;
30963122
Lock();
3097-
}
3123+
}

0 commit comments

Comments
 (0)