Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement retroactive IS locking of transactions first seen in blocks instead of mempool #2770

Merged
merged 11 commits into from
Mar 19, 2019
Merged
43 changes: 38 additions & 5 deletions src/llmq/quorums_instantsend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& has
g_connman->RelayInv(inv);

RemoveMempoolConflictsForLock(hash, islock);
RetryLockMempoolTxs(islock.txid);
RetryLockTxs(islock.txid);

UpdateWalletTransaction(islock.txid, tx);
}
Expand Down Expand Up @@ -712,7 +712,7 @@ void CInstantSendManager::SyncTransaction(const CTransaction& tx, const CBlockIn
}

if (IsLocked(tx.GetHash())) {
RetryLockMempoolTxs(tx.GetHash());
RetryLockTxs(tx.GetHash());
}
}

Expand Down Expand Up @@ -759,7 +759,7 @@ void CInstantSendManager::NotifyChainLock(const CBlockIndex* pindexChainLock)
db.WriteLastChainLockBlock(pindexChainLock->GetBlockHash());
}

RetryLockMempoolTxs(uint256());
RetryLockTxs(uint256());
}

void CInstantSendManager::RemoveFinalISLock(const uint256& hash, const CInstantSendLockPtr& islock)
Expand Down Expand Up @@ -798,9 +798,9 @@ void CInstantSendManager::RemoveMempoolConflictsForLock(const uint256& hash, con
}
}

void CInstantSendManager::RetryLockMempoolTxs(const uint256& lockedParentTx)
void CInstantSendManager::RetryLockTxs(const uint256& lockedParentTx)
{
// Let's retry all mempool TXs which don't have an islock yet and where the parents got ChainLocked now
// Let's retry all unlocked TXs from mempool and and recently connected blocks

std::unordered_map<uint256, CTransactionRef> txs;

Expand All @@ -820,6 +820,39 @@ void CInstantSendManager::RetryLockMempoolTxs(const uint256& lockedParentTx)
}
}
}

uint256 lastChainLockBlock;
const CBlockIndex* pindexLastChainLockBlock = nullptr;
const CBlockIndex* pindexWalk = nullptr;
{
LOCK(cs);
lastChainLockBlock = db.GetLastChainLockBlock();
UdjinM6 marked this conversation as resolved.
Show resolved Hide resolved
}
{
LOCK(cs_main);
if (!lastChainLockBlock.IsNull()) {
pindexLastChainLockBlock = mapBlockIndex.at(lastChainLockBlock);
pindexWalk = chainActive.Tip();
}
}

while (pindexWalk && pindexWalk != pindexLastChainLockBlock) {
CBlock block;
{
LOCK(cs_main);
if (!ReadBlockFromDisk(block, pindexWalk, Params().GetConsensus())) {
pindexWalk = pindexWalk->pprev;
continue;
}
}

for (const auto& tx : block.vtx) {
txs.emplace(tx->GetHash(), tx);
}

pindexWalk = pindexWalk->pprev;
}

for (auto& p : txs) {
auto& tx = p.second;
{
Expand Down
2 changes: 1 addition & 1 deletion src/llmq/quorums_instantsend.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class CInstantSendManager : public CRecoveredSigsListener
void RemoveFinalISLock(const uint256& hash, const CInstantSendLockPtr& islock);

void RemoveMempoolConflictsForLock(const uint256& hash, const CInstantSendLock& islock);
void RetryLockMempoolTxs(const uint256& lockedParentTx);
void RetryLockTxs(const uint256& lockedParentTx);

bool AlreadyHave(const CInv& inv);
bool GetInstantSendLockByHash(const uint256& hash, CInstantSendLock& ret);
Expand Down