Bitcoin Forum
April 26, 2024, 06:02:04 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1] 2 »  All
  Print  
Author Topic: [BOUNTY] Pushpool question  (Read 7834 times)
davout (OP)
Legendary
*
Offline Offline

Activity: 1372
Merit: 1007


1davout


View Profile WWW
June 01, 2011, 11:38:40 AM
Last edit: June 01, 2011, 02:54:20 PM by davout
 #1

TL;DR : Share solutions, how do they work ?

I've installed jgarzik's pushpool and it's successfully running against a bitcoin client running on testnet,

Pointed a miner at it, generated a few blocks, now I need to track them, and link them to the share that provided the right solution.

So I have a share where pushpool's result is "Y", upstream result is "Y", seems like it generated the block http://blockexplorer.com/testnet/block/000000000055825d01acc3dcc80d02671c2e75ab5b692940446e9b8615ea3824

I do own the address and the logs show a share submission time that is the same as the block timestamp.

The recorded solution for the share is
Code:
0000000150c549978a44e3ef671a4ed3f5b922195ebde0fbbccfdb5900e6827000000000c8a03dfb42fa04d47e9fbfd3e6afcb3d0df2b516eb86f4e64d09fe53cc397b6c4de61f4c1c069652a228e13d000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000

and the block hash is
Code:
000000000055825d01acc3dcc80d02671c2e75ab5b692940446e9b8615ea3824

So my question is, how do I get to the block hash from the submitted share solution so I can track these properly ?

1714111324
Hero Member
*
Offline Offline

Posts: 1714111324

View Profile Personal Message (Offline)

Ignore
1714111324
Reply with quote  #2

1714111324
Report to moderator
1714111324
Hero Member
*
Offline Offline

Posts: 1714111324

View Profile Personal Message (Offline)

Ignore
1714111324
Reply with quote  #2

1714111324
Report to moderator
Even in the event that an attacker gains more than 50% of the network's computational power, only transactions sent by the attacker could be reversed or double-spent. The network would not be destroyed.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1714111324
Hero Member
*
Offline Offline

Posts: 1714111324

View Profile Personal Message (Offline)

Ignore
1714111324
Reply with quote  #2

1714111324
Report to moderator
1714111324
Hero Member
*
Offline Offline

Posts: 1714111324

View Profile Personal Message (Offline)

Ignore
1714111324
Reply with quote  #2

1714111324
Report to moderator
1714111324
Hero Member
*
Offline Offline

Posts: 1714111324

View Profile Personal Message (Offline)

Ignore
1714111324
Reply with quote  #2

1714111324
Report to moderator
davout (OP)
Legendary
*
Offline Offline

Activity: 1372
Merit: 1007


1davout


View Profile WWW
June 01, 2011, 12:58:40 PM
 #2

No one ?

Pieter Wuille
Legendary
*
qt
Offline Offline

Activity: 1072
Merit: 1174


View Profile WWW
June 01, 2011, 01:27:10 PM
 #3

That looks like a hex-encoded block header, including padding done by the sha256 hasher.

Take the first 160 characters of it (80 bytes), decode each group of 2 characters as a hex to a byte, and feed those 80 bytes to a regular sha256 hasher, twice. That should give you the block's id.

I do Bitcoin stuff.
davout (OP)
Legendary
*
Offline Offline

Activity: 1372
Merit: 1007


1davout


View Profile WWW
June 01, 2011, 01:44:26 PM
 #4

That looks like a hex-encoded block header, including padding done by the sha256 hasher.

Take the first 160 characters of it (80 bytes), decode each group of 2 characters as a hex to a byte, and feed those 80 bytes to a regular sha256 hasher, twice. That should give you the block's id.

Thanks a lot! I'll try that and post the results.

davout (OP)
Legendary
*
Offline Offline

Activity: 1372
Merit: 1007


1davout


View Profile WWW
June 01, 2011, 02:28:42 PM
 #5

Maybe I'm doing something wrong but it doesn't really seem to work ...

The original solution :
Code:
irb(main):038:0> str
=> "0000000150c549978a44e3ef671a4ed3f5b922195ebde0fbbccfdb5900e6827000000000c8a03dfb42fa04d47e9fbfd3e6afcb3d0df2b516eb86f4e64d09fe53cc397b6c4de61f4c1c069652a228e13d000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"

