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

feat: process/accept CbTx CL as new CL #5779

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/evo/cbtx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPre
return true;
}

bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindex, const llmq::CChainLocksHandler& chainlock_handler, BlockValidationState& state)
bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindex, llmq::CChainLocksHandler& chainlock_handler, BlockValidationState& state)
{
if (block.vtx[0]->nType != TRANSACTION_COINBASE) {
return true;
Expand Down Expand Up @@ -365,9 +365,11 @@ bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindex, cons
return true;
}
uint256 curBlockCoinbaseCLBlockHash = pindex->GetAncestor(curBlockCoinbaseCLHeight)->GetBlockHash();
if (!chainlock_handler.VerifyChainLock(llmq::CChainLockSig(curBlockCoinbaseCLHeight, curBlockCoinbaseCLBlockHash, cbTx.bestCLSignature))) {
llmq::CChainLockSig cbtxcl = llmq::CChainLockSig(curBlockCoinbaseCLHeight, curBlockCoinbaseCLBlockHash, cbTx.bestCLSignature);
if (!chainlock_handler.VerifyChainLock(cbtxcl)) {
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cbtx-invalid-clsig");
}
chainlock_handler.ProcessNewChainLock(-1, cbtxcl, ::SerializeHash(cbtxcl));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a couple of issues with this:

  1. A syncing node will spam the network with old clsigs because of RelayInv inside of ProcessNewChainLock.
  2. We are going to run VerifyChainLock twice in a row it seems - first here and then again inside of ProcessNewChainLock.

We should probably avoid processing any clsigs (these and p2p ones) until blockchain is synced. Pls see 93ed4e1.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we instead extract this code

{
LOCK(cs);
bestChainLockHash = hash;
bestChainLock = clsig;
if (pindex != nullptr) {
if (pindex->nHeight != clsig.getHeight()) {
// Should not happen, same as the conflict check from above.
LogPrintf("CChainLocksHandler::%s -- height of CLSIG (%s) does not match the specified block's height (%d)\n",
__func__, clsig.ToString(), pindex->nHeight);
// Note: not relaying clsig here
return;
}
bestChainLockWithKnownBlock = bestChainLock;
bestChainLockBlockIndex = pindex;
}
// else if (pindex == nullptr)
// Note: make sure to still relay clsig further.
}
to a new function and only call this function on block processing?

So avoid the re-verification and enforcement?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might work.. not sure

UdjinM6 marked this conversation as resolved.
Show resolved Hide resolved
} else if (cbTx.bestCLHeightDiff != 0) {
// Null bestCLSignature is allowed only with bestCLHeightDiff = 0
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cbtx-cldiff");
Expand Down
2 changes: 1 addition & 1 deletion src/evo/cbtx.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, const
bool CalcCbTxMerkleRootMNList(const CBlock& block, const CBlockIndex* pindexPrev, uint256& merkleRootRet, BlockValidationState& state, const CCoinsViewCache& view);
bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPrev, const llmq::CQuorumBlockProcessor& quorum_block_processor, uint256& merkleRootRet, BlockValidationState& state);

bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindexPrev, const llmq::CChainLocksHandler& chainlock_handler, BlockValidationState& state);
bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindexPrev, llmq::CChainLocksHandler& chainlock_handler, BlockValidationState& state);
bool CalcCbTxBestChainlock(const llmq::CChainLocksHandler& chainlock_handler, const CBlockIndex* pindexPrev, uint32_t& bestCLHeightDiff, CBLSSignature& bestCLSignature);

std::optional<CCbTx> GetCoinbaseTx(const CBlockIndex* pindex);
Expand Down
2 changes: 1 addition & 1 deletion src/evo/specialtxman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ static bool UndoSpecialTx(const CTransaction& tx, const CBlockIndex* pindex)
}

bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager,
llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CChainLocksHandler& chainlock_handler,
llmq::CQuorumBlockProcessor& quorum_block_processor, llmq::CChainLocksHandler& chainlock_handler,
const Consensus::Params& consensusParams, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots,
BlockValidationState& state, std::optional<MNListUpdates>& updatesRet)
{
Expand Down
2 changes: 1 addition & 1 deletion src/evo/specialtxman.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extern RecursiveMutex cs_main;
bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache& view, bool check_sigs,
TxValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager,
llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CChainLocksHandler& chainlock_handler,
llmq::CQuorumBlockProcessor& quorum_block_processor, llmq::CChainLocksHandler& chainlock_handler,
const Consensus::Params& consensusParams, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots,
BlockValidationState& state, std::optional<MNListUpdates>& updatesRet) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager,
Expand Down
5 changes: 5 additions & 0 deletions src/llmq/chainlocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ void CChainLocksHandler::ProcessMessage(const CNode& pfrom, const std::string& m

void CChainLocksHandler::ProcessNewChainLock(const NodeId from, const llmq::CChainLockSig& clsig, const uint256& hash)
{
if (!m_mn_sync.IsBlockchainSynced()) {
// too early to do anything
return;
}

CheckActiveState();

CInv clsigInv(MSG_CLSIG, hash);
Expand Down
1 change: 1 addition & 0 deletions test/functional/feature_llmq_chainlocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ def run_test(self):
self.log.info("Restart it so that it forgets all the chainlock messages from the past")
self.restart_node(0)
self.connect_nodes(0, 1)
force_finish_mnsync(self.nodes[0])
assert self.nodes[0].getbestblockhash() == good_tip
self.nodes[0].invalidateblock(good_tip)
self.log.info("Now try to reorg the chain")
Expand Down
Loading