Skip to content

Commit d8d5cda

Browse files
committed
Unit tests for UTXO hasher in wallet.
Extend the unit tests in wallet_coinmanagement_tests.cpp to include also explicit checks for situations in which the wallet is supposed to the UTXO hasher rather than e.g. a plain transaction hash.
1 parent a7c8845 commit d8d5cda

File tree

3 files changed

+75
-3
lines changed

3 files changed

+75
-3
lines changed

divi/src/test/FakeWallet.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,8 @@ void FakeWallet::AddConfirmations(const unsigned numConf, const int64_t minAge)
120120
fakeChain.addBlocks(numConf, version, fakeChain.activeChain->Tip()->nTime + minAge);
121121
}
122122

123-
const CWalletTx& FakeWallet::AddDefaultTx(const CScript& scriptToPayTo, unsigned& outputIndex,
124-
const CAmount amount)
123+
const CWalletTx& FakeWallet::Add(const CTransaction& tx)
125124
{
126-
const CMutableTransaction tx = createDefaultTransaction(scriptToPayTo, outputIndex, amount);
127125
const CMerkleTx merkleTx(tx, *fakeChain.activeChain, *fakeChain.blockIndexByHash);
128126
const CWalletTx wtx(merkleTx);
129127
AddToWallet(wtx);
@@ -132,6 +130,12 @@ const CWalletTx& FakeWallet::AddDefaultTx(const CScript& scriptToPayTo, unsigned
132130
return *txPtr;
133131
}
134132

133+
const CWalletTx& FakeWallet::AddDefaultTx(const CScript& scriptToPayTo, unsigned& outputIndex,
134+
const CAmount amount)
135+
{
136+
return Add(createDefaultTransaction(scriptToPayTo, outputIndex, amount));
137+
}
138+
135139
void FakeWallet::FakeAddToChain(const CWalletTx& tx)
136140
{
137141
auto* txPtr = const_cast<CWalletTx*>(&tx);

divi/src/test/FakeWallet.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class FakeWallet : public CWallet
4545
* and number of confirmations. */
4646
void AddConfirmations(unsigned numConf, int64_t minAge = 0);
4747

48+
/** Adds a given transaction to the wallet. */
49+
const CWalletTx& Add(const CTransaction& tx);
50+
4851
/** Adds a new ordinary transaction to the wallet, paying a given amount
4952
* to a given script. The transaction is returned, and the output index
5053
* with the output to the requested script is set. */

divi/src/test/wallet_coinmanagement_tests.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,24 @@
1515
#include <chain.h>
1616
#include <blockmap.h>
1717
#include <test/FakeWallet.h>
18+
#include <test/MockUtxoHasher.h>
1819
#include <StakableCoin.h>
1920

2021
class WalletCoinManagementTestFixture
2122
{
2223
public:
2324
FakeBlockIndexWithHashes fakeChain;
2425
FakeWallet wallet;
26+
MockUtxoHasher* utxoHasher;
2527

2628
WalletCoinManagementTestFixture()
2729
: fakeChain(1, 1600000000, 1), wallet(fakeChain)
2830
{
2931
ENTER_CRITICAL_SECTION(wallet.cs_wallet);
32+
33+
std::unique_ptr<MockUtxoHasher> hasher(new MockUtxoHasher());
34+
utxoHasher = hasher.get();
35+
wallet.SetUtxoHasherForTesting(std::move(hasher));
3036
}
3137
~WalletCoinManagementTestFixture()
3238
{
@@ -400,4 +406,63 @@ BOOST_AUTO_TEST_CASE(willEnsureStakingBalanceAndTotalBalanceAgreeEvenIfTxsBelong
400406
BOOST_CHECK_EQUAL_MESSAGE(stakableCoins.size(),2,"Missing coins in the stakable set");
401407
}
402408

409+
BOOST_AUTO_TEST_CASE(willUseUtxoHasherForCoinLock)
410+
{
411+
CScript defaultScript = GetScriptForDestination(wallet.getNewKey().GetID());
412+
unsigned outputIndex=0;
413+
const CWalletTx& wtx = wallet.AddDefaultTx(defaultScript,outputIndex, COIN);
414+
const auto id = utxoHasher->Add(wtx);
415+
416+
wallet.LockCoin(COutPoint(id, outputIndex));
417+
418+
bool fIsSpendable;
419+
BOOST_CHECK(!wallet.IsAvailableForSpending(&wtx,outputIndex,false,fIsSpendable,ALL_SPENDABLE_COINS));
420+
421+
BOOST_CHECK_EQUAL(wallet.ComputeCredit(wtx, ISMINE_SPENDABLE, REQUIRE_UNLOCKED), 0);
422+
BOOST_CHECK_EQUAL(wallet.ComputeCredit(wtx, ISMINE_SPENDABLE, REQUIRE_LOCKED), COIN);
423+
}
424+
425+
BOOST_AUTO_TEST_CASE(willMarkOutputsSpentBasedOnUtxoHasher)
426+
{
427+
CScript defaultScript = GetScriptForDestination(wallet.getNewKey().GetID());
428+
unsigned outputIndex=0;
429+
const CWalletTx& wtx = wallet.AddDefaultTx(defaultScript,outputIndex, COIN);
430+
const auto id = utxoHasher->Add(wtx);
431+
432+
CMutableTransaction mtx;
433+
mtx.vin.emplace_back(id, outputIndex);
434+
const auto& spendTx = wallet.Add(mtx);
435+
436+
/* The wallet's IsSpent check verifies also the spending tx' number
437+
of confirmations, which requires it to be either in the chain or
438+
in the mempool at least. */
439+
wallet.FakeAddToChain(wtx);
440+
wallet.FakeAddToChain(spendTx);
441+
442+
BOOST_CHECK(wallet.IsSpent(wtx, outputIndex));
443+
bool fIsSpendable;
444+
BOOST_CHECK(!wallet.IsAvailableForSpending(&wtx,outputIndex,false,fIsSpendable,ALL_SPENDABLE_COINS));
445+
}
446+
447+
BOOST_AUTO_TEST_CASE(willUseUtxoHashForSpendingCoins)
448+
{
449+
CScript defaultScript = GetScriptForDestination(wallet.getNewKey().GetID());
450+
unsigned outputIndex=0;
451+
const CWalletTx& wtx = wallet.AddDefaultTx(defaultScript,outputIndex, COIN);
452+
const auto id = utxoHasher->Add(wtx);
453+
wallet.FakeAddToChain(wtx);
454+
455+
const CScript sendTo = CScript() << OP_TRUE;
456+
std::string strError;
457+
CReserveKey reserveKey(wallet);
458+
CAmount nFeeRequired;
459+
CWalletTx wtxNew;
460+
BOOST_CHECK(wallet.CreateTransaction({{sendTo, COIN / 10}}, wtxNew, reserveKey, ALL_SPENDABLE_COINS, nullptr).second);
461+
462+
BOOST_CHECK_EQUAL(wtxNew.vin.size(), 1);
463+
const auto& prevout = wtxNew.vin[0].prevout;
464+
BOOST_CHECK(prevout.hash == id);
465+
BOOST_CHECK_EQUAL(prevout.n, outputIndex);
466+
}
467+
403468
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)