I strip it down to the 160 first chars
Code:
irb(main):039:0> stripped = str[0,160]
=> "0000000150c549978a44e3ef671a4ed3f5b922195ebde0fbbccfdb5900e6827000000000c8a03dfb42fa04d47e9fbfd3e6afcb3d0df2b516eb86f4e64d09fe53cc397b6c4de61f4c1c069652a228e13d"
irb(main):040:0> stripped.length
=> 160

I pack it to a binary string :
Code:
irb(main):042:0> binary_data = stripped.to_a.pack("H*")
=> "\000\000\000\001P▒I\227\212D▒▒g\032N▒▒\271\"\031^\275▒▒▒▒Y\000▒p\000\000\000\000Ƞ=▒B▒▒~\237\277▒▒\257▒=\r▒▒\206▒▒M  \376S▒9{lM▒L\034\006\226R\242(\341="

Hash it a first time
Code:
irb(main):043:0> first_pass = (Digest::SHA2.new << binary_data).digest
=> "\025\\2\245▒ҏ\260\211\016D/▒ 0TM$T\aç=▒X\"\251▒▒+\001\276"

Then a second time
Code:
irb(main):044:0> second_pass = (Digest::SHA2.new << first_pass).digest
=> "\276▒*{▒`h▒▒S▒4\230\254h\004n▒▒G\234;^\a\207M;5\016\250t"

And then finally unpack the result back to hex
Code:
irb(main):045:0> second_pass.unpack("H*")
=> ["bef9bc2a7b896068f9c253f23498ac68046ec9f5479c3b5e07874d3b350ea874"]

Doesn't match the block hash...

I feel like a total clueless noob on this one Sad

Any ideas ?

davout (OP)
Legendary
*
Offline Offline

Activity: 1372
Merit: 1007


1davout


View Profile WWW
June 01, 2011, 02:56:50 PM
Last edit: June 01, 2011, 03:28:53 PM by davout
 #6

This is pretty frustrating,  

I'll pay 3 BTC to the person providing a Ruby solution (or that helps me code a working one Cheesy)

EDIT : Maybe there's something to do with endianness ?


xf2_org
Member
**
Offline Offline

Activity: 98
Merit: 13


View Profile
June 01, 2011, 03:45:42 PM
 #7

It is as sipa said...  This is not a custom format.  pushpool is recording the 'getwork' data sent from the miner client, verbatim.  That is standard across all of bitcoin.  The first 160 hex chars (80 bytes) are the block header that successfully found a solution.

To link that to a block, the block header includes the 'prevhash' field that tells you precisely block X-1, for solved block X.

keine-ahnung
Newbie
*
Offline Offline

Activity: 13
Merit: 0


View Profile
June 01, 2011, 04:35:44 PM
 #8

http://pastebin.com/Ya3604J0
I found this code which takes some information and calculates the checksum of the blockheader. It should be possible to use this code to read the hash of the previous block.
davout (OP)
Legendary
*
Offline Offline

Activity: 1372
Merit: 1007


1davout


View Profile WWW
June 01, 2011, 08:03:58 PM
 #9

Hey !

thanks for all the input !
http://pastebin.com/Ya3604J0
I found this code which takes some information and calculates the checksum of the blockheader. It should be possible to use this code to read the hash of the previous block.

I found this piece of code, it's been really useful, now I manage to decode the block header and extract the different fields, I don't think it's a necessary step to retrieve the 2xSHA256 checksum but I just felt it would help my understanding. Thing is I'm doing something that shouldn't work, yet it somehow works... I can't get my head around it.

So for example, to retrieve the previous block hash from the block header I thought I would have to do this :
 - Chop the string between position 8 and 8 + 64 to get a hex representation of the previous hash in little endian
 - Swap bytes to retrieve big endian representation

So, to swap bytes I first tried to reverse the string with chunks of two hex chars, "ab cd ef gh ij kl mn op" becoming "op mn kl ij gh ef cd ab". Didn't work out well.
But for some reason I don't understand, doing that in chunks of 4 bytes (8 chars) yielded correct results ("ab cd ef gh ij kl mn op" -> "ij kl mn op ab cd ef gh")

Looks pretty straightforward in the example code (which yields correct results btw when I hardcode my data sample) :
 - Take previous block hash in big endian
 - Swap bytes without chunks
 - Hash along with the rest of header data

My code (missing the checksum part, and mysteriously succeeding at extracting merkle root and previous block hash) : http://pastebin.com/yVvvwRUd




