kingcoin
|
|
March 24, 2013, 05:40:25 AM |
|
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.txtValid 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
uut.data_buf = 512'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000002194261a9395e64dbed17115;
but in the uut it's declared as a 256-bit value: //// Virtual Wire Control reg [255:0] midstate_buf = 0, data_buf = 0;
- How can a new set of data for data_buf and midstate_buf be found on the net or extracted from the BDB files?
|
|
|
|
kingcoin
|
|
March 24, 2013, 06:01:53 AM |
|
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.
|
|
|
|
senseless
|
|
March 24, 2013, 06:08:04 AM |
|
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. set golden_nonce [wait_for_golden_ticket 20]
to set golden_nonce [wait_for_golden_ticket 4]
|
|
|
|
kingcoin
|
|
March 24, 2013, 01:54:56 PM |
|
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...
|
|
|
|
kingcoin
|
|
March 24, 2013, 02:10:07 PM |
|
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
|
|
|
|
kingcoin
|
|
March 24, 2013, 02:33:30 PM |
|
In the testbench the data is set as 512 bit value uut.data_buf = 512'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000002194261a9395e64dbed17115;
but in the uut it's declared as a 256-bit value: //// 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?
|
|
|
|
kramble
|
|
March 24, 2013, 03:21:12 PM Last edit: March 24, 2013, 05:27:53 PM by kramble |
|
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 ... 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
|
|
|
|
kingcoin
|
|
March 24, 2013, 06:08:22 PM |
|
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.
|
|
|
|
kingcoin
|
|
March 25, 2013, 09:37:50 PM |
|
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.txtValid 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_algorithmthen wrote a short-hand function to return the data given in the URL above and a function to print it >>> 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/00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1dNow 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: >>> 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 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?
|
|
|
|
kramble
|
|
March 25, 2013, 11:50:23 PM |
|
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
|
|
|
|
kingcoin
|
|
March 26, 2013, 06:28:18 AM |
|
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: "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.
|
|
|
|
kramble
|
|
March 26, 2013, 09:41:56 AM Last edit: March 26, 2013, 09:57:21 AM by kramble |
|
I grabbed this data using "bitcoind getwork" for the purpose of running it through the python functions: "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 ... 000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000006e81021a86604f513b4139bc8ed7a11d6bb1b2395f71f810586f7fe0649e6e472102d30aaa1e64f000000000ec0000006d1b817fad97371b4583981c6102ba9d6771924d51df357f02000000
If I then put this into the simulation ... 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
|
|
|
|
kramble
|
|
March 26, 2013, 12:13:55 PM |
|
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.pyUse it like this ... 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
|
|
|
|
kingcoin
|
|
March 26, 2013, 01:32:36 PM |
|
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.
|
|
|
|
kingcoin
|
|
March 26, 2013, 01:36:09 PM |
|
Thank you for the link. I'll check it out.
|
|
|
|
Ltcfaucet
|
|
March 29, 2013, 04:52:06 AM |
|
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 ... 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 So what if I double altsource_probe width? X6500 blow up?
|
|
|
|
kramble
|
|
March 29, 2013, 09:50:54 AM Last edit: March 29, 2013, 10:51:03 AM by kramble |
|
So what if I double altsource_probe width?
Not possible. Max per channel is 256 bits. Anyway why would you want to? Only 96 bits are relevant [EDIT] (for data, of course midstate uses all 256). Besides which, the X6500 uses a Xilinx device. Altsource_probe is for Altera devices. X6500 blow up?
You should not be using this software with the X6500 as it is for general purpose FPGA development boards and the X6500 is a purpose built bitcon miner (I'm not saying it can't be used on a X6500, but I don't see why you would want to as it already has its own fully opitimized bitstream). [EDIT] Actually it would appear that the X6500 bitstream is based on the Open Source FPGA Bitcoin Miner, see http://fpgamining.com/documentation/firmware. I really should not comment on things I know nothing about. You should be able to get help on the X6500 thread https://bitcointalk.org/index.php?topic=40058.0Regards Mark
|
|
|
|
kingcoin
|
|
March 29, 2013, 04:34:37 PM |
|
So what if I double altsource_probe width? X6500 blow up?
I don't know anything about the X6500 either. But if the RTL code is the same, then I would assume that you simply shuffle lots of unused data over JTAG. Does the X6500 use JTAG for communication or does it use some more effective protocol? I noticed on their web site that they stopped making these board, does anybody know why? EDIT: Also how much did these boards cost when they were available for sale?
|
|
|
|
kintex_wibble
Newbie
Offline
Activity: 8
Merit: 0
|
|
March 29, 2013, 06:30:26 PM |
|
I've trawled this topic and github but am still not sure what the best starting point for a new (Kintex7-325) fpga miner would be. Multicore is key and a pointer to a working open source software/fpga combo for a serial interface would be hugely appreciated but any sensible starting point would be fine - I expect to do some work! I'm poking about with the verilog_xilinx port at the moment.
|
|
|
|
Ltcfaucet
|
|
March 29, 2013, 08:50:10 PM |
|
So what if I double altsource_probe width?
Not possible. Max per channel is 256 bits. Anyway why would you want to? Only 96 bits are relevant [EDIT] (for data, of course midstate uses all 256). Besides which, the X6500 uses a Xilinx device. Altsource_probe is for Altera devices. X6500 blow up?
You should not be using this software with the X6500 as it is for general purpose FPGA development boards and the X6500 is a purpose built bitcon miner (I'm not saying it can't be used on a X6500, but I don't see why you would want to as it already has its own fully opitimized bitstream). [EDIT] Actually it would appear that the X6500 bitstream is based on the Open Source FPGA Bitcoin Miner, see http://fpgamining.com/documentation/firmware. I really should not comment on things I know nothing about. You should be able to get help on the X6500 thread https://bitcointalk.org/index.php?topic=40058.0Regards Mark What are the 384 bits for when it sends the new nonce and buffer? Is that wasted space or used for something?
|
|
|
|
|