Skip to content

Commit b0b0ad6

Browse files
Merge #6770: refactor: follow-up dash#6742, implement review suggestions, avoid redundant transaction queries
f488c43 fix: remove unnecessary tx fetching in `RemoveMempoolConflictsForLock` (Kittywhiskers Van Gogh) dd54011 refactor: move inexpensive checks earlier in `ProcessInstantSendLock()` (Kittywhiskers Van Gogh) c86d886 refactor: abstract away InstantSend parent implementation from signer (Kittywhiskers Van Gogh) cbfd325 refactor: avoid shared_ptr copies in `{WriteNew,Remove}InstantSendLock()` (Kittywhiskers Van Gogh) 234a16a refactor: use unordered set for faster duplicates checking (Kittywhiskers Van Gogh) 0459848 refactor: `constexpr` static string definitions (Kittywhiskers Van Gogh) 710c504 refactor: s/cs_inputReqests/cs_input_requests/g (Kittywhiskers Van Gogh) 31065d1 chore: mark `hashBlock` as unused in `HandleNewInputLockRecoveredSig()` (Kittywhiskers Van Gogh) cf47f14 chore: apply most `clang-format` suggestions (Kittywhiskers Van Gogh) 63371e0 trivial: move forward declaration above `using` declarations (Kittywhiskers Van Gogh) Pull request description: ## Additional Information * Dependent on #6742 * This pull request aims to address reviewer concerns raised during [dash#6742](#6742), the following changes were made with that in mind * Marking unused variable `hashBlock` by prefixing with underscore, [comment](#6742 (comment)) * Correct typo in variable name `cs_inputReqests` (now `cs_input_requests`, [comment](#6770 (comment))), [comment](#6742 (comment)) * Using `constexpr` for `std::string_view`s, [comment](#6742 (comment)) * Utilizing a faster way to validate uniqueness of entries (`std::unordered_set`), [comment](#6742 (comment)). The construction of the unordered set is inspired by similar usage in `policy/package.cpp` ([source](https://github.com/dashpay/dash/blob/f648039258d2192ec5e505721e34edaa0bda568c/src/policy/packages.cpp#L51)). * Avoiding unnecessary `std::shared_ptr` copying (`InstantSendLockPtr` is a `std::shared_ptr<InstantSendLock>`), [comment](#6742 (comment)) * Resolving circular dependency by cherry-picking 1e2e854, [comment](#6742 (comment)) but has been renamed to `InstantSendSignerParent`. For rationale, see [comment](#6761 (comment)). * Additionally, optimizations have been made to `ProcessInstantSendLock()` * The _cheaper_ database checks have been moved _earlier_ in the function to allow for faster bail-out. This is alongside consolidating network requests to the tail of the function and general cleanup for better clarity. * Dropping the peer request for a transaction we know about in `RemoveMempoolConflictsForLock()` (introduced in [dash#2898](#2898)) as `ProcessInstantSendLock()` calls it when we _know_ about the transaction and seek to remove conflicts ([source](https://github.com/dashpay/dash/blob/f648039258d2192ec5e505721e34edaa0bda568c/src/instantsend/instantsend.cpp#L419-L420)) The only other caller, `TransactionAddedToMempool()` calls it when we have knowledge of the transaction and want to purge conflicts from the mempool ([source](https://github.com/dashpay/dash/blob/f648039258d2192ec5e505721e34edaa0bda568c/src/instantsend/instantsend.cpp#L455-L463)). In both cases, we already know the _good_ transaction. Additionally, tests introduced in [dash#2898](#2898) still pass ([source](https://github.com/dashpay/dash/blob/f648039258d2192ec5e505721e34edaa0bda568c/test/functional/p2p_instantsend.py#L95-L142)), indicating a lack of regression but this change may require additional scrutiny. ## Breaking Changes None expected. ## Checklist - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)** - [x] I have added or updated relevant unit/integration/functional/e2e tests **(note: N/A)** - [x] I have made corresponding changes to the documentation **(note: N/A)** - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: PastaPastaPasta: utACK f488c43 knst: utACK f488c43 UdjinM6: utACK f488c43 Tree-SHA512: dcd153e14747639f8dbbbd5c3bea1123e4f84f82884787992e20f494227913763bf19a73b485e345dddb63ad551c856bc56dcad72e67304f84df60cb76deaa74
2 parents d93878e + f488c43 commit b0b0ad6

