static Mining.Merkle AsMerkle(string hex) { var res = new Mining.Merkle(); HexHelp.DecodeInto(res.blob, hex); return(res); }
/// <summary> /// Parsing the response of "mining.subscribe". It is quite convoluted as this uses heterogeneous arrays. /// </summary> static public Response.MiningSubscribe MiningSubscribe(object?jsonLine) { if (jsonLine is not JArray arr) { throw new BadParseException("mining.subscribe: result must be an array"); } if (arr[0] is not JArray first) { throw new BadParseException("mining.subscribe: result[0] must be an array"); } var parts = from el in first where el.Type == JTokenType.Array select el as JArray; var sessionId = (from el in parts where el.Count == 2 where el[0].Type == JTokenType.String && el[0].Value <string>() == "mining.notify" where el[1].Type == JTokenType.String select el[1].Value <string>()).FirstOrDefault(); if (null == sessionId) { throw new MissingRequiredException("mining.subscribe: couldn't find any sessionid mining.notify pair"); } if (arr[1].Type != JTokenType.String) { var careful = arr[1].Type; if (careful == JTokenType.Undefined || careful == JTokenType.Null) { throw new MissingRequiredException("mining.subscribe: missing extraNonce1"); } throw new BadParseException("mining.subscribe: extraNonce1 must be a string"); } var extra1str = arr[1].Value <string>().Trim(); if (extra1str.Length == 0) { throw new MissingRequiredException("mining.subscribe: extraNonce1 is an empty string"); } var extraNonce1 = HexHelp.DecodeHex(extra1str); if (arr[2].Type != JTokenType.Integer) { throw new BadParseException("mining.subscribe: result[2] must be an integral number"); } var nonce2sz = arr[2].Value <long>(); if (nonce2sz != 4) { throw new BadParseException("mining.subscribe: for the time being, nonce2sz must be 4"); } if (nonce2sz < 0 || nonce2sz > ushort.MaxValue) { throw new BadParseException($"mining.subscribe: nonce2sz is invalid ({nonce2sz})"); } return(new Response.MiningSubscribe(sessionId, extraNonce1, (ushort)nonce2sz)); }
static public Notification.NewJob MiningNotify(object?evargs) { if (null == evargs) { throw new MissingRequiredException("mining.notify: no payload given"); } if (evargs is not JArray concrete) { throw new MissingRequiredException("mining.notify: payload must be an array"); } if (concrete.Count != 9 && concrete.Count != 10) { throw new BadParseException("mining.notify: element count mismatch, won't be able to parse"); } var getTrie = concrete.Count == 10; byte[]? trie = null; var index = 0; var jobid = concrete[index++].Value <string>(); var prevHashHexstr = concrete[index++].Value <string>(); if (getTrie) { var triestr = concrete[index++].Value <string>(); trie = HexHelp.DecodeHex(triestr); } var coinbaseFirst = concrete[index++].Value <string>(); var coinBaseSecond = concrete[index++].Value <string>(); var merkles = concrete[index++] as JArray ?? throw new BadParseException("mining.notify: merkles must be an array"); var version = HexHelp.DecodeHex(concrete[index++].Value <string>()); var nbits = HexHelp.DecodeHex(concrete[index++].Value <string>()); var ntime = HexHelp.DecodeHex(concrete[index++].Value <string>()); var flush = concrete[index++].Value <bool>(); var cbFirst = HexHelp.DecodeHex(coinbaseFirst); var cbTail = HexHelp.DecodeHex(coinBaseSecond); var res = new Notification.NewJob(jobid, version, trie, cbFirst, cbTail, nbits, ntime, flush); HexHelp.DecodeInto(res.prevBlock.blob, prevHashHexstr); var decodedMerkles = merkles.Select(el => AsMerkle(el)); res.merkles.AddRange(decodedMerkles); return(res); }