xf2_org
Member
**
Offline Offline

Activity: 98
Merit: 13


View Profile
June 01, 2011, 08:09:59 PM
 #10

You may also find python hash checking source code, well documented for analysis:

https://github.com/jgarzik/pyminer/blob/master/pyminer.py Miner.work()

http://yyz.us/bitcoin/poold.py checkwork()

davout (OP)
Legendary
*
Offline Offline

Activity: 1372
Merit: 1007


1davout


View Profile WWW
June 01, 2011, 08:14:32 PM
 #11

You may also find python hash checking source code, well documented for analysis:

https://github.com/jgarzik/pyminer/blob/master/pyminer.py Miner.work()

http://yyz.us/bitcoin/poold.py checkwork()
Thank you very much


davout (OP)
Legendary
*
Offline Offline

Activity: 1372
Merit: 1007


1davout


View Profile WWW
June 01, 2011, 09:53:36 PM
 #12

Here we go, if anyone is interested in the ruby BlockHeader class.

Not very elegant, but it does the job :
 - Extracts block header fields
 - Computes block hash

http://pastebin.com/y0sMZSbi

Wuked
Member
**
Offline Offline

Activity: 112
Merit: 10


View Profile WWW
June 09, 2011, 04:44:53 PM
 #13

Thanks for this, it's excellent.

Can I ask what method you are using to convert your solution, or your block_hash into the block ID?

Wuked
Member
**
Offline Offline

Activity: 112
Merit: 10


View Profile WWW
June 09, 2011, 04:59:04 PM
 #14

Obviously you can get it from : http://blockexplorer.com/testnet/rawblock/<HASH>

But, is there a better way ?


davout (OP)
Legendary
*
Offline Offline

Activity: 1372
Merit: 1007


1davout


View Profile WWW
June 10, 2011, 08:19:43 AM
 #15

Obviously you can get it from : http://blockexplorer.com/testnet/rawblock/<HASH>
Certainly not, the block hash is derived directly from the share solution, see the class I pasted.
Basically you initialize a BlockHeader object, feed it the share solution, from there it gives you accessors on the various block header properties (prev. block hash, timestamp, nonce etc.) and an accessor on the block hash.

You can do :
Code:
b = BlockHeader.new(solution)
b.block_hash
=> "000000afbcd21..."

And this doesn't hit any external service

Wuked
Member
**
Offline Offline

Activity: 112
Merit: 10


View Profile WWW
June 10, 2011, 08:19:24 PM
 #16

Yes, I understand that part.

Sorry, I think I was confusing - I'm new to this and was just wondering how you personally going about getting the block number. I've since worked out that different people seem to have different "counts" on the block number - some people starting from 0 and some from 1.

When I say block number, I don't mean the hash. I mean the number.

davout (OP)
Legendary
*
Offline Offline

Activity: 1372
Merit: 1007


1davout


View Profile WWW
June 10, 2011, 09:25:04 PM
 #17

Oh I see, that makes sense.

The answer is that I don't compute the block number.

I don't think there is something like a block ID, there can be multiple blocks at a point of time with the same height (same previous block) and (theoretically) multiple blocks with the same hash. Theoretically it's also possible, even if tremendously unlikely, to have different blocks, at the same height, and having the very same hash.

I wondered about how finding about it though, didn't find a satisfying solution and ended up dropping this issue altogether since I don't really need it in my context.

Please someone correct me if I'm wrong but I think the only way to get the block number without relying on an external service is to simply maintain a linked list of the whole block  chain's headers starting from the genesis block and count the items of the list.

redshark1802
Newbie
*
Offline Offline

Activity: 44
Merit: 0


View Profile
June 19, 2011, 04:25:24 PM
 #18

Hello,

could some please provide a php solution to this problem, or tell where i need to put the
share result in the ruby programm.
I couldn't figure it out.

regards, redshark1802
redshark1802
Newbie
*
Offline Offline

Activity: 44
Merit: 0


View Profile
June 21, 2011, 04:32:41 PM
 #19

thats sad :/
davout (OP)
Legendary
*
Offline Offline

Activity: 1372
Merit: 1007


1davout


View Profile WWW
June 21, 2011, 04:40:45 PM
 #20

thats sad :/
What is your question exactly ? If you need someone to feed you an already made PHP solution I think you're out of luck :

If what you want is use my code you just need a ruby interpreter

Pages: [1] 2 »  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!