File tree

9 files changed

+187
-179
lines changed

9 files changed

+187
-179
lines changed

src/dsnotificationinterface.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ void CDSNotificationInterface::TransactionAddedToMempool(const CTransactionRef&
104104
{
105105
assert(m_cj_ctx && m_llmq_ctx);
106106

107-
m_llmq_ctx->isman->TransactionAddedToMempool(m_peerman, ptx);
107+
m_llmq_ctx->isman->TransactionAddedToMempool(ptx);
108108
m_llmq_ctx->clhandler->TransactionAddedToMempool(ptx, nAcceptTime);
109109
m_cj_ctx->dstxman->TransactionAddedToMempool(ptx);
110110
}

src/instantsend/db.cpp

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@
99
#include <primitives/block.h>
1010
#include <util/system.h>
1111

12-
static const std::string_view DB_ARCHIVED_BY_HASH = "is_a2";
13-
static const std::string_view DB_ARCHIVED_BY_HEIGHT_AND_HASH = "is_a1";
14-
static const std::string_view DB_HASH_BY_OUTPOINT = "is_in";
15-
static const std::string_view DB_HASH_BY_TXID = "is_tx";
16-
static const std::string_view DB_ISLOCK_BY_HASH = "is_i";
17-
static const std::string_view DB_MINED_BY_HEIGHT_AND_HASH = "is_m";
18-
static const std::string_view DB_VERSION = "is_v";
12+
static constexpr std::string_view DB_ARCHIVED_BY_HASH{"is_a2"};
13+
static constexpr std::string_view DB_ARCHIVED_BY_HEIGHT_AND_HASH{"is_a1"};
14+
static constexpr std::string_view DB_HASH_BY_OUTPOINT{"is_in"};
15+
static constexpr std::string_view DB_HASH_BY_TXID{"is_tx"};
16+
static constexpr std::string_view DB_ISLOCK_BY_HASH{"is_i"};
17+
static constexpr std::string_view DB_MINED_BY_HEIGHT_AND_HASH{"is_m"};
18+
static constexpr std::string_view DB_VERSION{"is_v"};
1919

2020
namespace instantsend {
2121
namespace {
22-
static std::tuple<std::string, uint32_t, uint256> BuildInversedISLockKey(std::string_view k, int nHeight, const uint256& islockHash)
22+
static std::tuple<std::string, uint32_t, uint256> BuildInversedISLockKey(std::string_view k, int nHeight,
23+
const uint256& islockHash)
2324
{
2425
return std::make_tuple(std::string{k}, htobe32_internal(std::numeric_limits<uint32_t>::max() - nHeight), islockHash);
2526
}
@@ -50,44 +51,39 @@ void CInstantSendDb::Upgrade(bool unitTests)
5051
}
5152
}
5253

53-
void CInstantSendDb::WriteNewInstantSendLock(const uint256& hash, const InstantSendLock& islock)
54+
void CInstantSendDb::WriteNewInstantSendLock(const uint256& hash, const InstantSendLockPtr& islock)
5455
{
5556
LOCK(cs_db);
5657
CDBBatch batch(*db);
57-
batch.Write(std::make_tuple(DB_ISLOCK_BY_HASH, hash), islock);
58-
batch.Write(std::make_tuple(DB_HASH_BY_TXID, islock.txid), hash);
59-
for (const auto& in : islock.inputs) {
58+
batch.Write(std::make_tuple(DB_ISLOCK_BY_HASH, hash), *islock);
59+
batch.Write(std::make_tuple(DB_HASH_BY_TXID, islock->txid), hash);
60+
for (const auto& in : islock->inputs) {
6061
batch.Write(std::make_tuple(DB_HASH_BY_OUTPOINT, in), hash);
6162
}
6263
db->WriteBatch(batch);
6364

64-
islockCache.insert(hash, std::make_shared<InstantSendLock>(islock));
65-
txidCache.insert(islock.txid, hash);
66-
for (const auto& in : islock.inputs) {
65+
islockCache.insert(hash, islock);
66+
txidCache.insert(islock->txid, hash);
67+
for (const auto& in : islock->inputs) {
6768
outpointCache.insert(in, hash);
6869
}
6970
}
7071

71-
void CInstantSendDb::RemoveInstantSendLock(CDBBatch& batch, const uint256& hash, InstantSendLockPtr islock, bool keep_cache)
72+
void CInstantSendDb::RemoveInstantSendLock(CDBBatch& batch, const uint256& hash, const InstantSendLock& islock,
73+
bool keep_cache)
7274
{
7375
AssertLockHeld(cs_db);
74-
if (!islock) {
75-
islock = GetInstantSendLockByHashInternal(hash, false);
76-
if (!islock) {
77-
return;
78-
}
79-
}
8076

8177
batch.Erase(std::make_tuple(DB_ISLOCK_BY_HASH, hash));
82-
batch.Erase(std::make_tuple(DB_HASH_BY_TXID, islock->txid));
83-
for (auto& in : islock->inputs) {
78+
batch.Erase(std::make_tuple(DB_HASH_BY_TXID, islock.txid));
79+
for (auto& in : islock.inputs) {
8480
batch.Erase(std::make_tuple(DB_HASH_BY_OUTPOINT, in));
8581
}
8682

8783
if (!keep_cache) {
8884
islockCache.erase(hash);
89-
txidCache.erase(islock->txid);
90-
for (const auto& in : islock->inputs) {
85+
txidCache.erase(islock.txid);
86+
for (const auto& in : islock.inputs) {
9187
outpointCache.erase(in);
9288
}
9389
}
@@ -151,7 +147,7 @@ std::unordered_map<uint256, InstantSendLockPtr, StaticSaltedHasher> CInstantSend
151147
auto& islockHash = std::get<2>(curKey);
152148

153149
if (auto islock = GetInstantSendLockByHashInternal(islockHash, false)) {
154-
RemoveInstantSendLock(batch, islockHash, islock);
150+
RemoveInstantSendLock(batch, islockHash, *islock);
155151
ret.try_emplace(islockHash, std::move(islock));
156152
}
157153

@@ -221,7 +217,8 @@ void CInstantSendDb::WriteBlockInstantSendLocks(const gsl::not_null<std::shared_
221217
db->WriteBatch(batch);
222218
}
223219

224-
void CInstantSendDb::RemoveBlockInstantSendLocks(const gsl::not_null<std::shared_ptr<const CBlock>>& pblock, gsl::not_null<const CBlockIndex*> pindexDisconnected)
220+
void CInstantSendDb::RemoveBlockInstantSendLocks(const gsl::not_null<std::shared_ptr<const CBlock>>& pblock,
221+
gsl::not_null<const CBlockIndex*> pindexDisconnected)
225222
{
226223
LOCK(cs_db);
227224
CDBBatch batch(*db);
@@ -241,7 +238,8 @@ void CInstantSendDb::RemoveBlockInstantSendLocks(const gsl::not_null<std::shared
241238
bool CInstantSendDb::KnownInstantSendLock(const uint256& islockHash) const
242239
{
243240
LOCK(cs_db);
244-
return GetInstantSendLockByHashInternal(islockHash) != nullptr || db->Exists(std::make_tuple(DB_ARCHIVED_BY_HASH, islockHash));
241+
return GetInstantSendLockByHashInternal(islockHash) != nullptr ||
242+
db->Exists(std::make_tuple(DB_ARCHIVED_BY_HASH, islockHash));
245243
}
246244

247245
size_t CInstantSendDb::GetInstantSendLockCount() const
@@ -354,7 +352,8 @@ std::vector<uint256> CInstantSendDb::GetInstantSendLocksByParent(const uint256&
354352
return result;
355353
}
356354

357-
std::vector<uint256> CInstantSendDb::RemoveChainedInstantSendLocks(const uint256& islockHash, const uint256& txid, int nHeight)
355+
std::vector<uint256> CInstantSendDb::RemoveChainedInstantSendLocks(const uint256& islockHash, const uint256& txid,
356+
int nHeight)
358357
{
359358
LOCK(cs_db);
360359
std::vector<uint256> result;
@@ -374,7 +373,7 @@ std::vector<uint256> CInstantSendDb::RemoveChainedInstantSendLocks(const uint256
374373
continue;
375374
}
376375

377-
RemoveInstantSendLock(batch, childIslockHash, childIsLock, false);
376+
RemoveInstantSendLock(batch, childIslockHash, *childIsLock, false);
378377
WriteInstantSendLockArchived(batch, childIslockHash, nHeight);
379378
result.emplace_back(childIslockHash);
380379

@@ -384,7 +383,9 @@ std::vector<uint256> CInstantSendDb::RemoveChainedInstantSendLocks(const uint256
384383
}
385384
}
386385

387-
RemoveInstantSendLock(batch, islockHash, nullptr, false);
386+
if (auto islock = GetInstantSendLockByHashInternal(islockHash, /*use_cache=*/false)) {
387+
RemoveInstantSendLock(batch, islockHash, *islock, false);
388+
}
388389
WriteInstantSendLockArchived(batch, islockHash, nHeight);
389390
result.emplace_back(islockHash);
390391

src/instantsend/db.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ class CInstantSendDb
3333

3434
static constexpr int CURRENT_VERSION{1};
3535

36-
int best_confirmed_height GUARDED_BY(cs_db) {0};
36+
int best_confirmed_height GUARDED_BY(cs_db){0};
3737

38-
std::unique_ptr<CDBWrapper> db GUARDED_BY(cs_db) {nullptr};
38+
std::unique_ptr<CDBWrapper> db GUARDED_BY(cs_db){nullptr};
3939
mutable unordered_lru_cache<uint256, InstantSendLockPtr, StaticSaltedHasher, 10000> islockCache GUARDED_BY(cs_db);
4040
mutable unordered_lru_cache<uint256, uint256, StaticSaltedHasher, 10000> txidCache GUARDED_BY(cs_db);
4141

@@ -51,7 +51,8 @@ class CInstantSendDb
5151
* @param islock The InstantSend Lock object itself
5252
* @param keep_cache Should we still keep corresponding entries in the cache or not
5353
*/
54-
void RemoveInstantSendLock(CDBBatch& batch, const uint256& hash, InstantSendLockPtr islock, bool keep_cache = true) EXCLUSIVE_LOCKS_REQUIRED(cs_db);
54+
void RemoveInstantSendLock(CDBBatch& batch, const uint256& hash, const InstantSendLock& islock,
55+
bool keep_cache = true) EXCLUSIVE_LOCKS_REQUIRED(cs_db);
5556
/**
5657
* Marks an InstantSend Lock as archived.
5758
* @param batch Object used to batch many calls together
@@ -88,7 +89,7 @@ class CInstantSendDb
8889
* @param hash The hash of the InstantSend Lock
8990
* @param islock The InstantSend Lock object itself
9091
*/
91-
void WriteNewInstantSendLock(const uint256& hash, const InstantSendLock& islock) EXCLUSIVE_LOCKS_REQUIRED(!cs_db);
92+
void WriteNewInstantSendLock(const uint256& hash, const InstantSendLockPtr& islock) EXCLUSIVE_LOCKS_REQUIRED(!cs_db);
9293
/**
9394
* This method updates a DB entry for an InstantSend Lock from being not included in a block to being included in a block
9495
* @param hash The hash of the InstantSend Lock

0 commit comments

Comments
 (0)