/// <exception cref="BlockStoreException"/>
/// <exception cref="VerificationException"/>
private void ConnectBlock(StoredBlock newStoredBlock, StoredBlock storedPrev, IDictionary <Wallet, List <Transaction> > newTransactions)
{
if (storedPrev.Equals(_chainHead))
{
// This block connects to the best known block, it is a normal continuation of the system.
ChainHead = newStoredBlock;
_log.DebugFormat("Chain is now {0} blocks high", _chainHead.Height);
if (newTransactions != null)
{
SendTransactionsToWallet(newStoredBlock, NewBlockType.BestChain, newTransactions);
}
}
else
{
// This block connects to somewhere other than the top of the best known chain. We treat these differently.
//
// Note that we send the transactions to the wallet FIRST, even if we're about to re-organize this block
// to become the new best chain head. This simplifies handling of the re-org in the Wallet class.
var haveNewBestChain = newStoredBlock.MoreWorkThan(_chainHead);
if (haveNewBestChain)
{
_log.Info("Block is causing a re-organize");
}
else
{
var splitPoint = FindSplit(newStoredBlock, _chainHead);
var splitPointHash = splitPoint != null ? splitPoint.Header.HashAsString : "?";
_log.InfoFormat("Block forks the chain at {0}, but it did not cause a reorganize:{1}{2}",
splitPointHash, Environment.NewLine, newStoredBlock);
}
// We may not have any transactions if we received only a header. That never happens today but will in
// future when GetHeaders is used as an optimization.
if (newTransactions != null)
{
SendTransactionsToWallet(newStoredBlock, NewBlockType.SideChain, newTransactions);
}
if (haveNewBestChain)
{
HandleNewBestChain(newStoredBlock);
}
}
}