Bitcoin Forum
May 26, 2024, 02:50:50 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Unable to mine blocks 128 and beyond using version 2 blocks.  (Read 1529 times)
Farthom (OP)
Newbie
*
Offline Offline

Activity: 14
Merit: 0


View Profile
January 17, 2014, 02:39:05 AM
 #1

I am working on a self education project, where I am attempting to build a cheap miner application. I have set up "testnet in a box" and have written a small miner that builds version 2 blocks. The miner mines successfully, all blocks up to and including 127, but when attempting to submit block 128 blocks become rejected citing error "AcceptBlock() : block height mismatch in coinbase"

The coinbase script I am using looks like this: (example does not include the script length varint prefix)
0180 00002f503253482f04b8864e50080800000200000001072f736c7573682f



It is curious, how the block that fails is the one immediately past the max value of a signed byte (127) I suspect there may be a genuine bug here, related to how bitcoin computes the expected prefix.

Internally height is stored as a "signed" int: (Collected from AcceptBlock() function in main.cpp)
int nHeight = 0;

I suspect errors occur when these signed values get compacted into a variable integer. We may simply have never seen this, because of the possibility block version 2 was not introduced until both testnet and mainnet were sufficiently long to mask the problem. Sadly, I don't have the environment or tools set up to compile and rake around in bitcoin code. Can someone here more equipped, and more knowledgeable than I help me investigate this? I'd be curious of the result of the following snippit of code:

int nHeight = 128;
CScript expect = CScript() << nHeight;

See if the bytes built by CScript turn out to be "0180" as expected.


Thanks in advance!

Matt
Farthom (OP)
Newbie
*
Offline Offline

Activity: 14
Merit: 0


View Profile
January 17, 2014, 02:47:59 AM
 #2

In case anyone would like more context here, this is an example attempted submission. (Submitted hex to "submitblock")

0200000062BDE75A8EF452C5489925E0439FFB42DA9C03B9152E4F361C75C2D400000000A548FD7 DADA0874163A7480A114F1EB2DE0A1BA0CFF667444867A421907865A14999D852FFFF001D600B96 520101000000010000000000000000000000000000000000000000000000000000000000000000f fffffff20018000002f503253482f04b8864e50080800000209020000072f736c7573682f000000 000100f2052a010000001976a91445434bcc52d8e4255d1a5d624854b11fd3a9853188ac0000000
techwtf
Full Member
***
Offline Offline

Activity: 140
Merit: 100


View Profile
January 17, 2014, 03:04:39 AM
 #3

the last byte should be less than or equal 127, the correct encoding is "02 80 00".

maybe you should use unsigned int.
Farthom (OP)
Newbie
*
Offline Offline

Activity: 14
Merit: 0


View Profile
January 17, 2014, 03:27:07 AM
 #4

I'm confused, the varint spec says single byte storage is good up to 252

< 0xfd    1    uint8_t
Farthom (OP)
Newbie
*
Offline Offline

Activity: 14
Merit: 0


View Profile
January 17, 2014, 03:37:03 AM
 #5

I'm also assuming it uses "varint" as specified on the bitcoin wiki. I guess I am confused over what determines the "length" of a number.
deepceleron
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
January 17, 2014, 04:12:20 PM
 #6

It depends on which "varint" is being used...

Quote
// Variable-length integers: bytes are a MSB base-128 encoding of the number.
// The high bit in each byte signifies whether another digit follows. To make
// the encoding is one-to-one, one is subtracted from all but the last digit.
// Thus, the byte sequence a[] with length len, where all but the last byte
// has bit 128 set, encodes the number:
//
//   (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1))
//
// Properties:
// * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes)
// * Every integer has exactly one encoding
// * Encoding does not depend on size of original integer type
// * No redundancy: every (infinite) byte sequence corresponds to a list
//   of encoded integers.
//
// 0:         [0x00]  256:        [0x81 0x00]
// 1:         [0x01]  16383:      [0xFE 0x7F]
// 127:       [0x7F]  16384:      [0xFF 0x00]
// 128:  [0x80 0x00]  16511: [0x80 0xFF 0x7F]
// 255:  [0x80 0x7F]  65535: [0x82 0xFD 0x7F]
// 2^32:           [0x8E 0xFE 0xFE 0xFF 0x00]

the DER-encoded signatures uses a data format with octet lengths specified in ASN.1 http://luca.ntop.org/Teaching/Appunti/asn1.html
TierNolan
Legendary
*
Offline Offline

Activity: 1232
Merit: 1084


View Profile
January 17, 2014, 04:20:58 PM
 #7

BIP-34 defines it as

byte: length
byte[length]: height

It doesn't define if height is signed or not.

I think the likely problem is that it is interpreted as a signed number.

01 80 means -128 in signed binary.

You need to add a 00 byte to guarantee that it works.

02 0080 would be 128.

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
Farthom (OP)
Newbie
*
Offline Offline

Activity: 14
Merit: 0


View Profile
January 18, 2014, 04:03:55 AM
Last edit: January 18, 2014, 04:20:39 AM by Farthom
 #8

Thank you deepceleron for your answer. I'm convinced what you posted is correct, but I am stumped by one last thing. I've used the "BouncyCastle" library for .NET to perform this encoding. Sample code:

DerInteger integ = new DerInteger((int)template.Height);
byte[] heightBytes = integ.GetDerEncoded();
string hex = Util.ByteArrayToString(heightBytes);
hex = hex.Substring(2); //Strip off the INTEGER starting tag "02"

For value 128 this results in:
02 00 80
Rather than the expected
02 80 00

Why does bitcoin differ in byte order from the specification? I suppose it is easy enough to write some byte order reversing logic, but I want to make sure I'm not missing something.
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!