BkResult HandleBlock(HandleBlockAction a) { BlockVerificationHelper action = null; using (var dbTx = _DBContext.GetTransactionContext()) { action = new BlockVerificationHelper( this, dbTx, a.BkHash, a.Bk, a.IsOrphan ); switch (action.Result.BkResultEnum) { case BkResultEnum.AcceptedOrphan: dbTx.Commit(); break; case BkResultEnum.Accepted: if (action.ConfirmedTxs.Any() || action.UnconfirmedTxs.Any()) { UpdateMempool(dbTx, action.ConfirmedTxs, action.UnconfirmedTxs); } else { dbTx.Commit(); } BlockStore.Orphans(dbTx, a.BkHash).ToList().ForEach(t => new HandleBlockAction(t.Key, t.Value, true).Publish()); break; case BkResultEnum.Rejected: return(action.Result); } } //TODO: memory management issues. trying to explicitly collect DynamicMethods GC.Collect(); GC.WaitForPendingFinalizers(); action.QueueActions.ForEach(t => { if (t is MessageAction) { (t as MessageAction).Message.Publish(); } else { t.Publish(); } }); return(action.Result); }
void Reorg() { var originalTip = _BlockChain.Tip; Keyed <Types.Block> fork = null; var newMainChain = GetNewMainChainStartFromForkToLeaf(new Keyed <Types.Block>(_BkHash, _Bk), out fork); _BlockChain.ChainTip.Context(_DbTx).Value = fork.Key; _BlockChain.Tip = fork; _BlockChain.InitBlockTimestamps(_DbTx); var oldMainChain = GetOldMainChainStartFromLeafToFork(fork, originalTip.Key); foreach (var block in oldMainChain) { UndoBlock(block.Value, block.Key); } //append new chain foreach (var _bk in newMainChain) { var action = new BlockVerificationHelper( _BlockChain, _DbTx, _bk.Key, _bk.Value, false, true, ConfirmedTxs, UnconfirmedTxs, QueueActions); BlockChainTrace.Information($"new main chain bk {_bk.Value.header.blockNumber} {action.Result.BkResultEnum}", _bk.Value); if (action.Result.BkResultEnum == BkResultEnum.Rejected) { _BlockChain.ChainTip.Context(_DbTx).Value = originalTip.Key; _BlockChain.Tip = originalTip; _BlockChain.InitBlockTimestamps(_DbTx); BlockChainTrace.Information("reorganization undo", _bk.Value); Result = new BkResult(BkResultEnum.Rejected); return; } } }