Esempio n. 1
0
 public bool SubmitWork(IMiner miner, Work work, string comment)
 {
     return onWork(miner, work);
 }
Esempio n. 2
0
        /// <summary>
        /// Parses a <see cref="WebResponse"/> containing the results of a 'getwork' request.
        /// </summary>
        /// <param name="webResponse"></param>
        /// <returns></returns>
        Work ParseGetWork(WebResponse webResponse)
        {
            // obtain and update current block number
            uint blockNumber = 0;
            if (webResponse.Headers["X-Blocknum"] != null)
                CurrentBlockNumber = blockNumber = uint.Parse(webResponse.Headers["X-Blocknum"]);

            // parse and update long poll url value if present
            var longPollUrlStr = webResponse.Headers["X-Long-Polling"];
            if (longPollUrlStr == null)
                longPollUrl = null;
            else if (longPollUrlStr == "")
                longPollUrl = url;
            else if (longPollUrlStr.StartsWith("http:") || longPollUrlStr.StartsWith("https:"))
                longPollUrl = new Uri(longPollUrlStr);
            else
                longPollUrl = new Uri(url, longPollUrlStr);

            // longPollUrl does not specify user info, but userinfo was required on initial url
            if (string.IsNullOrWhiteSpace(longPollUrl.UserInfo) && !string.IsNullOrWhiteSpace(url.UserInfo))
            {
                var b = new UriBuilder(longPollUrl);
                var u = url.UserInfo
                    .Split(':')
                    .Select(i => HttpUtility.UrlDecode(i))
                    .ToArray();
                if (u.Length >= 2)
                {
                    b.UserName = u[0];
                    b.Password = u[1];
                }
                longPollUrl = b.Uri;
            }

            // retrieve invocation response
            using (var txt = new StreamReader(webResponse.GetResponseStream()))
            using (var rdr = new JsonTextReader(txt))
            {
                if (!rdr.MoveToContent() && rdr.Read())
                    throw new JsonException("Unexpected content from 'getwork'.");

                var response = JsonConvert.Import<JsonGetWork>(rdr);
                if (response == null)
                    throw new JsonException("No response returned.");

                if (response.Error != null)
                    Console.WriteLine("JSON-RPC: {0}", response.Error);

                var result = response.Result;
                if (result == null)
                    return null;

                // decode data
                var data = Memory.Decode(result.Data);
                if (data.Length != 128)
                    throw new InvalidDataException("Received data is not valid.");

                // extract only header portion
                var header = new byte[80];
                Array.Copy(data, header, 80);

                // decode target
                var target = Memory.Decode(result.Target);
                if (target.Length != 32)
                    throw new InvalidDataException("Received target is not valid.");

                // generate new work instance
                var work = new Work()
                {
                    Pool = this,
                    BlockNumber = blockNumber,
                    Header = header,
                    Target = target,
                };

                // release connection
                webResponse.Close();

                return work;
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Parses a <see cref="WebResponse"/> containing the results of a 'getwork' request.
        /// </summary>
        /// <param name="webResponse"></param>
        /// <returns></returns>
        private Work ParseGetWork(WebResponse webResponse)
        {
            // obtain and update current block number
            uint blockNumber = 0;
            if (webResponse.Headers["X-Blocknum"] != null)
                CurrentBlockNumber = blockNumber = uint.Parse(webResponse.Headers["X-Blocknum"]);

            // parse and update long poll url value if present
            var longPollUrlStr = webResponse.Headers["X-Long-Polling"];
            if (longPollUrlStr == null)
                longPollUrl = null;
            else if (longPollUrlStr == "")
                longPollUrl = url;
            else if (longPollUrlStr.StartsWith("http:") || longPollUrlStr.StartsWith("https:"))
                longPollUrl = new Uri(longPollUrlStr);
            else
                longPollUrl = new Uri(url, longPollUrlStr);

            // retrieve invocation response
            using (var txt = new StreamReader(webResponse.GetResponseStream()))
            using (var rdr = new JsonTextReader(txt))
            {
                if (!rdr.MoveToContent() && rdr.Read())
                    throw new JsonException("Unexpected content from 'getwork'.");

                var response = JsonConvert.Import<JsonGetWork>(rdr);
                if (response == null)
                    throw new JsonException("No response returned.");

                if (response.Error != null)
                    Console.WriteLine("JSON-RPC: {0}", response.Error);

                var result = response.Result;
                if (result == null)
                    return null;

                // decode data
                var data = Memory.Decode(result.Data);
                if (data.Length != 128)
                    throw new InvalidDataException("Received data is not valid.");

                // extract only header portion
                var header = new byte[80];
                Array.Copy(data, header, 80);

                // decode target
                var target = Memory.Decode(result.Target);
                if (target.Length != 32)
                    throw new InvalidDataException("Received target is not valid.");

                // generate new work instance
                var work = new Work()
                {
                    Pool = this,
                    BlockNumber = blockNumber,
                    Header = header,
                    Target = target,
                };

                // release connection
                webResponse.Close();

                return work;
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Invokes the 'getwork' JSON method, submitting the proposed work. Returns <c>true</c> if the service accepts
        /// the proposed work.
        /// </summary>
        /// <param name="work"></param>
        /// <returns></returns>
        public bool SubmitWorkRpc(IMiner miner, Work work, string comment)
        {
            var req = OpenRpc(miner, comment);
            if (req == null)
                return false;

            // header needs to have SHA-256 padding appended
            var data = Sha256.AllocateInputBuffer(80);

            // prepare header buffer with SHA-256
            Sha256.Prepare(data, 80, 0);
            Sha256.Prepare(data, 80, 1);

            // dump header data on top of padding
            Array.Copy(work.Header, data, 80);

            // encode in proper format
            var solution = Memory.Encode(data);

            Console.WriteLine();
            Console.WriteLine("SOLUTION: {0,10} {1}", miner.GetType().Name, Memory.Encode(work.Header));
            Console.WriteLine();
            Console.WriteLine();

            using (var txt = new StreamWriter(req.GetRequestStream()))
            using (var wrt = new JsonTextWriter(txt))
            {
                wrt.WriteStartObject();
                wrt.WriteMember("id");
                wrt.WriteString("json");
                wrt.WriteMember("method");
                wrt.WriteString("getwork");
                wrt.WriteMember("params");
                wrt.WriteStartArray();
                wrt.WriteString(solution);
                wrt.WriteEndArray();
                wrt.WriteEndObject();
                wrt.Flush();
            }

            using (var txt = new StreamReader(req.GetResponse().GetResponseStream()))
            using (var rdr = new JsonTextReader(txt))
            {
                if (!rdr.MoveToContent() && rdr.Read())
                    throw new JsonException("Unexpected content from 'getwork <data>'.");

                var response = JsonConvert.Import<JsonSubmitWork>(rdr);
                if (response == null)
                    throw new JsonException("No response returned.");

                if (response.Error != null)
                    Console.WriteLine("JSON-RPC: {0}", response.Error);

                Console.WriteLine();
                Console.WriteLine("{0}: {1,10} {2}", response.Result ? "ACCEPTED" : "REJECTED", miner.GetType().Name, Memory.Encode(work.Header));
                Console.WriteLine();
                Console.WriteLine();

                return response.Result;
            }
        }
Esempio n. 5
0
        public unsafe void BlockHeaderHashTest()
        {
            // sample work with immediate solution
            var work = new Work()
            {
                BlockNumber = 0,
                Header = Memory.Decode("00000001d915b8fd2face61c6fe22ab76cad5f46c11cebab697dbd9e00000804000000008fe5f19cbdd55b40db93be7ef8ae249e0b21ec6e29c833b186404de0de205cc54e0022ac1a132185007d1adf000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"),
                Target = Memory.Decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000"),
            };

            // allocate buffers to hold hashing work
            byte[] round1Blocks = Sha256.AllocateInputBuffer(80);
            uint[] round1State = Sha256.AllocateStateBuffer();
            byte[] round2Blocks = Sha256.AllocateInputBuffer(Sha256.SHA256_HASH_SIZE);
            uint[] round2State = Sha256.AllocateStateBuffer();
            byte[] hash = Sha256.AllocateHashBuffer();

            fixed (byte* round1BlocksPtr = round1Blocks, round2BlocksPtr = round2Blocks, hashPtr = hash, targetPtr = work.Target)
            fixed (uint* round1StatePtr = round1State, round2StatePtr = round2State)
            {
                byte* round1Block1Ptr = round1BlocksPtr;
                byte* round1Block2Ptr = round1BlocksPtr + Sha256.SHA256_BLOCK_SIZE;
                byte* round2Block1Ptr = round2BlocksPtr;

                // header arrives in big endian, convert to host
                fixed (byte* workHeaderPtr = work.Header)
                    Memory.ReverseEndian((uint*)workHeaderPtr, (uint*)round1BlocksPtr, 20);

                // prepare states and blocks
                Sha256.Initialize(round1StatePtr);
                Sha256.Initialize(round2StatePtr);
                Sha256.Prepare(round1Block1Ptr, 80, 0);
                Sha256.Prepare(round1Block2Ptr, 80, 1);
                Sha256.Prepare(round2BlocksPtr, Sha256.SHA256_HASH_SIZE, 0);

                // hash first half of header
                Sha256.Transform(round1StatePtr, round1Block1Ptr);
                Sha256.Transform(round1StatePtr, round1Block2Ptr, (uint*)round2Block1Ptr);
                Sha256.Transform(round2StatePtr, round2Block1Ptr);
                Sha256.Finalize(round2StatePtr, hashPtr);

                for (int i = 7; i >= 0; i--)
                    Assert.IsFalse(((uint*)hashPtr)[i] > ((uint*)targetPtr)[i]);
            }
        }