Pages:
Author

Topic: Official Open Source FPGA Bitcoin Miner (Last Update: April 14th, 2013) - page 16. (Read 432891 times)

full member
Activity: 126
Merit: 100
sr. member
Activity: 262
Merit: 250
I've found some python code to calculate midstate in the stratum mining proxy.

https://github.com/slush0/stratum-mining-proxy/blob/master/mining_libs/midstate.py


Thank you for the link. I'll check it out.
sr. member
Activity: 262
Merit: 250
So I suggest checking your big->little endinan conversion.

Thanks! I found it a little confusing as when data was shown in big endian and when in little endian so I suspected some problems in this area. With your sample data it will be a lot easier to spot the mistake.
sr. member
Activity: 384
Merit: 250
I've found some python code to calculate midstate in the stratum mining proxy.

https://github.com/slush0/stratum-mining-proxy/blob/master/mining_libs/midstate.py

Use it like this ...
Code:
import midstate

# From testbenches/test_data.txt
data="000000014cc2c57c7905fd399965282c87fe259e7da366e035dc087a0000141f000000006427b6492f2b052578fb4bc23655ca4e8b9e2b9b69c88041b2ac8c771571d1be4de695931a2694217a33330e000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"

m = midstate.calculateMidstate(data[0:128].decode('hex'))
print "midstate=" + m[::-1].encode('hex_codec')

I printed the reversed string so it matches the verilog version.
Mark
sr. member
Activity: 384
Merit: 250
I grabbed this data using "bitcoind getwork" for the purpose of running it through the python functions:

Code:
"midstate" : "eb672bb44f809201ba29d7668d4b2026073bd338fd1f46e8f9cf6520aa70492e",
"data" : "000000027f35df514d9271679dba02611c9883451b3797ad7f811b6d000000ec00000000f0641eaa0ad30221476e9e64e07f6f5810f8715f39b2b16b1da1d78ebc39413b514f60861a02816e00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000",
"hash1" : "00000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000010000",
"target" : "00000000000000000000000000000000000000000000006e8102000000000000"

I run the data and midstate through the miner and got the nonce 3352694142. Then I tried to extract the verilog data as:

midstate_buf = 256'h2e4970aa2065cff9e8461ffd38d33b0726204b8d66d729ba0192804fb42b67eb,
data_buf =     256'h00000000000000000000000080000000000000001a02816e514f60863b4139bc,
nonce =        32'd3352694142 - 256,

But of course this did not work, which I expeced since my interpretation of the data in test_data.txt is wrong as I can't get the correct SHA256.

I think there is something a bit off in your reversal of data as I get ...
Code:
000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000006e81021a86604f513b4139bc8ed7a11d6bb1b2395f71f810586f7fe0649e6e472102d30aaa1e64f000000000ec0000006d1b817fad97371b4583981c6102ba9d6771924d51df357f02000000

If I then put this into the simulation ...
Code:
uut.midstate_buf = 256'h2e4970aa2065cff9e8461ffd38d33b0726204b8d66d729ba0192804fb42b67eb;
uut.data_buf = 256'h00000000000000000000000080000000000000006e81021a86604f513b4139bc;
uut.nonce = 32'd3352694142 - 2; // I was impatient and offset by 2 rather than 256

It gives me the expected nonce C7D60D7E

So I suggest checking your big->little endinan conversion.

I'll have a look into midstate, but as it means digging into the bitcoind code it may take a while.
Regards
Mark
sr. member
Activity: 262
Merit: 250
the only way to generate it is to delve into the bitcoind (or cpuminer etc) source code (its not available by calling the usual crypto library sha256 digester from python/perl/whatever).

I guess it should be possible to feed a block through a simulation of the double SHA256 blocks with a zero init state and sample the state at some point. This task would be easier if given a known block and a known midstate, then I could try with a different block and sample it in the same manner.

But why are you starting from the block anyway? If all you want is some test data, just use the midstate and data from the getwork request. Swap the endian'ness and plug them directly into the test bench (hacking the data field down to 512 bits).

This was actually the reason why I wrote the litte Python functions, i.e. to aid this task. But it did not produce the correct result. The reason for my previous post was that I would like to know where my understanding of going from a given midstate and block to the actual data used is wrong.

