I need some help trying to verify that my implementation is correct or not. I'm trying to make a Stratum mining client.
All byte orders are as is directly received from the server, without endian swapping
Here's the data:
{"result": [[["mining.notify", "108fa002000000001"], ["mining.set_difficulty", "108fa002000000002"]], "108fa00200000000", 4], "id": 1, "error": null}
{"params": ["1369818357 489", "56d14795eadabe52464b0c6410f8c1f70c0af2c5444379160000002400000000", "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff51039aa3030d00456c69676975730051a5c4f5fabe6d6d28db22e01b9dceb2e0dc8d7cc01bfc4dcdbce7f7a49c57020c827389efdcea970200000000000000002f7373302f00", "ffffffff3ed2f0af0c000000001976a914ad9261f01eae43c949ecaaa375759f9fcbcb3dc288acda8bae0c000000001976a914df4ad46ed8ac51d73e17f8bd7a203f07e932294e88ac0914f809000000001976a91479257603444e9e8b6796d17646ecae881376128388ac2d535509000000001976a914a804274391cb1a6f157a500cf8df2b4141bae42588ac88a61107000000001976a914c8459142759347c481684590dabf11d9f91e143f88acd1c76e06000000001976a914da9d41c79ca85ce0c68057b8adfb753424e7f07a88ac5f874c06000000001976a914bc98f0de5c77080eae5142e11a884e6e0b793d3888acb36b4c06000000001976a914b5945df721fd42b339737c07c24ab36ee3e7c1ac88ac44963606000000001976a91499b4fb6f4d29cfd2ccd200ce9df24c61e2491da188acfb86b605000000001976a914195344563ecbfc06eb183d330437fddd53b2635288acd7659902000000001976a914bf7d251592efa8397598e08960b22c434464d23288acc8418f02000000001976a9145dfae39b14a09e9493fc6f95019fc1d8d1c9258088ac023c3d02000000001976a91453d0290a46f94887b3f5a552e7ffcce5f1202d9b88ac76bf2d02000000001976a9141623fbaf4d6b6ba8af9183c41760adadaef34bab88ac04b4f501000000001976a91435244a9cdc90997ff5536bdfbf909b2b6165d67a88ac24fad101000000001976a914fc169f6235cbfd5a1f9f7f080b60e3599f1d677388ac9d94cb01000000001976a914647dffe1e73cdffe0c763fb677f938dcd2d616a988ac3a0a9f01000000001976a914b3056b29332c33e84c97ab2f61dd648cc6c8f75588ac01649301000000001976a914a2df6ff0702ac2889cfff340df476af8adbcc8b688acb4838501000000001976a914f5aab50a274a24857d8745f2e3aeee18c28b513288accd188501000000001976a914c17e44923f07ddd95b030cee63e94bea7a28550288ac48f88301000000001976a9141fc352bd6c1db3f461bc41af113701f6e28256ea88aceed28101000000001976a914a72cab69d8a1748729a2798834dc3408c0e0f5a288ac29ff4a01000000001976a914eb2715703c77f1b334e8c68010682a58aa011be188ac48234201000000001976a914cce45595065ed827562e901ce831d6274222753288ac58254001000000001976a9147d702b3c6d922699b9d2509d9db40c2915aa54e488ac711f3b01000000001976a9149465fdac29b5c47b99c8d17379d0fc6d99c1e4a688ac46313a01000000001976a91455d28f71541dcb0a5848f3a15218da960182512b88ac80be3701000000001976a9147f960729bfd6684569d58e13674d877552069d8288ac4fed3401000000001976a914720b13f90cfb675568b99ae88bdc41e0b9612f4c88ac59643401000000001976a914a07d0ff15ad9d770a8f4ce336ccfd038436a51e588ac61532f01000000001976a914768acf953a1d3b1eddbe225291290d55d067a18e88ac9adf2d01000000001976a91404ba740ae19208ecc3f6505dc8dbcf0b692a6c6e88ac82a62c01000000001976a914da39d920f0f15c9d99978992517efcc3429dd62088ac066e2701000000001976a9149193af5c84dea0a2fc0b7e52087c7c96bfbcf44088acaade2501000000001976a914247bf801ffd4afb506e71b027eb2ed647fdc69d488ac458e2401000000001976a914952dea3415effa2c0b8544fb7fc0a602a92fe84288ac10662401000000001976a9143d192a354cee6d1ddbddb7df03ad4229d3095bb788ac07e92201000000001976a9144ae00300aaad08ee3a219fe772ec1f3a73a8c94788ac413b2101000000001976a914540d04e4f2a7281a2a2b60e90ebd5c46074dc00e88acb56c2001000000001976a914172205d324c0d902ab9e4330e7fbdef128b71b7f88ac22361f01000000001976a9145c90a505a74f6c3c10d71c9b089b9cd0b919bdb988acc9d11d01000000001976a9148fdf745b2aca7f918bf2a4f54526653e3466e54388ac404a1b01000000001976a914e54f005cdc5405459f22a0588bae51940deaad1988ac8b3f1b01000000001976a914d39d22a99da41e94b3a866822a3e482b09e3d73088ac21ec1a01000000001976a9145f5473211ff432a7a65df04d5ea1f05d183368c288aca6521a01000000001976a9146b1af4b5e35b061381cb75505edec009caa8566f88aca7111901000000001976a9145ab1860a6059e4ec5e82a733132ef678fdd4abcf88ac383f1701000000001976a91447e803b8dc72e6a3bdad26f0e623e66f5c46c77e88ac84221701000000001976a914bb5db3069f74f1a7775e238c7361ee1ca37279ea88ac18951601000000001976a9141fed5b3bffd76ecc742257286befccf4a561ac6788ac0a7d1601000000001976a914b6aae63d35235aa5742db64bf41983feb55c1fd188ac09e91501000000001976a9148ace0f9a55cfb3f119bb8b40344eaadd2f83932d88ac24fd1301000000001976a91498bc3bd4ef9f301985a73042a41e307bbc21b2b388ac04e21301000000001976a9142ac79cc463b3bf2a67c28a0a71d54cb7def691ca88ac31581301000000001976a9146790d62962472fbdd81bc7552a23a4fb0a07c17088accac61201000000001976a914235e7b503fd47e908b4ea7d11237003e18e4833e88acff761201000000001976a914915c5363289cef9e4b05eaf13608d955717bf5fb88ac7b681201000000001976a914db2f9af40204e79f9c2316c043df0abc2121879388acaaed1101000000001976a914d2744af774b66c595b753af38c88b8948a99827188ac56780b00000000001976a91467123b0c6577d7932ddb7045567eed2c488773c488ac01000000000000001976a9145399c3093d31e4b0af4be1215d59b857b861ad5d88ac00000000", ["d8481cf9050990f425c82fd0f4b0d1dcd3166435cd56eb8f00c76244704812d8", "815bb21cfd4bf9d26b8b85937390bfb6c39f84a81f8580ba0028c935543cfeec", "1450b5fe41462f25ca2b8f1f8df1fc08732532ec5b72039f5ad1ad1bd0a3546c", "af94c2da313d385e2c0c8812c70f8e86809e90f95e79f25e6cdf6c98eac1232a", "53276d253bee618e675e32b0367e3a786e717bc7e766b165caa8d5de84ef1bf8", "b0e99cef9b6a55684b8a399a54842a5123163c2fe324a9c563f4d5314ff50684", "1b559b9b59306deb2d23716fecd213852efe519cbf297c9b10178be71c1013e9"], "00000002", "1a016164", "51a5c4f5", false], "id": null, "method": "mining.notify"}
{"params": ["redacted", "1369818357 489", "12000000", "51a5c4f5", "41f20233"], "id": 2, "method": "mining.submit"}
I've obtained this from running bfgminer and dumped the share logs and tcpdumped the connection to the pool.
bfgminer has logged the block header as (with padding):
0000000256d14795eadabe52464b0c6410f8c1f70c0af2c5444379160000002400000000751b1aba
ddefb3e3e74c3ac8bbe49787a5ae21703b873e0958a9441a0871d2dc51a5c4f51a01616441f20233
00000080000000000000000000000000000000000000000000000000000000000000000000000000
0000000080020000
Hashing the data as it appears in the usual fashion, ie., sha256(sha256(data)), doesn't yield the hash that it says it obtained, which is d8b5ed97e69707dc17cae1c23e672818a18b75fd362bb698fad4433b00000000
.
I thought I could calculate the merkle root by the usual fashion, with the nonces obtained from the above subscription and the submission message:
>>> coinbase = coinbase1 + extranonce1 + extranonce2 + coinbase2
>>> coinbase_bin = binascii.unhexlify(coinbase)
>>> root = coinbase_bin
>>> for h in merkle_branch:
... root = hashlib.sha256(hashlib.sha256(root + binascii.unhexlify(h)).digest()).digest()
>>> binascii.hexlify(root)
'eed07afc76bc7b15dc5871581a2460c7473ed68573082a0e5864140db0d11803'
which is wrong too.
Can someone tell me what's going on here? What do I need to swap and what do I need to keep as-is? Or can someone give me a subscription message, a work notification, and a submission message, and show me how to perform all the validation steps?