ethereumjs / ethereumjs-block

Project is in active development and has been moved to the EthereumJS VM monorepo.
https://github.com/ethereumjs/ethereumjs-vm/tree/master/packages/block
Mozilla Public License 2.0
42 stars 49 forks source link

Nonce should never be 0 bytes #42

Closed AusIV closed 6 years ago

AusIV commented 6 years ago

I have a project where we're trying to use Ganache to test our services that are written in Go. The RPC client that ships with Geth ignores the hash provided by RPC and recalculates it instead. Due to some discrepancies between the value used to calculate the hash and the values served over RPC, the Go client is unable to compute the same hash as Ganache.

One of the issues we ran into was that ethereumjs-block defaults to an empty nonce, while according to the spec a nonce should be 8 bytes. When computing the hash, the difference between a 0 byte nonce and a nonce with 8 null bytes is obviously significant.

With this change along with a couple of changes to Ganache's RPC encoding, the Ethereum client within Geth computes the same block hashes as Ganache.

coveralls commented 6 years ago

Coverage Status

Coverage remained the same at 70.213% when pulling 4833c54593b152b601a2e1b976cf9c43c2af849a on NoteGio:full-size-nonce into 8641dc9867ca3fdfffbcb66980499f19a0a26e54 on ethereumjs:master.

holgerd77 commented 6 years ago

Could you link to the specification where this is defined? (And what is with the other default values?)

AusIV commented 6 years ago

Page 5 of the yellow paper defines the nonce as :

A 64-bit value which, combined with the mixhash, proves that a sufficient amount of computation has been carried out on this block; formally Hn.

No default is specified, but the current default in ethereumjs-block is not 64 bits.

For my purposes it doesn't matter what the default is, so long as it's the right number of bits. Ultimately the geth ethereum client reads whatever it is provided into an 8 byte array. If no value is provided it ends up with eight null bytes, which it uses when computing the hash. If ethereumjs-block decides to use some other default, I'll pass that value to the geth ethereum client and it will still compute the same hash. The problem right now is that ethereumjs-block is using 0 bits for the nonce, and the ethereum geth client always uses a 64 bit nonce.