Refactor IsSpent(nullifier) for Sprout and Sapling domain separation.
We need separate functions for checking Sprout and Sapling nullifiers, because they are in separate domains and aren't guaranteed to be collision-resistant (otherwise there is a possibility of a nullifier collision, however remote, between Sprout and Sapling causing the spend of one to prevent the spend of the other).
This commit is contained in:
parent
ec064abbdf
commit
3b6dd486b4
|
@ -179,7 +179,7 @@ TEST(WalletTests, FindUnspentNotes) {
|
||||||
|
|
||||||
wtx.SetSproutNoteData(noteData);
|
wtx.SetSproutNoteData(noteData);
|
||||||
wallet.AddToWallet(wtx, true, NULL);
|
wallet.AddToWallet(wtx, true, NULL);
|
||||||
EXPECT_FALSE(wallet.IsSpent(nullifier));
|
EXPECT_FALSE(wallet.IsSproutSpent(nullifier));
|
||||||
|
|
||||||
// We currently have an unspent and unconfirmed note in the wallet (depth of -1)
|
// We currently have an unspent and unconfirmed note in the wallet (depth of -1)
|
||||||
std::vector<CSproutNotePlaintextEntry> entries;
|
std::vector<CSproutNotePlaintextEntry> entries;
|
||||||
|
@ -204,7 +204,7 @@ TEST(WalletTests, FindUnspentNotes) {
|
||||||
|
|
||||||
wtx.SetMerkleBranch(block);
|
wtx.SetMerkleBranch(block);
|
||||||
wallet.AddToWallet(wtx, true, NULL);
|
wallet.AddToWallet(wtx, true, NULL);
|
||||||
EXPECT_FALSE(wallet.IsSpent(nullifier));
|
EXPECT_FALSE(wallet.IsSproutSpent(nullifier));
|
||||||
|
|
||||||
|
|
||||||
// We now have an unspent and confirmed note in the wallet (depth of 1)
|
// We now have an unspent and confirmed note in the wallet (depth of 1)
|
||||||
|
@ -222,7 +222,7 @@ TEST(WalletTests, FindUnspentNotes) {
|
||||||
// Let's spend the note.
|
// Let's spend the note.
|
||||||
auto wtx2 = GetValidSpend(sk, note, 5);
|
auto wtx2 = GetValidSpend(sk, note, 5);
|
||||||
wallet.AddToWallet(wtx2, true, NULL);
|
wallet.AddToWallet(wtx2, true, NULL);
|
||||||
EXPECT_FALSE(wallet.IsSpent(nullifier));
|
EXPECT_FALSE(wallet.IsSproutSpent(nullifier));
|
||||||
|
|
||||||
// Fake-mine a spend transaction
|
// Fake-mine a spend transaction
|
||||||
EXPECT_EQ(0, chainActive.Height());
|
EXPECT_EQ(0, chainActive.Height());
|
||||||
|
@ -240,7 +240,7 @@ TEST(WalletTests, FindUnspentNotes) {
|
||||||
|
|
||||||
wtx2.SetMerkleBranch(block2);
|
wtx2.SetMerkleBranch(block2);
|
||||||
wallet.AddToWallet(wtx2, true, NULL);
|
wallet.AddToWallet(wtx2, true, NULL);
|
||||||
EXPECT_TRUE(wallet.IsSpent(nullifier));
|
EXPECT_TRUE(wallet.IsSproutSpent(nullifier));
|
||||||
|
|
||||||
// The note has been spent. By default, GetFilteredNotes() ignores spent notes.
|
// The note has been spent. By default, GetFilteredNotes() ignores spent notes.
|
||||||
wallet.GetFilteredNotes(entries, "", 0);
|
wallet.GetFilteredNotes(entries, "", 0);
|
||||||
|
@ -274,7 +274,7 @@ TEST(WalletTests, FindUnspentNotes) {
|
||||||
|
|
||||||
wtx.SetSproutNoteData(noteData);
|
wtx.SetSproutNoteData(noteData);
|
||||||
wallet.AddToWallet(wtx, true, NULL);
|
wallet.AddToWallet(wtx, true, NULL);
|
||||||
EXPECT_FALSE(wallet.IsSpent(nullifier));
|
EXPECT_FALSE(wallet.IsSproutSpent(nullifier));
|
||||||
|
|
||||||
wtx3 = wtx;
|
wtx3 = wtx;
|
||||||
}
|
}
|
||||||
|
@ -490,14 +490,14 @@ TEST(WalletTests, NullifierIsSpent) {
|
||||||
auto note = GetNote(sk, wtx, 0, 1);
|
auto note = GetNote(sk, wtx, 0, 1);
|
||||||
auto nullifier = note.nullifier(sk);
|
auto nullifier = note.nullifier(sk);
|
||||||
|
|
||||||
EXPECT_FALSE(wallet.IsSpent(nullifier));
|
EXPECT_FALSE(wallet.IsSproutSpent(nullifier));
|
||||||
|
|
||||||
wallet.AddToWallet(wtx, true, NULL);
|
wallet.AddToWallet(wtx, true, NULL);
|
||||||
EXPECT_FALSE(wallet.IsSpent(nullifier));
|
EXPECT_FALSE(wallet.IsSproutSpent(nullifier));
|
||||||
|
|
||||||
auto wtx2 = GetValidSpend(sk, note, 5);
|
auto wtx2 = GetValidSpend(sk, note, 5);
|
||||||
wallet.AddToWallet(wtx2, true, NULL);
|
wallet.AddToWallet(wtx2, true, NULL);
|
||||||
EXPECT_FALSE(wallet.IsSpent(nullifier));
|
EXPECT_FALSE(wallet.IsSproutSpent(nullifier));
|
||||||
|
|
||||||
// Fake-mine the transaction
|
// Fake-mine the transaction
|
||||||
EXPECT_EQ(-1, chainActive.Height());
|
EXPECT_EQ(-1, chainActive.Height());
|
||||||
|
@ -513,7 +513,7 @@ TEST(WalletTests, NullifierIsSpent) {
|
||||||
|
|
||||||
wtx2.SetMerkleBranch(block);
|
wtx2.SetMerkleBranch(block);
|
||||||
wallet.AddToWallet(wtx2, true, NULL);
|
wallet.AddToWallet(wtx2, true, NULL);
|
||||||
EXPECT_TRUE(wallet.IsSpent(nullifier));
|
EXPECT_TRUE(wallet.IsSproutSpent(nullifier));
|
||||||
|
|
||||||
// Tear down
|
// Tear down
|
||||||
chainActive.SetTip(NULL);
|
chainActive.SetTip(NULL);
|
||||||
|
|
|
@ -712,8 +712,7 @@ bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
|
||||||
* Note is spent if any non-conflicted transaction
|
* Note is spent if any non-conflicted transaction
|
||||||
* spends it:
|
* spends it:
|
||||||
*/
|
*/
|
||||||
bool CWallet::IsSpent(const uint256& nullifier) const
|
bool CWallet::IsSproutSpent(const uint256& nullifier) const {
|
||||||
{
|
|
||||||
pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range;
|
pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range;
|
||||||
range = mapTxSproutNullifiers.equal_range(nullifier);
|
range = mapTxSproutNullifiers.equal_range(nullifier);
|
||||||
|
|
||||||
|
@ -724,7 +723,11 @@ bool CWallet::IsSpent(const uint256& nullifier) const
|
||||||
return true; // Spent
|
return true; // Spent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWallet::IsSaplingSpent(const uint256& nullifier) const {
|
||||||
|
pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range;
|
||||||
range = mapTxSaplingNullifiers.equal_range(nullifier);
|
range = mapTxSaplingNullifiers.equal_range(nullifier);
|
||||||
|
|
||||||
for (TxNullifiers::const_iterator it = range.first; it != range.second; ++it) {
|
for (TxNullifiers::const_iterator it = range.first; it != range.second; ++it) {
|
||||||
|
@ -4123,7 +4126,7 @@ void CWallet::GetFilteredNotes(
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip note which has been spent
|
// skip note which has been spent
|
||||||
if (ignoreSpent && nd.nullifier && IsSpent(*nd.nullifier)) {
|
if (ignoreSpent && nd.nullifier && IsSproutSpent(*nd.nullifier)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4204,7 +4207,7 @@ void CWallet::GetUnspentFilteredNotes(
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip note which has been spent
|
// skip note which has been spent
|
||||||
if (nd.nullifier && IsSpent(*nd.nullifier)) {
|
if (nd.nullifier && IsSproutSpent(*nd.nullifier)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -936,7 +936,8 @@ public:
|
||||||
bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const;
|
bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const;
|
||||||
|
|
||||||
bool IsSpent(const uint256& hash, unsigned int n) const;
|
bool IsSpent(const uint256& hash, unsigned int n) const;
|
||||||
bool IsSpent(const uint256& nullifier) const;
|
bool IsSproutSpent(const uint256& nullifier) const;
|
||||||
|
bool IsSaplingSpent(const uint256& nullifier) const;
|
||||||
|
|
||||||
bool IsLockedCoin(uint256 hash, unsigned int n) const;
|
bool IsLockedCoin(uint256 hash, unsigned int n) const;
|
||||||
void LockCoin(COutPoint& output);
|
void LockCoin(COutPoint& output);
|
||||||
|
|
Loading…
Reference in New Issue