aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Rubin <j@rubin.io>2019-08-30 13:25:41 -0700
committerJeremy Rubin <j@rubin.io>2019-10-21 13:16:22 -0700
commit595f09d6de7f1b94428cdd1310777aa6a4c584e5 (patch)
tree1b0757ce67c764b91ac4ccf97bc95fe6f7dbc99e
parentdce032ce294fe0d531770f540b1de00dc1d13f4b (diff)
Cache tx Trust per-call to avoid DoS
-rw-r--r--src/wallet/wallet.cpp12
-rw-r--r--src/wallet/wallet.h1
2 files changed, 12 insertions, 1 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 5acd0dbf0c..ae6c268484 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2295,6 +2295,12 @@ bool CWalletTx::InMempool() const
bool CWalletTx::IsTrusted(interfaces::Chain::Lock& locked_chain) const
{
+ std::set<uint256> s;
+ return IsTrusted(locked_chain, s);
+}
+
+bool CWalletTx::IsTrusted(interfaces::Chain::Lock& locked_chain, std::set<uint256>& trustedParents) const
+{
// Quick answer in most cases
if (!locked_chain.checkFinalTx(*tx)) {
return false;
@@ -2322,9 +2328,13 @@ bool CWalletTx::IsTrusted(interfaces::Chain::Lock& locked_chain) const
// Check that this specific input being spent is trusted
if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
return false;
+ // If we've already trusted this parent, continue
+ if (trustedParents.count(parent->GetHash()))
+ continue;
// Recurse to check that the parent is also trusted
- if (!parent->IsTrusted(locked_chain))
+ if (!parent->IsTrusted(locked_chain, trustedParents))
return false;
+ trustedParents.insert(parent->GetHash());
}
return true;
}
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index f9e2230a6f..986baa89ee 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -616,6 +616,7 @@ public:
bool InMempool() const;
bool IsTrusted(interfaces::Chain::Lock& locked_chain) const;
+ bool IsTrusted(interfaces::Chain::Lock& locked_chain, std::set<uint256>& trustedParents) const;
int64_t GetTxTime() const;