Skip to content

Commit 7e0a3f8

Browse files
committed
refactor: move masternode mode logic to chainlock/signer.{cpp,h}
Review with `git log -p -n1 --color-moved=dimmed_zebra`.
1 parent 5663eac commit 7e0a3f8

File tree

3 files changed

+234
-222
lines changed

3 files changed

+234
-222
lines changed

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ libbitcoin_node_a_SOURCES = \
457457
chain.cpp \
458458
chainlock/chainlock.cpp \
459459
chainlock/clsig.cpp \
460+
chainlock/signing.cpp \
460461
coinjoin/coinjoin.cpp \
461462
coinjoin/context.cpp \
462463
coinjoin/server.cpp \

src/chainlock/chainlock.cpp

Lines changed: 3 additions & 222 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include <chain.h>
88
#include <chainparams.h>
99
#include <consensus/validation.h>
10-
#include <node/blockstorage.h>
1110
#include <node/interface_ui.h>
1211
#include <scheduler.h>
1312
#include <txmempool.h>
@@ -23,23 +22,15 @@
2322
#include <spork.h>
2423
#include <stats/client.h>
2524

26-
using node::ReadBlockFromDisk;
27-
2825
// Forward declaration to break dependency over node/transaction.h
29-
namespace node
30-
{
26+
namespace node {
3127
CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool,
3228
const uint256& hash, const Consensus::Params& consensusParams, uint256& hashBlock);
3329
} // namespace node
34-
using node::GetTransaction;
3530

36-
static bool ChainLocksSigningEnabled(const CSporkManager& sporkman)
37-
{
38-
return sporkman.GetSporkValue(SPORK_19_CHAINLOCKS_ENABLED) == 0;
39-
}
31+
using node::GetTransaction;
4032

41-
namespace llmq
42-
{
33+
namespace llmq {
4334
CChainLocksHandler::CChainLocksHandler(CChainState& chainstate, CQuorumManager& _qman, CSigningManager& _sigman,
4435
CSigSharesManager& _shareman, CSporkManager& sporkman, CTxMemPool& _mempool,
4536
const CMasternodeSync& mn_sync, bool is_masternode) :
@@ -226,122 +217,6 @@ void CChainLocksHandler::CheckActiveState()
226217
}
227218
}
228219

