From dd21d046f5bc3daaa13242963e9a0f6a679e24e7 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 5 Apr 2019 13:37:25 +0200 Subject: [PATCH 1/4] Avoid unnecessary calls to parentIt->GetKey --- src/dbwrapper.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 94db323dc..1531a9425 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -464,7 +464,14 @@ public: } if (curIsParent) { - return parentIt->GetKey(key); + try { + // TODO try to avoid this copy (we need a stream that allows reading from external buffers) + CDataStream ssKey = parentKey; + ssKey >> key; + } catch (const std::exception&) { + return false; + } + return true; } else { try { // TODO try to avoid this copy (we need a stream that allows reading from external buffers) @@ -482,7 +489,7 @@ public: return CDataStream(SER_DISK, CLIENT_VERSION); } if (curIsParent) { - return parentIt->GetKey(); + return parentKey; } else { return transactionIt->first; } From 53656b3e82f24a802da821c52f62987373565bd9 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 5 Apr 2019 13:37:58 +0200 Subject: [PATCH 2/4] Compare CDataStream internal vector with unsigned comparison --- src/dbwrapper.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 1531a9425..b4bd0fdbc 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -553,7 +553,9 @@ protected: struct DataStreamCmp { static bool less(const CDataStream& a, const CDataStream& b) { - return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); + return std::lexicographical_compare( + (const uint8_t*)a.data(), (const uint8_t*)a.data() + a.size(), + (const uint8_t*)b.data(), (const uint8_t*)b.data() + b.size()); } bool operator()(const CDataStream& a, const CDataStream& b) const { return less(a, b); From 4b9f6cd3a9aed783c08e1c1961e6a5fdd24abb75 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 5 Apr 2019 13:39:29 +0200 Subject: [PATCH 3/4] Use big endian inversed height in BuildInversedHeightKey Otherwise keys are not properly sorted. --- src/llmq/quorums_blockprocessor.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/llmq/quorums_blockprocessor.cpp b/src/llmq/quorums_blockprocessor.cpp index 209f64cb9..793ab1ed3 100644 --- a/src/llmq/quorums_blockprocessor.cpp +++ b/src/llmq/quorums_blockprocessor.cpp @@ -25,7 +25,7 @@ CQuorumBlockProcessor* quorumBlockProcessor; static const std::string DB_MINED_COMMITMENT = "q_mc"; static const std::string DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT = "q_mcih"; -static const std::string DB_BEST_BLOCK_UPGRADE = "q_bbu"; +static const std::string DB_BEST_BLOCK_UPGRADE = "q_bbu2"; void CQuorumBlockProcessor::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman) { @@ -168,9 +168,10 @@ bool CQuorumBlockProcessor::ProcessBlock(const CBlock& block, const CBlockIndex* // We store a mapping from minedHeight->quorumHeight in the DB // minedHeight is inversed so that entries are traversable in reversed order -static std::tuple BuildInversedHeightKey(Consensus::LLMQType llmqType, int nMinedHeight) +static std::tuple BuildInversedHeightKey(Consensus::LLMQType llmqType, int nMinedHeight) { - return std::make_tuple(DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT, (uint8_t)llmqType, std::numeric_limits::max() - nMinedHeight); + // nMinedHeight must be converted to big endian to make it comparable when serialized + return std::make_tuple(DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT, (uint8_t)llmqType, htobe32(std::numeric_limits::max() - nMinedHeight)); } bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockHash, const CFinalCommitment& qc, CValidationState& state) @@ -422,7 +423,7 @@ std::vector CQuorumBlockProcessor::GetMinedCommitmentsUntilB break; } - int nMinedHeight = std::numeric_limits::max() - std::get<2>(curKey); + uint32_t nMinedHeight = std::numeric_limits::max() - be32toh(std::get<2>(curKey)); if (nMinedHeight > pindex->nHeight) { break; } From 206e5a1b479dfe086663c9e54930d11f06e8d073 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 5 Apr 2019 13:40:18 +0200 Subject: [PATCH 4/4] Use big endian inversed height in CInstantSendDb --- src/llmq/quorums_instantsend.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/llmq/quorums_instantsend.cpp b/src/llmq/quorums_instantsend.cpp index 2aff53cf5..de074a41a 100644 --- a/src/llmq/quorums_instantsend.cpp +++ b/src/llmq/quorums_instantsend.cpp @@ -90,21 +90,26 @@ void CInstantSendDb::RemoveInstantSendLock(CDBBatch& batch, const uint256& hash, } } +static std::tuple BuildInversedISLockMinedKey(int nHeight, const uint256& islockHash) +{ + return std::make_tuple(std::string("is_m"), htobe32(std::numeric_limits::max() - nHeight), islockHash); +} + void CInstantSendDb::WriteInstantSendLockMined(const uint256& hash, int nHeight) { - db.Write(std::make_tuple(std::string("is_m"), std::numeric_limits::max() - nHeight, hash), true); + db.Write(BuildInversedISLockMinedKey(nHeight, hash), true); } void CInstantSendDb::RemoveInstantSendLockMined(const uint256& hash, int nHeight) { - db.Erase(std::make_tuple(std::string("is_m"), std::numeric_limits::max() - nHeight, hash)); + db.Erase(BuildInversedISLockMinedKey(nHeight, hash)); } std::unordered_map CInstantSendDb::RemoveConfirmedInstantSendLocks(int nUntilHeight) { auto it = std::unique_ptr(db.NewIterator()); - auto firstKey = std::make_tuple(std::string("is_m"), std::numeric_limits::max() - nUntilHeight, uint256()); + auto firstKey = BuildInversedISLockMinedKey(nUntilHeight, uint256()); it->Seek(firstKey); @@ -115,7 +120,7 @@ std::unordered_map CInstantSendDb::RemoveConfirmed if (!it->GetKey(curKey) || std::get<0>(curKey) != "is_m") { break; } - int nHeight = std::numeric_limits::max() - std::get<1>(curKey); + uint32_t nHeight = std::numeric_limits::max() - be32toh(std::get<1>(curKey)); if (nHeight > nUntilHeight) { break; }