Bitcoin Forum
April 19, 2024, 11:24:50 PM *
News: Latest Bitcoin Core release: 26.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: parsing getwork blockheaders with BitCoinJ  (Read 1491 times)
shads (OP)
Sr. Member
****
Offline Offline

Activity: 266
Merit: 254


View Profile
June 24, 2011, 11:59:26 AM
Last edit: June 24, 2011, 11:48:17 PM by shads
 #1

So what are the extra bytes?

I've tried feeding the getwork data field into the BitCoinJ Block class for parsing but I get rubbish results:

This is the JSON result:

Code:
{
    "error": null,
    "id": 2,
    "result": {
        "data": "000000013aef333a9788611a61cee16e0d555b989015425446f0776c00000478000000009d0221ae1fe47f5963e1b868dbe6388070888400ffcce91c7b60e4f157ed70f44e047b5d1a0c2a1200000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000",
        "hash1": "00000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000010000",
        "midstate": "b5160a8f1c6ade7fc3cac93d31f5f34a5d53faa48b04fa549126c7d6cd4fe791",
        "target": "0000000000000000000000000000000000000000000000122a0c000000000000"
    }
}

This is what I get from parsing it with BitCoinJ:

Code:
size: 128
difficulty: 304745498
nonce: 0
time: 1568343118
My system time: 1308916582
version: 16777216
hash: fa336f7e89b73b44ca1ec41b597c03f92c1e9e68a06789d10517ed1fe9cd9c38

The only thing that seems correct is the nonce.

I've tried reversing the bytes but still rubbish.  Should I be offsetting perhaps?

PoolServerJ Home Page - High performance java mining pool engine

Quote from: Matthew N. Wright
Stop wasting the internet.
The grue lurks in the darkest places of the earth. Its favorite diet is adventurers, but its insatiable appetite is tempered by its fear of light. No grue has ever been seen by the light of day, and few have survived its fearsome jaws to tell the tale.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
kjj
Legendary
*
Offline Offline

Activity: 1302
Merit: 1024



View Profile
June 24, 2011, 01:26:41 PM
 #2

The block is right.  The parser is wrong.  SHA256 works on 64 byte blocks, so messages get padded and salted before hashing.

17Np17BSrpnHCZ2pgtiMNnhjnsWJ2TMqq8
I routinely ignore posters with paid advertising in their sigs.  You should too.
shads (OP)
Sr. Member
****
Offline Offline

Activity: 266
Merit: 254


View Profile
June 24, 2011, 01:45:10 PM
 #3

ok, so do you know if they are padded at the beginning or end?  Is it just a simple matter of trimming the byte array?  The parser is probably not designed to handle the results of a getwork.  According to it's constructor:

/** Constructs a block object from the BitCoin wire format. */

Which probably doesn't include the padding I'm guessing.

PoolServerJ Home Page - High performance java mining pool engine

Quote from: Matthew N. Wright
Stop wasting the internet.
kjj
Legendary
*
Offline Offline

Activity: 1302
Merit: 1024



View Profile
June 24, 2011, 02:20:34 PM
 #4

I couldn't tell without looking at the function, and I despise Java, so...  Hopefully someone familiar with bitcoinj will pop in and help.  Maybe change the subject of the thread.

Usually the first problem people run into when trying to parse/hash this stuff is the difference between network byte order and host byte order.

17Np17BSrpnHCZ2pgtiMNnhjnsWJ2TMqq8
I routinely ignore posters with paid advertising in their sigs.  You should too.
Mike Hearn
Legendary
*
expert
Offline Offline

Activity: 1526
Merit: 1128


View Profile
June 24, 2011, 04:27:56 PM
 #5

Yes, that constructor isn't intended to take the output of getwork.

Presumably the problem is the following code from FormatHashBuffers:

Code:
    // Byte swap all the input buffer
    for (int i = 0; i < sizeof(tmp)/4; i++)
        ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);

But what are you trying to do? If you want to build a miner I don't think you don't have to parse the output of getwork. The getwork protocol is something else.
shads (OP)
Sr. Member
****
Offline Offline

Activity: 266
Merit: 254


View Profile
June 25, 2011, 12:00:18 AM
 #6

I thought it might be a problem with endianess.  Never had to deal with it before in my little java bubble.

Most likely use is to parse the returned getwork to verify it before passing it on upstream.  Or possibly even to generate work for downstream clients.  I know bitcoinj is really focussed on being an end user client atm so not really built with those sort of things in mind but seemed sensible to try an leverage some of the code and it's useful particularly as a learning exercise.

p.s. Mike, the javadoc and comments are great, I've learned more from those than I have from the wiki.

