void AttachedNode_MessageReceived(Node node, IncomingMessage message) { if (!PingVersion()) { return; } message.IfPayloadIs <PingPayload>(ping => { if (Mode.HasFlag(PingPongMode.RespondPong)) { node.SendMessageAsync(new PongPayload() { Nonce = ping.Nonce }); } }); message.IfPayloadIs <PongPayload>(pong => { if (Mode.HasFlag(PingPongMode.SendPing) && _CurrentPing != null && _CurrentPing.Nonce == pong.Nonce) { Latency = DateTimeOffset.UtcNow - _DateSent; ClearCurrentPing(); } }); }
void AttachedNode_MessageReceived(Node node, IncomingMessage message) { if ((Mode & AddressManagerBehaviorMode.Advertize) != 0) { message.IfPayloadIs <GetAddrPayload>(getaddr => { node.SendMessageAsync(new AddrPayload(AddressManager.GetAddr().Take(1000).ToArray())); }); } if ((Mode & AddressManagerBehaviorMode.Discover) != 0) { message.IfPayloadIs <AddrPayload>(addr => { AddressManager.Add(addr.Addresses, node.RemoteSocketAddress); }); } }
void AttachedNode_MessageReceived(Node node, IncomingMessage message) { message.IfPayloadIs <PongPayload>(pong => { var tx = GetBlock(pong.Nonce, true); if (tx != null) { tx.State = BroadcastState.Accepted; Types.Block unused; if (_BlockBroadcastHub.BroadcastedBlock.TryRemove(GetHash(tx.Block), out unused)) { _BlockBroadcastHub.OnBlockBroadcasted(tx.Block); } } }); }
void AttachedNode_MessageReceived(Node node, IncomingMessage message) { //var filterload = message.Message.Payload as FilterLoadPayload; //if (filterload != null) //{ // _Filter = filterload.Object; //} //var filteradd = message.Message.Payload as FilterAddPayload; //if (filteradd != null) //{ // _Filter.Insert(filteradd.Data); //} //var getdata = message.Message.Payload as GetDataPayload; //if (getdata != null) //{ // foreach (var inv in getdata.Inventory) // { // if (inv.Type == InventoryType.MSG_FILTERED_BLOCK && _Filter != null) // { // var merkle = new MerkleBlock(_Blocks[inv.Hash], _Filter); // AttachedNode.SendMessageAsync(new MerkleBlockPayload(merkle)); // foreach (var tx in merkle.PartialMerkleTree.GetMatchedTransactions()) // { // if (_Known.TryAdd(tx, tx)) // { // AttachedNode.SendMessageAsync(new InvPayload(InventoryType.MSG_TX, tx)); // } // } // } // var found = FindTransaction(inv.Hash); // if (inv.Type == InventoryType.MSG_TX && found != null) // AttachedNode.SendMessageAsync(new TxPayload(found)); // } //} //var mempool = message.Message.Payload as MempoolPayload; //if (mempool != null) //{ // foreach (var tx in _Builder.Mempool) // { // BroadcastCore(tx.Value); // } //} message.IfPayloadIs <InvPayload>(invPayload => { var list = new List <InventoryVector>(); foreach (var item in invPayload.Where(i => i.Type == InventoryType.MSG_TX)) { var tx = new GetTxAction() { TxHash = item.Hash }.Publish().Result; if (tx == null) { list.Add(item); } } node.SendMessageAsync(new GetDataPayload(list.ToArray())); }); message.IfPayloadIs <GetDataPayload>(getData => { foreach (var inventory in getData.Inventory.Where(i => i.Type == InventoryType.MSG_TX)) { var tx = new GetTxAction() { TxHash = inventory.Hash }.Publish().Result; if (tx != null) { _BroadcastHub.BroadcastTransactionAsync(tx); } } }); message.IfPayloadIs <Types.Transaction>(tx => { switch (new HandleTransactionAction() { Tx = tx }.Publish().Result) { case BlockChain.BlockChain.TxResultEnum.Accepted: foreach (var other in Nodes) { if (other != AttachedNode && other.State == NodeState.HandShaked) { other.SendMessageAsync(new InvPayload(tx)); } } break; case BlockChain.BlockChain.TxResultEnum.Invalid: //todo: TBD ban peer / reject node.SendMessageAsync(new RejectPayload() { Hash = GetHash(tx), Code = RejectCode.INVALID, Message = "tx" }); break; case BlockChain.BlockChain.TxResultEnum.Orphan: case BlockChain.BlockChain.TxResultEnum.InactiveContract: case BlockChain.BlockChain.TxResultEnum.DoubleSpend: case BlockChain.BlockChain.TxResultEnum.Known: break; } }); }
void AttachedNode_MessageReceived(Node node, IncomingMessage message) { message.IfPayloadIs <Types.Block>(async bk => { var result = await new HandleBlockAction(bk).Publish(); switch (result.BkResultEnum) { case BlockChain.BlockVerificationHelper.BkResultEnum.Accepted: foreach (var other in Nodes) { if (other != AttachedNode && other.State == NodeState.HandShaked) { other.SendMessageAsync(bk); } } break; case BlockChain.BlockVerificationHelper.BkResultEnum.AcceptedOrphan: StatusMessageProducer.LastOrphan = bk.header.blockNumber; node.SendMessageAsync(new GetDataPayload(new InventoryVector[] { new InventoryVector(InventoryType.MSG_BLOCK, result.MissingParent) })); break; case BlockChain.BlockVerificationHelper.BkResultEnum.Rejected: if (result.MissingParent != null) { node.SendMessageAsync(new GetDataPayload(new InventoryVector[] { new InventoryVector(InventoryType.MSG_BLOCK, result.MissingParent) })); } //TODO: refine possible state (don't reject blocks that were requested by GetTip; reply with DUPLICATE instead of INVALID, ...) node.SendMessageAsync(new RejectPayload() { Hash = Consensus.Merkle.blockHeaderHasher.Invoke(bk.header), Code = RejectCode.INVALID, Message = "bk" }); break; } }); message.IfPayloadIs <GetTipPayload>(getTip => { var tip = _BlockChain.Tip; if (tip != null) { var bk = new GetBlockAction() { BkHash = tip.Key }.Publish().Result; if (bk != null) { NodeServerTrace.Information("Sending tip: " + tip.Value.header.blockNumber); node.SendMessageAsync(bk); } else { NodeServerTrace.Information("Missing or invalid tip block requested"); } } else { NodeServerTrace.Information("No tip to send"); } }); message.IfPayloadIs <GetDataPayload>(getData => { foreach (var inventory in getData.Inventory.Where(i => i.Type == InventoryType.MSG_BLOCK)) { var bk = new GetBlockAction() { BkHash = inventory.Hash }.Publish().Result; if (bk != null) { NodeServerTrace.Information("Sending block: " + bk.header.blockNumber); node.SendMessageAsync(bk); } else { NodeServerTrace.Information("Missing or invalid block requested"); } } }); }
void AttachedNode_MessageReceived(Node node, IncomingMessage message) { message.IfPayloadIs <InvPayload>(invPayload => { foreach (var hash in invPayload.Where(i => i.Type == InventoryType.MSG_TX).Select(i => i.Hash)) { var tx = GetTransaction(hash, true); if (tx != null) { tx.State = BroadcastState.Accepted; } Types.Transaction unused; if (_BroadcastHub.BroadcastedTransaction.TryRemove(hash, out unused)) { _BroadcastHub.OnTransactionBroadcasted(tx.Transaction); } } }); message.IfPayloadIs <RejectPayload>(reject => { if (reject.Message == "tx") { var tx = GetTransaction(reject.Hash, true); if (tx != null) { tx.State = BroadcastState.Rejected; } Types.Transaction tx2; if (_BroadcastHub.BroadcastedTransaction.TryRemove(reject.Hash, out tx2)) { _BroadcastHub.OnTransactionRejected(tx2, reject); } } }); message.IfPayloadIs <GetDataPayload>(getData => { foreach (var inventory in getData.Inventory.Where(i => i.Type == InventoryType.MSG_TX)) { var tx = GetTransaction(inventory.Hash, false); //if (tx == null) //{ // tx = _BlockChain.GetTransaction(inventory.Hash); //} if (tx != null) { tx.State = BroadcastState.Broadcasted; var ping = new PingPayload(); tx.PingValue = ping.Nonce; _PingToTransaction.TryAdd(tx.PingValue, tx); node.SendMessageAsync(tx.Transaction); node.SendMessageAsync(ping); } } }); message.IfPayloadIs <PongPayload>(pong => { var tx = GetTransaction(pong.Nonce, true); if (tx != null) { tx.State = BroadcastState.Accepted; Types.Transaction unused; if (_BroadcastHub.BroadcastedTransaction.TryRemove(GetHash(tx.Transaction), out unused)) { _BroadcastHub.OnTransactionBroadcasted(tx.Transaction); } } }); }