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); }
public BlockChain(string dbName, byte[] genesisBlockHash) { memPool = new MemPool(); UTXOStore = new UTXOStore(); ActiveContractSet = new ActiveContractSet(); BlockStore = new BlockStore(); BlockNumberDifficulties = new BlockNumberDifficulties(); ChainTip = new ChainTip(); Timestamps = new BlockTimestamps(); GenesisBlockHash = genesisBlockHash; _DBContext = new DBContext(dbName); OwnResource(_DBContext); //var listener = new EventLoopMessageListener<QueueAction>(HandleQueueAction, "BlockChain listener"); //OwnResource(MessageProducer<QueueAction>.Instance.AddMessageListener(listener)); var buffer = new BufferBlock <QueueAction>(); QueueAction.Target = buffer; using (var dbTx = _DBContext.GetTransactionContext()) { var chainTip = ChainTip.Context(dbTx).Value; //TODO: check if makred as main? Tip = chainTip == null ? null : BlockStore.GetBlock(dbTx, chainTip); if (Tip != null) { BlockChainTrace.Information("Tip's block number is " + Tip.Value.header.blockNumber); //Try to validate orphans of tip, if any. this would be the case when a sync action was interrupted BlockStore.Orphans(dbTx, Tip.Key).ToList().ForEach(t => new HandleBlockAction(t.Key, t.Value, true).Publish()); } else { BlockChainTrace.Information("No tip."); } InitBlockTimestamps(dbTx); } var consumer = ConsumeAsync(buffer); }