static (bool ok, ReadOnlySequence <byte> ros) FetchBlockByHeightAndHash(int height, KzUInt256?hash, KzBlock b) { var kzrpc = KzH.GetKzRpc(); if (hash == null) { hash = new KzUInt256(kzrpc.GetBlockHash(height)); } var raw = kzrpc.GetBlockRaw(hash.Value).GetBytes(); var ros = new ReadOnlySequence <byte>(raw); var bh = new KzBlockHeader { Height = height }; b.Height = height; var tros = ros; if (!b.TryReadBlock(ref tros)) { goto fail; } return(true, ros); fail: return(false, ros); }
static async Task ReadBlockPipeAsync(PipeReader reader) { var block = new KzBlock(); // Read Bitcoin block headers from a PipeReader while (_zmqRunning) { var rr = await reader.ReadAsync(); var consumed = 0L; var buf = rr.Buffer; var ros = buf; if (block.TryReadBlock(ref buf)) { reader.AdvanceTo(buf.GetPosition(consumed)); //KzH.WriteMessageLine($"Block parsed {block.Hash}"); Blocks.AddNewBlock(block, ros); } else { reader.AdvanceTo(buf.Start, buf.End); KzH.WriteMessageLine($"Block parse failed"); } } }
public static int GetLatestBlockHeight() { var kzrpc = KzH.GetKzRpc(); var bci = kzrpc.GetBlockchainInfo(); var height = (int)bci.blocks; return(height); }
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 void SetDefaultMessage() { KzH.WriteMessageLine(@" Basic Getting Started Instructions for KzjHack: a Bitcoin SV sandbox application. You'll need access to a Bitcoin SV node for JSON-RPC and ZMQ access to block and transaction data. Click the ""Settings"" button on the Actions panel to configure access to your node. Also check the root folder to be used on this machine to save cached block data. Once configured, switch to the Log panel to monitor the initial data retrieval. In the Tasks panel, first click Fetch Recent Blocks to fetch recent blocks from your node and save them locally. Once that completes, or if you stop it by unchecking its checkbox, as long as you've retrieved at least on recent block, click the Enable ZMQ checkbox to begin receiving live transaction and new blocks. See http://github.com/tonesnotes/KzBitcoinSV for more information. "); }
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); }