Skip to content

Commit 47448c8

Browse files
random-zebrafurszy
authored andcommitted
[QA] pos_validation_tests: fix gTx double spending in G3
1 parent 128b901 commit 47448c8

File tree

1 file changed

+34
-22
lines changed

1 file changed

+34
-22
lines changed

src/wallet/test/pos_validations_tests.cpp

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,18 @@ COutPoint GetOutpointWithAmount(const CTransaction& tx, CAmount outpointValue)
126126
return {};
127127
}
128128

129+
static bool IsSpentOnFork(const COutput& coin, std::initializer_list<std::shared_ptr<CBlock>> forkchain = {})
130+
{
131+
for (const auto& block : forkchain) {
132+
const auto& usedOutput = block->vtx[1]->vin.at(0).prevout;
133+
if (coin.tx->GetHash() == usedOutput.hash && coin.i == (int)usedOutput.n) {
134+
// spent on fork
135+
return true;
136+
}
137+
}
138+
return false;
139+
}
140+
129141
std::shared_ptr<CBlock> CreateBlockInternal(CWallet* pwalletMain, const std::vector<CMutableTransaction>& txns = {},
130142
CBlockIndex* customPrevBlock = nullptr,
131143
std::initializer_list<std::shared_ptr<CBlock>> forkchain = {})
@@ -135,26 +147,15 @@ std::shared_ptr<CBlock> CreateBlockInternal(CWallet* pwalletMain, const std::vec
135147

136148
// Remove any utxo which is not deeper than 120 blocks (for the same reasoning
137149
// used when selecting tx inputs in CreateAndCommitTx)
138-
for (auto it = availableCoins.begin(); it != availableCoins.end() ;) {
139-
if (it->nDepth <= 120) {
140-
it = availableCoins.erase(it);
141-
} else {
142-
it++;
143-
}
144-
}
145-
146150
// Also, as the wallet is not prepared to follow several chains at the same time,
147151
// need to manually remove from the stakeable utxo set every already used
148152
// coinstake inputs on the previous blocks of the parallel chain so they
149153
// are not used again.
150-
for (const auto& block : forkchain) {
151-
auto usedOutput = block->vtx[1]->vin.at(0).prevout;
152-
for (auto it = availableCoins.begin(); it != availableCoins.end() ; it++) {
153-
if (it->tx->GetHash() == usedOutput.hash &&
154-
it->i == (int) usedOutput.n) {
155-
availableCoins.erase(it);
156-
break;
157-
}
154+
for (auto it = availableCoins.begin(); it != availableCoins.end() ;) {
155+
if (it->nDepth <= 120 || IsSpentOnFork(*it, forkchain)) {
156+
it = availableCoins.erase(it);
157+
} else {
158+
it++;
158159
}
159160
}
160161

@@ -179,6 +180,20 @@ std::shared_ptr<CBlock> CreateBlockInternal(CWallet* pwalletMain, const std::vec
179180
return pblock;
180181
}
181182

183+
static COutput GetUnspentCoin(CWallet* pwallet, std::initializer_list<std::shared_ptr<CBlock>> forkchain = {})
184+
{
185+
std::vector<COutput> availableCoins;
186+
CWallet::AvailableCoinsFilter coinsFilter;
187+
coinsFilter.minDepth = 120;
188+
BOOST_CHECK(pwallet->AvailableCoins(&availableCoins, nullptr, coinsFilter));
189+
for (const auto& coin : availableCoins) {
190+
if (!IsSpentOnFork(coin, forkchain)) {
191+
return coin;
192+
}
193+
}
194+
throw std::runtime_error("Unspent coin not found");
195+
}
196+
182197
BOOST_FIXTURE_TEST_CASE(created_on_fork_tests, TestPoSChainSetup)
183198
{
184199
// Let's create few more PoS blocks
@@ -354,12 +369,9 @@ BOOST_FIXTURE_TEST_CASE(created_on_fork_tests, TestPoSChainSetup)
354369
// ##############################################################################
355370

356371
// First create new coins in G
357-
std::vector<COutput> availableCoins;
358-
CWallet::AvailableCoinsFilter coinsFilter;
359-
coinsFilter.nMaximumCount = 3;
360-
coinsFilter.minDepth = 20;
361-
BOOST_CHECK(pwalletMain->AvailableCoins(&availableCoins, nullptr, coinsFilter));
362-
COutput input = availableCoins.at(0);
372+
// select an input that is not already spent in D3 or E3 (since we want to spend it also in G3)
373+
const COutput& input = GetUnspentCoin(pwalletMain.get(), {pblockD3, pblockE3});
374+
363375
coinControl.UnSelectAll();
364376
coinControl.Select(COutPoint(input.tx->GetHash(), input.i), input.Value());
365377
coinControl.fAllowOtherInputs = false;

0 commit comments

Comments
 (0)