229-
void CChainLocksHandler::TrySignChainTip(const llmq::CInstantSendManager& isman)
230-
{
231-
Cleanup();
232-
233-
if (!m_is_masternode) {
234-
return;
235-
}
236-
237-
if (!m_mn_sync.IsBlockchainSynced()) {
238-
return;
239-
}
240-
241-
if (!isEnabled) {
242-
return;
243-
}
244-
245-
if (!ChainLocksSigningEnabled(spork_manager)) {
246-
return;
247-
}
248-
249-
const CBlockIndex* pindex = WITH_LOCK(::cs_main, return m_chainstate.m_chain.Tip());
250-
251-
if (pindex->pprev == nullptr) {
252-
return;
253-
}
254-
255-
// DIP8 defines a process called "Signing attempts" which should run before the CLSIG is finalized
256-
// To simplify the initial implementation, we skip this process and directly try to create a CLSIG
257-
// This will fail when multiple blocks compete, but we accept this for the initial implementation.
258-
// Later, we'll add the multiple attempts process.
259-
260-
{
261-
LOCK(cs);
262-
263-
if (pindex->nHeight == lastSignedHeight) {
264-
// already signed this one
265-
return;
266-
}
267-
268-
if (bestChainLock.getHeight() >= pindex->nHeight) {
269-
// already got the same CLSIG or a better one
270-
return;
271-
}
272-
273-
if (InternalHasConflictingChainLock(pindex->nHeight, pindex->GetBlockHash())) {
274-
// don't sign if another conflicting CLSIG is already present. EnforceBestChainLock will later enforce
275-
// the correct chain.
276-
return;
277-
}
278-
}
279-
280-
LogPrint(BCLog::CHAINLOCKS, "CChainLocksHandler::%s -- trying to sign %s, height=%d\n", __func__, pindex->GetBlockHash().ToString(), pindex->nHeight);
281-
282-
// When the new IX system is activated, we only try to ChainLock blocks which include safe transactions. A TX is
283-
// considered safe when it is islocked or at least known since 10 minutes (from mempool or block). These checks are
284-
// performed for the tip (which we try to sign) and the previous 5 blocks. If a ChainLocked block is found on the
285-
// way down, we consider all TXs to be safe.
286-
if (isman.IsInstantSendEnabled() && isman.RejectConflictingBlocks()) {
287-
const auto* pindexWalk = pindex;
288-
while (pindexWalk != nullptr) {
289-
if (pindex->nHeight - pindexWalk->nHeight > 5) {
290-
// no need to check further down, 6 confs is safe to assume that TXs below this height won't be
291-
// islocked anymore if they aren't already
292-
LogPrint(BCLog::CHAINLOCKS, "CChainLocksHandler::%s -- tip and previous 5 blocks all safe\n", __func__);
293-
break;
294-
}
295-
if (HasChainLock(pindexWalk->nHeight, pindexWalk->GetBlockHash())) {
296-
// we don't care about islocks for TXs that are ChainLocked already
297-
LogPrint(BCLog::CHAINLOCKS, "CChainLocksHandler::%s -- chainlock at height %d\n", __func__, pindexWalk->nHeight);
298-
break;
299-
}
300-
301-
auto txids = GetBlockTxs(pindexWalk->GetBlockHash());
302-
if (!txids) {
303-
pindexWalk = pindexWalk->pprev;
304-
continue;
305-
}
306-
307-
for (const auto& txid : *txids) {
308-
int64_t txAge = 0;
309-
{
310-
LOCK(cs);
311-
auto it = txFirstSeenTime.find(txid);
312-
if (it != txFirstSeenTime.end()) {
313-
txAge = GetTime<std::chrono::seconds>().count() - it->second;
314-
}
315-
}
316-
317-
if (txAge < WAIT_FOR_ISLOCK_TIMEOUT && !isman.IsLocked(txid)) {
318-
LogPrint(BCLog::CHAINLOCKS, "CChainLocksHandler::%s -- not signing block %s due to TX %s not being islocked and not old enough. age=%d\n", __func__,
319-
pindexWalk->GetBlockHash().ToString(), txid.ToString(), txAge);
320-
return;
321-
}
322-
}
323-
324-
pindexWalk = pindexWalk->pprev;
325-
}
326-
}
327-
328-
uint256 requestId = ::SerializeHash(std::make_pair(chainlock::CLSIG_REQUESTID_PREFIX, pindex->nHeight));
329-
uint256 msgHash = pindex->GetBlockHash();
330-
331-
{
332-
LOCK(cs);
333-
if (bestChainLock.getHeight() >= pindex->nHeight) {
334-
// might have happened while we didn't hold cs
335-
return;
336-
}
337-
lastSignedHeight = pindex->nHeight;
338-
lastSignedRequestId = requestId;
339-
lastSignedMsgHash = msgHash;
340-
}
341-
342-
sigman.AsyncSignIfMember(Params().GetConsensus().llmqTypeChainLocks, shareman, requestId, msgHash);
343-
}
344-
345220
void CChainLocksHandler::TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime)
346221
{
347222
if (tx->IsCoinBase() || tx->vin.empty()) {
@@ -391,55 +266,6 @@ void CChainLocksHandler::BlockDisconnected(const std::shared_ptr<const CBlock>&
391266
blockTxs.erase(pindexDisconnected->GetBlockHash());
392267
}
393268

394-
CChainLocksHandler::BlockTxs::mapped_type CChainLocksHandler::GetBlockTxs(const uint256& blockHash)
395-
{
396-
AssertLockNotHeld(cs);
397-
AssertLockNotHeld(cs_main);
398-
399-
CChainLocksHandler::BlockTxs::mapped_type ret;
400-
401-
{
402-
LOCK(cs);
403-
auto it = blockTxs.find(blockHash);
404-
if (it != blockTxs.end()) {
405-
ret = it->second;
406-
}
407-
}
408-
if (!ret) {
409-
// This should only happen when freshly started.
410-
// If running for some time, SyncTransaction should have been called before which fills blockTxs.
411-
LogPrint(BCLog::CHAINLOCKS, "CChainLocksHandler::%s -- blockTxs for %s not found. Trying ReadBlockFromDisk\n", __func__,
412-
blockHash.ToString());
413-
414-
uint32_t blockTime;
415-
{
416-
LOCK(::cs_main);
417-
const auto* pindex = m_chainstate.m_blockman.LookupBlockIndex(blockHash);
418-
CBlock block;
419-
if (!ReadBlockFromDisk(block, pindex, Params().GetConsensus())) {
420-
return nullptr;
421-
}
422-
423-
ret = std::make_shared<std::unordered_set<uint256, StaticSaltedHasher>>();
424-
for (const auto& tx : block.vtx) {
425-
if (tx->IsCoinBase() || tx->vin.empty()) {
426-
continue;
427-
}
428-
ret->emplace(tx->GetHash());
429-
}
430-
431-
blockTime = block.nTime;
432-
}
433-
434-
LOCK(cs);
435-
blockTxs.emplace(blockHash, ret);
436-
for (const auto& txid : *ret) {
437-
txFirstSeenTime.emplace(txid, blockTime);
438-
}
439-
}
440-
return ret;
441-
}
442-
443269
bool CChainLocksHandler::IsTxSafeForMining(const uint256& txid) const
444270
{
445271
int64_t txAge = 0;
@@ -511,38 +337,12 @@ void CChainLocksHandler::EnforceBestChainLock()
511337
::g_stats_client->gauge("chainlocks.blockHeight", clsig->getHeight(), 1.0f);
512338
}
513339

514-
MessageProcessingResult CChainLocksHandler::HandleNewRecoveredSig(const llmq::CRecoveredSig& recoveredSig)
515-
{
516-
if (!isEnabled) {
517-
return {};
518-
}
519-
520-
chainlock::ChainLockSig clsig;
521-
{
522-
LOCK(cs);
523-
524-
if (recoveredSig.getId() != lastSignedRequestId || recoveredSig.getMsgHash() != lastSignedMsgHash) {
525-
// this is not what we signed, so lets not create a CLSIG for it
526-
return {};
527-
}
528-
if (bestChainLock.getHeight() >= lastSignedHeight) {
529-
// already got the same or a better CLSIG through the CLSIG message
530-
return {};
531-
}
532-
533-
534-
clsig = chainlock::ChainLockSig(lastSignedHeight, lastSignedMsgHash, recoveredSig.sig.Get());
535-
}
536-
return ProcessNewChainLock(-1, clsig, ::SerializeHash(clsig));
537-
}
538-
539340
bool CChainLocksHandler::HasChainLock(int nHeight, const uint256& blockHash) const
540341
{
541342
LOCK(cs);
542343
return InternalHasChainLock(nHeight, blockHash);
543344
}
544345

545-
546346
VerifyRecSigStatus CChainLocksHandler::VerifyChainLock(const chainlock::ChainLockSig& clsig) const
547347
{
548348
const auto llmqType = Params().GetConsensus().llmqTypeChainLocks;
@@ -656,25 +456,6 @@ void CChainLocksHandler::Cleanup()
656456
}
657457
}
658458

659-
std::vector<std::shared_ptr<std::unordered_set<uint256, StaticSaltedHasher>>> CChainLocksHandler::CleanupSigner()
660-
{
661-
AssertLockHeld(cs);
662-
std::vector<std::shared_ptr<std::unordered_set<uint256, StaticSaltedHasher>>> removed;
663-
LOCK(::cs_main);
664-
for (auto it = blockTxs.begin(); it != blockTxs.end(); ) {
665-
const auto* pindex = m_chainstate.m_blockman.LookupBlockIndex(it->first);
666-
if (InternalHasChainLock(pindex->nHeight, pindex->GetBlockHash())) {
667-
removed.push_back(it->second);
668-
it = blockTxs.erase(it);
669-
} else if (InternalHasConflictingChainLock(pindex->nHeight, pindex->GetBlockHash())) {
670-
it = blockTxs.erase(it);
671-
} else {
672-
++it;
673-
}
674-
}
675-
return removed;
676-
}
677-
678459
bool AreChainLocksEnabled(const CSporkManager& sporkman)
679460
{
680461
return sporkman.IsSporkActive(SPORK_19_CHAINLOCKS_ENABLED);

0 commit comments

Comments
 (0)