p.p.s. I've search my entire eclipse workspace for references to FormatHashBuffers and even done a text searches for the code snippets but not there.  I've just checked out the trunk so if it's part of the project I should have it? -- whoops looked a bit closer and that's not java...

PoolServerJ Home Page - High performance java mining pool engine

Quote from: Matthew N. Wright
Stop wasting the internet.
shads (OP)
Sr. Member
****
Offline Offline

Activity: 266
Merit: 254


View Profile
June 25, 2011, 04:05:47 AM
 #7

got it... had to brute force it with ever permutation I could think of but finally got an almost result:

Code:
	public static void checkByteSwapped(String data) {
byte[] bytes = Hex.decode(data);
byte[] rev = new byte[bytes.length];
for (int i = 0; i < bytes.length; i += 4) {
byte[] chunk = Arrays.copyOfRange(bytes, i ,  i  + 4);
chunk = Utils.reverseBytes(chunk);
System.arraycopy(chunk, 0, rev, i , 4);
}
checkBytes(rev);
}

produces:

Code:
offset: 0
v1 block:
   previous block: 00000000000008ee4076724291e1656d84ac61d98bf89dd3656680782aad1a4a
   merkle root: 8de49d9cc1dce6cf0a89b95cd5d683eb787e3f6a02072acf69ddab88b8ae01ff
   time: [1308974260] Sat Jun 25 13:57:40 EST 2011
   difficulty target (nBits): 437004818
   nonce: 0

which matches the last block from blockexplorer.  The only part that doesn't match up is the difficulty target.  Block explorer says: 1379223.4296725

but at least it's progress...

PoolServerJ Home Page - High performance java mining pool engine

Quote from: Matthew N. Wright
Stop wasting the internet.
shads (OP)
Sr. Member
****
Offline Offline

Activity: 266
Merit: 254


View Profile
June 25, 2011, 05:03:57 AM
 #8

ok so I've just learned about compact form vs long form... and I seem to be decoding difficulty close but not precise:

Code:
					L.println("************************************************************************");
L.println("offset: " + i);
L.println(block.toString());
String diff = block.getDifficultyTargetAsInteger().toString(16);
long highestDifficult = 0x1d00ffff;
BigDecimal highestDifficulty = new BigDecimal(Utils.decodeCompactBits(highestDifficult));
diff = StringUtils.leftPad(diff, 64, '0');
L.println("max diff: " + StringUtils.leftPad(Utils.decodeCompactBits(highestDifficult).toString(16), 64, '0'));
L.println("hex diff: " + diff);
BigDecimal ratio = highestDifficulty.divide(new BigDecimal(block.getDifficultyTargetAsInteger()), 7, RoundingMode.FLOOR);
L.println("ratio: " + ratio.toPlainString());
L.println("************************************************************************");

gives me:

Code:
************************************************************************
offset: 0
v1 block:
   previous block: 00000000000003fc392bab7a327a019fce4b48c98d5bc4b0d8d20f6e21e4ce1f
   merkle root: 2891334d6466ea274ac50cdb2af50afc889d236689cfe6ace9682b752900985a
   time: [1308977962] Sat Jun 25 14:59:22 EST 2011
   difficulty target (nBits): 437004818
   nonce: 0

max diff: 00000000ffff0000000000000000000000000000000000000000000000000000
hex diff: 0000000000000c2a120000000000000000000000000000000000000000000000
ratio: 1379192.2882280
************************************************************************

which is pretty damn close to blockexplorer: 1379223.4296725

It seems odd that difference is very close to 32 (31.1414).  Perhaps I've mashed a bit somewhere.

PoolServerJ Home Page - High performance java mining pool engine

Quote from: Matthew N. Wright
Stop wasting the internet.
shads (OP)
Sr. Member
****
Offline Offline

Activity: 266
Merit: 254


View Profile
June 25, 2011, 05:57:40 AM
 #9

excuse me continuing to talk to myself...

Just notices that my bitcoind client is returning 1379192.28822808 from getdifficulty so it was decoded properly.

Odd though that blockexplorer is returning a different difficulty?

PoolServerJ Home Page - High performance java mining pool engine

Quote from: Matthew N. Wright
Stop wasting the internet.
theymos
Administrator
Legendary
*
Offline Offline

Activity: 5180
Merit: 12865


View Profile
June 25, 2011, 06:41:40 AM
 #10

BBE's /q/getdifficulty uses Bitcoin's old difficulty calculation, which has some precision problems. You'll notice that the difficulty reported on block pages is the same as yours.

1NXYoJ5xU91Jp83XfVMHwwTUyZFK64BoAD
Pages: [1]
  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!