static async Task ReadBlockHashPipeAsync(PipeReader reader) { // Read Bitcoin block ids from a PipeReader while (_zmqRunning) { var rr = await reader.ReadAsync(); var buf = rr.Buffer; var blockId = new KzUInt256(); buf.ToSpan().CopyTo(blockId.Span); reader.AdvanceTo(buf.GetPosition(32)); KzH.WriteLine($"BlockId parsed id={blockId.ToHex()}"); } }
static async Task ReadTxPipeAsync(PipeReader reader) { var tx = new KzTransaction(); // Read Bitcoin transactions from a PipeReader while (_zmqRunning) { var rr = await reader.ReadAsync(); var consumed = 0L; var buf = rr.Buffer; if (tx.TryReadTransaction(ref buf)) { reader.AdvanceTo(buf.GetPosition(consumed)); KzH.WriteLine($"Tx parsed id={tx.TxId.ToHex()}"); } else { reader.AdvanceTo(buf.Start, buf.End); KzH.WriteLine($"Tx parse failed"); } } }
public static async Task MainZmq(string[] args) { var txhashpipe = new Pipe(); var txhashreadingtask = ReadTxHashPipeAsync(txhashpipe.Reader); var txpipe = new Pipe(); var txreadingtask = ReadTxPipeAsync(txpipe.Reader); var blockhashpipe = new Pipe(); var blockhashreadingtask = ReadBlockHashPipeAsync(blockhashpipe.Reader); var blockpipe = new Pipe(); var blockreadingtask = ReadBlockPipeAsync(blockpipe.Reader); try { using (var sub = new SubscriberSocket()) { sub.Options.ReceiveHighWatermark = 1000; sub.Connect(KzH.S.BitcoinSvZmqAddress); //sub.Subscribe("hashtx"); //sub.Subscribe("rawtx"); sub.Subscribe("hashblock"); //sub.Subscribe("rawblock"); while (_zmqRunning) { var mm = sub.ReceiveMultipartMessage(); var ch = mm[0].ConvertToString(); if (ch == "hashtx" || ch == "rawtx" || mm.FrameCount == 3) { var bytes = mm[1].Buffer; var count = BitConverter.ToUInt32(mm[2].Buffer); //KzH.WriteLine($"{ch} {count} {bytes.Length}"); switch (ch) { case "hashtx": { var w = txhashpipe.Writer; w.Write(bytes); // 32 bytes transaction ID // count is the transaction number in the mempool. await w.FlushAsync(); } break; case "rawtx": { var w = txpipe.Writer; w.Write(bytes); await w.FlushAsync(); } break; case "hashblock": { var w = blockhashpipe.Writer; w.Write(bytes); await w.FlushAsync(); } break; case "rawblock": { var w = blockpipe.Writer; w.Write(bytes); await w.FlushAsync(); } break; default: break; } } else { //KzH.WriteLine($"{ch}"); } } } } catch (Exception e) { KzH.WriteLine(e.Message); } //await Task.WhenAll(txreadingtask, blockreadingtask); }