|
7 | 7 | #include <chain.h> |
8 | 8 | #include <chainparams.h> |
9 | 9 | #include <consensus/validation.h> |
10 | | -#include <node/blockstorage.h> |
11 | 10 | #include <node/interface_ui.h> |
12 | 11 | #include <scheduler.h> |
13 | 12 | #include <txmempool.h> |
|
23 | 22 | #include <spork.h> |
24 | 23 | #include <stats/client.h> |
25 | 24 |
|
26 | | -using node::ReadBlockFromDisk; |
27 | | - |
28 | 25 | // Forward declaration to break dependency over node/transaction.h |
29 | | -namespace node |
30 | | -{ |
| 26 | +namespace node { |
31 | 27 | CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, |
32 | 28 | const uint256& hash, const Consensus::Params& consensusParams, uint256& hashBlock); |
33 | 29 | } // namespace node |
34 | | -using node::GetTransaction; |
35 | 30 |
|
36 | | -static bool ChainLocksSigningEnabled(const CSporkManager& sporkman) |
37 | | -{ |
38 | | - return sporkman.GetSporkValue(SPORK_19_CHAINLOCKS_ENABLED) == 0; |
39 | | -} |
| 31 | +using node::GetTransaction; |
40 | 32 |
|
41 | | -namespace llmq |
42 | | -{ |
| 33 | +namespace llmq { |
43 | 34 | CChainLocksHandler::CChainLocksHandler(CChainState& chainstate, CQuorumManager& _qman, CSigningManager& _sigman, |
44 | 35 | CSigSharesManager& _shareman, CSporkManager& sporkman, CTxMemPool& _mempool, |
45 | 36 | const CMasternodeSync& mn_sync, bool is_masternode) : |
@@ -226,122 +217,6 @@ void CChainLocksHandler::CheckActiveState() |
226 | 217 | } |
227 | 218 | } |
228 | 219 |
|
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 | | - |
345 | 220 | void CChainLocksHandler::TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime) |
346 | 221 | { |
347 | 222 | if (tx->IsCoinBase() || tx->vin.empty()) { |
@@ -391,55 +266,6 @@ void CChainLocksHandler::BlockDisconnected(const std::shared_ptr<const CBlock>& |
391 | 266 | blockTxs.erase(pindexDisconnected->GetBlockHash()); |
392 | 267 | } |
393 | 268 |
|
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 | | - |
443 | 269 | bool CChainLocksHandler::IsTxSafeForMining(const uint256& txid) const |
444 | 270 | { |
445 | 271 | int64_t txAge = 0; |
@@ -511,38 +337,12 @@ void CChainLocksHandler::EnforceBestChainLock() |
511 | 337 | ::g_stats_client->gauge("chainlocks.blockHeight", clsig->getHeight(), 1.0f); |
512 | 338 | } |
513 | 339 |
|
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 | | - |
539 | 340 | bool CChainLocksHandler::HasChainLock(int nHeight, const uint256& blockHash) const |
540 | 341 | { |
541 | 342 | LOCK(cs); |
542 | 343 | return InternalHasChainLock(nHeight, blockHash); |
543 | 344 | } |
544 | 345 |
|
545 | | - |
546 | 346 | VerifyRecSigStatus CChainLocksHandler::VerifyChainLock(const chainlock::ChainLockSig& clsig) const |
547 | 347 | { |
548 | 348 | const auto llmqType = Params().GetConsensus().llmqTypeChainLocks; |
@@ -656,25 +456,6 @@ void CChainLocksHandler::Cleanup() |
656 | 456 | } |
657 | 457 | } |
658 | 458 |
|
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 | | - |
678 | 459 | bool AreChainLocksEnabled(const CSporkManager& sporkman) |
679 | 460 | { |
680 | 461 | return sporkman.IsSporkActive(SPORK_19_CHAINLOCKS_ENABLED); |
|
0 commit comments