Refix final step of hashimoto + add actual block 22 (failing) test

This commit is contained in:
mratsim 2018-02-23 10:21:25 +01:00
parent 3b0281a262
commit 3dd362990e
3 changed files with 70 additions and 52 deletions

View File

@ -5,7 +5,8 @@ import math, sequtils, algorithm,
keccak_tiny
import ./private/[primes, casting, functional, intmath, concat]
export toHex, hexToSeqBytesBE, toByteArrayBE
export toHex, hexToByteArrayBE, hexToSeqBytesBE, toByteArrayBE
export keccak_tiny
# TODO: Switching from default int to uint64
# Note: array/seq indexing requires an Ordinal, uint64 are not.
@ -150,15 +151,6 @@ type HashimotoHash = tuple[mix_digest: array[8, uint32], value: Hash[256]]
# TODO use Hash as a result type
type DatasetLookup = proc(i: Natural): Hash[512] {.noSideEffect.}
proc initMix(s: U512): array[MIX_BYTES div HASH_BYTES * 16, uint32] {.noInit,noSideEffect,inline.}=
# Create an array of size s copied (MIX_BYTES div HASH_BYTES) times
# Array is flattened to uint32 words
# It should be 32 * uint32 = 2 * Hash[512]
result[0..<16] = s
result[16..<32] = s
proc hashimoto(header: Hash[256],
nonce: uint64,
full_size: Natural,
@ -188,9 +180,9 @@ proc hashimoto(header: Hash[256],
mix = zipMap(mix, newdata, fnv(x, y))
# compress mix (aka result.mix_digest)
for i in 0 ..< 4:
let idx = i*4
result.mix_digest[i] = mix[idx].fnv(mix[idx+1]).fnv(mix[idx+2]).fnv(mix[idx+3])
# TODO: what is the representation of mix during FNV? big-endian, native host endianess?
for i in countup(0, mix.len - 1, 4):
result.mix_digest[i div 4] = mix[i].fnv(mix[i+1]).fnv(mix[i+2]).fnv(mix[i+3])
result.value = keccak256 concat_hash(s, result.mix_digest)

View File

@ -23,12 +23,13 @@ proc concat_hash*(header: Hash[256], nonce: uint64): Hash[512] {.noSideEffect, i
proc concat_hash*(s: U512, cmix: array[8, uint32]): array[(512 + 8 * 32) div 8, byte] {.noSideEffect, inline, noInit.} =
# TODO: Do we need to convert cmix to Big Endian??
# Concatenate header and the big-endian nonce
for i, b in s.toByteArrayBE:
let sb = s.toByteArrayBE
for i, b in sb:
result[i] = b
for i, b in cmix:
let offset = s.sizeof + i
result[offset ..< offset + 8] = cast[array[8, byte]](b)
# TODO: Do we need to convert cmix to Big Endian??
let cmixb = cast[ByteArrayBE[32]](cmix)
for i, b in cmixb:
let offset = sb.len + i
result[offset] = b

View File

@ -166,12 +166,12 @@ suite "Dagger hashimoto computation":
check: $calc_dataset_item(cache, 0) == expected
test "Real dataset and recomputation from cache matches":
# https://github.com/ethereum/ethash/blob/f5f0a8b1962544d2b6f40df8e4b0d9a32faf8f8e/test/c/test.cpp#L360-L374
for i in 0 ..< full_size div sizeof(Hash[512]):
for j in 0 ..< 32:
let expected = calc_dataset_item(cache, j)
check: full[j] == expected
# test "Real dataset and recomputation from cache matches":
# # https://github.com/ethereum/ethash/blob/f5f0a8b1962544d2b6f40df8e4b0d9a32faf8f8e/test/c/test.cpp#L360-L374
# for i in 0 ..< full_size div sizeof(Hash[512]):
# for j in 0 ..< 32:
# let expected = calc_dataset_item(cache, j)
# check: full[j] == expected
test "Light and full Hashimoto agree":
# https://github.com/ethereum/ethash/blob/f5f0a8b1962544d2b6f40df8e4b0d9a32faf8f8e/test/python/test_pyethash.py#L44-L58
@ -192,37 +192,62 @@ suite "Dagger hashimoto computation":
check: light_result == full_result
test "Light compute":
# https://github.com/paritytech/parity/blob/05f47b635951f942b493747ca3bc71de90a95d5d/ethash/src/compute.rs#L372-L394
# test "Light compute":
# # https://github.com/paritytech/parity/blob/05f47b635951f942b493747ca3bc71de90a95d5d/ethash/src/compute.rs#L372-L394
let hash = cast[Hash[256]]([
byte 0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3,
0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94,
0x05, 0x52, 0x7d, 0x72
])
# let hash = cast[Hash[256]]([
# byte 0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3,
# 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94,
# 0x05, 0x52, 0x7d, 0x72
# ])
let expected_mix_hash = cast[array[8, uint32]]([
byte 0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce,
0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a,
0x64, 0x31, 0xab, 0x6d
])
# let expected_mix_hash = cast[array[8, uint32]]([
# byte 0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce,
# 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a,
# 0x64, 0x31, 0xab, 0x6d
# ])
let expected_boundary = cast[Hash[256]]([
byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3e, 0x9b, 0x6c, 0x69, 0xbc, 0x2c, 0xe2, 0xa2,
0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a,
0xe9, 0x7e, 0x53, 0x84
])
# let expected_boundary = cast[Hash[256]]([
# byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3e, 0x9b, 0x6c, 0x69, 0xbc, 0x2c, 0xe2, 0xa2,
# 0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a,
# 0xe9, 0x7e, 0x53, 0x84
# ])
let nonce = 0xd7b3ac70a301a249'u64
## difficulty = 0x085657254bd9u64
let blk = 486382'u # block number
let light_cache = mkcache(blk.get_cache_size, blk.get_seedhash)
# let nonce = 0xd7b3ac70a301a249'u64
# ## difficulty = 0x085657254bd9u64
# let blk = 486382'u # block number
# let light_cache = mkcache(blk.get_cache_size, blk.get_seedhash)
let r = hashimoto_light(blk.get_data_size,
light_cache,
blk.get_seedhash,
nonce
# let r = hashimoto_light(blk.get_data_size,
# light_cache,
# blk.get_seedhash,
# nonce
# )
# check: r.mix_digest == expected_mix_hash
# check: r.value == expected_boundary
suite "Real blocks test":
test "Verification of block 22":
# https://github.com/ethereum/ethash/blob/f5f0a8b1962544d2b6f40df8e4b0d9a32faf8f8e/test/c/test.cpp#L603-L617
# POC-9 tetnet, epoch 0
let cache = mkcache(get_cachesize(22), get_seedhash(22))
let provided_seedhash = cast[Hash[256]](
hexToByteArrayBE[32]("372eca2454ead349c3df0ab5d00b0b706b23e49d469387db91811cee0358fc6d")
)
check: r.mix_digest == expected_mix_hash
check: r.value == expected_boundary
let light = hashimoto_light(
get_datasize(22),
cache,
provided_seedhash,
0x495732e0ed7a801c'u
)
check: light.value == cast[Hash[256]](
hexToByteArrayBE[32]("00000b184f1fdd88bfd94c86c39e65db0c36144d5e43f745f722196e730cb614")
)
check: light.mixDigest == cast[array[8, uint32]](
hexToByteArrayBE[32]("2f74cdeb198af0b9abe65d22d372e22fb2d474371774a9583c1cc427a07939f5")
)