I can't correctly calculate the SHA256 for the sample data given in test_data.txt so again my understanding and/or implementation of the little functions are wrong.

I grabbed this data using "bitcoind getwork" for the purpose of running it through the python functions:

Code:
"midstate" : "eb672bb44f809201ba29d7668d4b2026073bd338fd1f46e8f9cf6520aa70492e",
"data" : "000000027f35df514d9271679dba02611c9883451b3797ad7f811b6d000000ec00000000f0641eaa0ad30221476e9e64e07f6f5810f8715f39b2b16b1da1d78ebc39413b514f60861a02816e00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000",
"hash1" : "00000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000010000",
"target" : "00000000000000000000000000000000000000000000006e8102000000000000"

I run the data and midstate through the miner and got the nonce 3352694142. Then I tried to extract the verilog data as:

midstate_buf = 256'h2e4970aa2065cff9e8461ffd38d33b0726204b8d66d729ba0192804fb42b67eb,
data_buf =     256'h00000000000000000000000080000000000000001a02816e514f60863b4139bc,
nonce =        32'd3352694142 - 256,

But of course this did not work, which I expeced since my interpretation of the data in test_data.txt is wrong as I can't get the correct SHA256.

Another approach would be to take data from the blockchain and calculate the midstate. That's why I asked how to calculate the midstate.
sr. member
Activity: 384
Merit: 250
I've exhausted my google-fu on this, and basically got nowhere, but I'll dump my conclusions anyway.

You need a unique midstate for each block. Unfortunately this is internal to the sha256 algorithm, and since its not much used outside the bitcoin getwork protocol, the only way to generate it is to delve into the bitcoind (or cpuminer etc) source code (its not available by calling the usual crypto library sha256 digester from python/perl/whatever).

But why are you starting from the block anyway? If all you want is some test data, just use the midstate and data from the getwork request. Swap the endian'ness and plug them directly into the test bench (hacking the data field down to 512 bits).
[EDIT I guess you'll want the nonce too, the easiest way to get this is to log the share submitted back to the pool from a live miner as it would take way too long to simulate the entire 4GHashes].

I'll have another look at this tomorrow (I've done it myself ages ago, so I just need to work through some examples).
Mark
sr. member
Activity: 262
Merit: 250

The testbench contains a block of test data for the simuation:

https://github.com/progranism/Open-Source-FPGA-Bitcoin-Miner/blob/master/testbenches/test_data.txt
Code:
Valid hash examples:

Midstate: 90f741afb3ab06f1a582c5c85ee7a561912b25a7cd09c060a89b3c2a73a48e22
Data: 000000014cc2c57c7905fd399965282c87fe259e7da366e035dc087a0000141f000000006427b6492f2b052578fb4bc23655ca4e8b9e2b9b69c88041b2ac8c771571d1be4de695931a2694217a33330e000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000
NONCE: 32'h0e33337a == 238,236,538


Verilog values:
Data: 512'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000002194261a9395e64dbed17115
Midstate: 256'h228ea4732a3c9ba860c009cda7252b9161a5e75ec8c582a5f106abb3af41f790

The Midstate is converted to big endian, but

How was the data extracted/calculated?



Does anybody know how I convert a given block midstate and data in order to run it through the simulation?

It bugs me that I can't figure out how to do it.

First I grabbed the example data and functions to calculate SHA256 from:

https://en.bitcoin.it/wiki/Block_hashing_algorithm

then wrote a short-hand function to return the data given in the URL above  and a function to print it

Code:
>>> example_data_from_net()
'0100000081cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122bc7f5d74df2b9441a42a14695'
>>> btc_sha256(example_data_from_net())
'00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d'
>>> print_header(example_data_from_net())
version:         1
prev block hash: 00000000000008a3a41b85b8b29ad444def299fee21793cd8b9e567eab02cd81
merkle root:     2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3
time:            1305998791 (Sat May 21 17:26:31 2011)
bits:            440711666 (1a44b9f2)
nonce:           2504433986
>>>

The above is identical to block 125552 and is the same as:

https://blockchain.info/block-index/138942/00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d

Now to the verilog data. I also wrote a short-hand function to return it. The data appears to have been byte swapped (see nonce) so I tried to print it and calculate the SHA256:

