@@ -1895,6 +1895,11 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
18951895 for (unsigned int i = 0 ; i < block.vtx .size (); i++)
18961896 g_signals.SyncTransaction (block.GetTxHash (i), block.vtx [i], &block);
18971897
1898+ // Watch for changes to the previous coinbase transaction.
1899+ static uint256 hashPrevBestCoinBase;
1900+ g_signals.UpdatedTransaction (hashPrevBestCoinBase);
1901+ hashPrevBestCoinBase = block.GetTxHash (0 );
1902+
18981903 return true ;
18991904}
19001905
@@ -2082,6 +2087,7 @@ static CBlockIndex* FindMostWorkChain() {
20822087// Try to make some progress towards making pindexMostWork the active block.
20832088static bool ActivateBestChainStep (CValidationState &state, CBlockIndex *pindexMostWork) {
20842089 AssertLockHeld (cs_main);
2090+ bool fInvalidFound = false ;
20852091 CBlockIndex *pindexOldTip = chainActive.Tip ();
20862092 CBlockIndex *pindexFork = chainActive.FindFork (pindexMostWork);
20872093
@@ -2107,6 +2113,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
21072113 if (!state.CorruptionPossible ())
21082114 InvalidChainFound (vpindexToConnect.back ());
21092115 state = CValidationState ();
2116+ fInvalidFound = true ;
21102117 break ;
21112118 } else {
21122119 // A system error occurred (disk space, database error, ...).
@@ -2120,37 +2127,59 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
21202127 }
21212128 }
21222129
2123- if (chainActive. Tip () != pindexOldTip) {
2124- std::string strCmd = GetArg ( " -blocknotify " , " " );
2125- if (! IsInitialBlockDownload () && !strCmd. empty ())
2126- {
2127- boost::replace_all (strCmd, " %s " , chainActive. Tip ()-> GetBlockHash (). GetHex () );
2128- boost::thread t (runCommand, strCmd); // thread runs free
2129- }
2130- }
2130+ // Callbacks/notifications for a new best chain.
2131+ if ( fInvalidFound )
2132+ CheckForkWarningConditionsOnNewFork (vpindexToConnect. back ());
2133+ else
2134+ CheckForkWarningConditions ( );
2135+
2136+ if (!pblocktree-> Flush ())
2137+ return state. Abort ( _ ( " Failed to sync block index " ));
21312138
21322139 return true ;
21332140}
21342141
21352142bool ActivateBestChain (CValidationState &state) {
2143+ CBlockIndex *pindexNewTip = NULL ;
2144+ CBlockIndex *pindexMostWork = NULL ;
21362145 do {
21372146 boost::this_thread::interruption_point ();
21382147
2139- LOCK (cs_main);
2148+ bool fInitialDownload ;
2149+ {
2150+ LOCK (cs_main);
2151+ pindexMostWork = FindMostWorkChain ();
21402152
2141- // Check whether we're done (this could be avoided after the first run,
2142- // but that's not worth optimizing.
2143- CBlockIndex *pindexMostWork = FindMostWorkChain ();
2144- if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip ())
2145- return true ;
2153+ // Whether we have anything to do at all.
2154+ if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip ())
2155+ return true ;
21462156
2147- if (!ActivateBestChainStep (state, pindexMostWork))
2148- return false ;
2157+ if (!ActivateBestChainStep (state, pindexMostWork))
2158+ return false ;
21492159
2150- // Check whether we're done now.
2151- if (pindexMostWork == chainActive.Tip ())
2152- return true ;
2153- } while (true );
2160+ pindexNewTip = chainActive.Tip ();
2161+ fInitialDownload = IsInitialBlockDownload ();
2162+ }
2163+ // When we reach this point, we switched to a new tip (stored in pindexNewTip).
2164+
2165+ // Notifications/callbacks that can run without cs_main
2166+ if (!fInitialDownload ) {
2167+ uint256 hashNewTip = pindexNewTip->GetBlockHash ();
2168+ // Relay inventory, but don't relay old inventory during initial block download.
2169+ int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate ();
2170+ LOCK (cs_vNodes);
2171+ BOOST_FOREACH (CNode* pnode, vNodes)
2172+ if (chainActive.Height () > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
2173+ pnode->PushInventory (CInv (MSG_BLOCK, hashNewTip));
2174+
2175+ std::string strCmd = GetArg (" -blocknotify" , " " );
2176+ if (!strCmd.empty ()) {
2177+ boost::replace_all (strCmd, " %s" , hashNewTip.GetHex ());
2178+ boost::thread t (runCommand, strCmd); // thread runs free
2179+ }
2180+ }
2181+ uiInterface.NotifyBlocksChanged ();
2182+ } while (pindexMostWork != chainActive.Tip ());
21542183
21552184 return true ;
21562185}
@@ -2215,26 +2244,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
22152244 return state.Abort (_ (" Failed to write block index" ));
22162245
22172246 // New best?
2218- if (!ActivateBestChain (state))
2219- return false ;
2220-
2221- LOCK (cs_main);
2222- if (pindexNew == chainActive.Tip ())
2223- {
2224- // Clear fork warning if its no longer applicable
2225- CheckForkWarningConditions ();
2226- // Notify UI to display prev block's coinbase if it was ours
2227- static uint256 hashPrevBestCoinBase;
2228- g_signals.UpdatedTransaction (hashPrevBestCoinBase);
2229- hashPrevBestCoinBase = block.GetTxHash (0 );
2230- } else
2231- CheckForkWarningConditionsOnNewFork (pindexNew);
2232-
2233- if (!pblocktree->Flush ())
2234- return state.Abort (_ (" Failed to sync block index" ));
2235-
2236- uiInterface.NotifyBlocksChanged ();
2237- return true ;
2247+ return ActivateBestChain (state);
22382248}
22392249
22402250
@@ -2554,16 +2564,6 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
25542564 return state.Abort (_ (" System error: " ) + e.what ());
25552565 }
25562566
2557- // Relay inventory, but don't relay old inventory during initial block download
2558- int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate ();
2559- if (chainActive.Tip ()->GetBlockHash () == hash)
2560- {
2561- LOCK (cs_vNodes);
2562- BOOST_FOREACH (CNode* pnode, vNodes)
2563- if (chainActive.Height () > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
2564- pnode->PushInventory (CInv (MSG_BLOCK, hash));
2565- }
2566-
25672567 return true ;
25682568}
25692569
0 commit comments