Fix Carrot v1 protocol TX handling for peer synchronization
Root cause: Merkle verification failures (error 659) and peer bans occurred because protocol TX was not consistently present in m_transactions[1]. Parser fix (pool_block_parser.inl): - Skip dummy transactions[0] entry when populating m_transactions - Add protocol TX computation after parsing for Carrot v1 blocks Block template fix (block_template.cpp): - Insert protocol TX at position [1] during block creation in update() - Insert protocol TX during select_mempool_transactions() get_pow_hash fix (pool_block.cpp): - Ensure protocol TX is populated before serialize_mainchain_data() The protocol TX must be at m_transactions[1] before ANY serialization occurs, otherwise sender and receiver compute different merkle roots. Tested: Multiple restart cycles with two nodes, no bans, chains stay synced.
This commit is contained in:
+28
-12
@@ -625,6 +625,8 @@ bool SideChain::add_external_block(PoolBlock& block, std::vector<hash>& missing_
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGINFO(0, "DEBUG get_pow_hash: seed=" << block.m_seed << " txinGenHeight=" << block.m_txinGenHeight);
|
||||
|
||||
if (!block.get_pow_hash(m_pool->hasher(), block.m_txinGenHeight, block.m_seed, block.m_powHash)) {
|
||||
LOGWARN(3, "add_external_block: couldn't get PoW hash for height = " << block.m_sidechainHeight << ", mainchain height " << block.m_txinGenHeight << ". Ignoring it.");
|
||||
forget_incoming_block(block);
|
||||
@@ -648,6 +650,8 @@ bool SideChain::add_external_block(PoolBlock& block, std::vector<hash>& missing_
|
||||
}
|
||||
}
|
||||
|
||||
LOGINFO(0, "DEBUG PoW check: sidechainHeight=" << block.m_sidechainHeight << " m_difficulty=" << block.m_difficulty << " m_powHash=" << block.m_powHash);
|
||||
|
||||
if (!block.m_difficulty.check_pow(block.m_powHash)) {
|
||||
LOGWARN(3,
|
||||
"add_external_block mined by " << block.m_minerWallet <<
|
||||
@@ -2491,19 +2495,26 @@ bool SideChain::consider_peer_genesis(const hash& genesis_id, uint64_t timestamp
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a genesis and peer's is older (or same timestamp but lower hash), we need to yield
|
||||
if (m_genesisDecisionMade && our_genesis_timestamp > 0) {
|
||||
const bool peer_wins = (timestamp < our_genesis_timestamp) ||
|
||||
(timestamp == our_genesis_timestamp && genesis_id < our_genesis_id);
|
||||
|
||||
if (peer_wins) {
|
||||
LOGWARN(3, "Peer has older genesis (theirs=" << timestamp
|
||||
<< " ours=" << our_genesis_timestamp << "), purging to re-sync");
|
||||
purge_sidechain();
|
||||
// Fall through to adopt peer's genesis
|
||||
// If we have a genesis and peer's is older (or same timestamp but lower hash), we need to yield
|
||||
if (m_genesisDecisionMade) {
|
||||
if (our_genesis_timestamp > 0) {
|
||||
// We have an actual genesis block - check if peer's is older
|
||||
const bool peer_wins = (timestamp < our_genesis_timestamp) ||
|
||||
(timestamp == our_genesis_timestamp && genesis_id < our_genesis_id);
|
||||
if (peer_wins) {
|
||||
LOGWARN(3, "Peer has older genesis (theirs=" << timestamp
|
||||
<< " ours=" << our_genesis_timestamp << "), purging to re-sync");
|
||||
purge_sidechain();
|
||||
// Fall through to adopt peer's genesis
|
||||
} else {
|
||||
// Our genesis is older or same, keep it
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Our genesis is older or same, keep it
|
||||
return true;
|
||||
// We decided to create our own genesis but haven't mined it yet
|
||||
// Reset and adopt peer's genesis instead
|
||||
LOGINFO(3, "Canceling own genesis creation, will adopt peer's genesis");
|
||||
m_genesisDecisionMade = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2540,6 +2551,11 @@ void SideChain::purge_sidechain()
|
||||
// Clear difficulty data
|
||||
m_difficultyData.clear();
|
||||
|
||||
{
|
||||
WriteLock diff_lock(m_curDifficultyLock);
|
||||
m_curDifficulty = m_minDifficulty;
|
||||
}
|
||||
|
||||
// Reset genesis state to allow new genesis adoption
|
||||
m_genesisDecisionMade = false;
|
||||
m_adoptedGenesisId = {};
|
||||
|
||||
Reference in New Issue
Block a user