Code:
>>> raw_simulation_data()[0:160]
'000000014cc2c57c7905fd399965282c87fe259e7da366e035dc087a0000141f000000006427b6492f2b052578fb4bc23655ca4e8b9e2b9b69c88041b2ac8c771571d1be4de695931a2694217a33330e'
>>> print_header(raw_simulation_data()[0:160])
version:         16777216
prev block hash: 000000001f1400007a08dc35e066a37d9e25fe872c28659939fd05797cc5c24c
merkle root:     bed17115778cacb24180c8699b2b9e8b4eca5536c24bfb7825052b2f49b62764
time:            2476074573 (Thu Jun 18 06:29:33 2048)
bits:            563357210 (2194261a)
nonce:           238236538
>>> btc_sha256(raw_simulation_data()[0:160])
'99ebd86b20ed4da8ed5d1796261fa81e4ae6c2caff22d520f6dc77834df1e28b'
>>>

The nonce printed out match the one given in the test_data.txt file, even though the version and data is a little odd, but it might have been made on a test net. But the SHA256 is not correct so something is obviously wrong.

The simulation data in the is given as:

Data: 512'h000002800000000000000000000000000000000000000000000000000000000000000000000000 000000000080000000000000002194261a9395e64dbed17115

As kramble mentioned earlier only half of this is used, hence it seems like it's constructed like this

Code:
0000000000000000000000008000000000000000 2194261a 9395e64d  bed17115
constant                                 bits     time      merkle root

However, if I try to apply the same algorithm on some other block I don't get a hit in the simulation (I take the expected nonce and step back a few hundred cycles) so my interpretation of how this is done is clearly wrong. But where did I make a mistake?

sr. member
Activity: 262
Merit: 250
Since verilog automatically truncates the data, the 512 bit data supplied in the test harness for simulation is shoehorned into the 256 bit data_buf (this is either fortuitous or deliberately done like this, I cannot know which, but it works).

VHDL would have barfed big time upon similar assignment though. Thank you for the explanation of the getwork padding etc.
sr. member
Activity: 384
Merit: 250
Is this a typo in the code, which just happens to work because the way Verilog truncates array assignements?

Since you've not managed to coax a reply from the author(s), I'll volunteer a reply, so that you're not just talking to yourself ...

512 bits (64 bytes) is the input to the sha256_transform function (rx_input).
However the altsource_probe (virtual_wire) is limited to 256 bits per channel (or whatever its called).
Luckily most of the data is constant, in fact we only use 96 bits of it vis ...

Code:
data <= {384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000, nonce_next, data_buf[95:0]};

The 512 bits in the test harness is the second 64 bytes of the 128 byte getwork data field (see my addendum below).

This is truncated to 256 bits in the mining TCL script, and sent to the FPGA.
Only 96 bits of it is actually used, but since the rest is constant, the full 512 bits is reconstructed (including the variable nonce), and passed to sha256_transform.

Since verilog automatically truncates the data, the 512 bit data supplied in the test harness for simulation is shoehorned into the 256 bit data_buf (this is either fortuitous or deliberately done like this, I cannot know which, but it works).

And if you wanted to optimize the FPGA some more, modify the mining TCL script to only send 96 bits to the FPGA in the first place and save a chunk of registers in the altsource_probe.

[EDITED to fix numerous typos and mixup betweed midstate and data]

And one further edit (since I'm making a right dog's dinner of this post, I may as well try to get it correct, if only for my own peace of mind)...

Getwork supplies 128 bytes as "data", which is the 80 byte block header, padded with 0's (and a single 1) and its (fixed) length value to give a 128 byte message. The SHA256 digest requires the message to be split into 64 byte chunks for hashing, so the 128 byte is split into two chunks. The first of which is precalculated to give midstate and supplied within the getwork packet so we don't have to do it ourselves. Only the second 64 bytes is used by the FPGA (and much of this is constant, mainly 0's, and is assumed to be so within the verilog code, hence that 384'h string). To further confuse things, the TCL mining script only sends 32 bytes (256) bits of those 64 bytes to the FPGA, since this is the most altsource_probe allows per channel. The nonce is appended within the FPGA, plus the 384'h constant part and then the full 64 bytes (512 bits) is hashed TWICE.

That's my take on it anyway, if one of the experts wants to correct me, then feel free.
Mark

sr. member
Activity: 262
Merit: 250
In the testbench the data is set as 512 bit value

Code:
uut.data_buf = 512'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000002194261a9395e64dbed17115;
  but in the uut it's declared as a 256-bit value:

Code:
//// Virtual Wire Control
reg [255:0] midstate_buf = 0, data_buf = 0;
why is this?


Is this a typo in the code, which just happens to work because the way Verilog truncates array assignements?
sr. member
Activity: 262
Merit: 250
As of my last question it seems like I can use blockchain.info, but I have to convert the timestamp and difficulty unless there is a site which dumps the block header in hex.



calling "bitcoind getblock block" seem to return all the information
sr. member
Activity: 262
Merit: 250

   set golden_nonce [wait_for_golden_ticket 4]

I already tried this, but it did not help. I guess there must be a bug in my test code...
hero member
Activity: 1118
Merit: 541
I was playing with the multicore FPGA design and I get high local rates (as expected), but the estimated rate is low. Is this because the mine.tcl script does not implement long polling?

[03/23/2013 14:52:55] 300.00 MH/s (~54.09 MH/s) [Rej: 0/42 (0.00%)]



You need to modify the mine.tcl. At the bottom there is a wait for golden nonce. Change that wait time to 4-5 seconds.

Quote
   set golden_nonce [wait_for_golden_ticket 20]

to

Quote
   set golden_nonce [wait_for_golden_ticket 4]
sr. member
Activity: 262
Merit: 250
As of my last question it seems like I can use blockchain.info, but I have to convert the timestamp and difficulty unless there is a site which dumps the block header in hex.

sr. member
Activity: 262
Merit: 250
The testbench contains a block of test data for the simuation:

https://github.com/progranism/Open-Source-FPGA-Bitcoin-Miner/blob/master/testbenches/test_data.txt
Code:
Valid hash examples:

Midstate: 90f741afb3ab06f1a582c5c85ee7a561912b25a7cd09c060a89b3c2a73a48e22
Data: 000000014cc2c57c7905fd399965282c87fe259e7da366e035dc087a0000141f000000006427b6492f2b052578fb4bc23655ca4e8b9e2b9b69c88041b2ac8c771571d1be4de695931a2694217a33330e000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000
NONCE: 32'h0e33337a == 238,236,538


Verilog values:
Data: 512'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000002194261a9395e64dbed17115
Midstate: 256'h228ea4732a3c9ba860c009cda7252b9161a5e75ec8c582a5f106abb3af41f790

The Midstate is converted to big endian, but
  • How was the data extracted/calculated?
  • In the testbench the data is set as 512 bit value

Code:
uut.data_buf = 512'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000002194261a9395e64dbed17115;
  but in the uut it's declared as a 256-bit value:

Code:
//// Virtual Wire Control
reg [255:0] midstate_buf = 0, data_buf = 0;
    why is this?

  • How can a new set of data for data_buf and midstate_buf be found on the net or extracted from the BDB files?
sr. member
Activity: 262
Merit: 250
I was playing with the multicore FPGA design and I get high local rates (as expected), but the estimated rate is low. Is this because the mine.tcl script does not implement long polling?

[03/23/2013 14:52:55] 300.00 MH/s (~54.09 MH/s) [Rej: 0/42 (0.00%)]

sr. member
Activity: 262
Merit: 250
No I don't have a supply of Stratix V's. I was juts curious of their mining performance
hero member
Activity: 1118
Merit: 541
I would have expected the 28nm Stratix V to be faster. Maybe the new ALM structure does not map that well into the sha logic, at least with the current version of Quartus.

That was under Quartus 11.1, so not even the latest Quartus. I would also expect it to clock higher but it seems the stratix v's are pretty significantly different when compared to previous versions.

Do you have a supply of Stratix Vs? What sort of pricing are you getting for them?






sr. member
Activity: 262
Merit: 250
I would have expected the 28nm Stratix V to be faster. Maybe the new ALM structure does not map that well into the sha logic, at least with the current version of Quartus.
Pages:
Jump to: