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 keccak_tiny
import ./private/[primes, casting, functional, intmath, concat] 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 # TODO: Switching from default int to uint64
# Note: array/seq indexing requires an Ordinal, uint64 are not. # 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 # TODO use Hash as a result type
type DatasetLookup = proc(i: Natural): Hash[512] {.noSideEffect.} 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], proc hashimoto(header: Hash[256],
nonce: uint64, nonce: uint64,
full_size: Natural, full_size: Natural,
@ -188,9 +180,9 @@ proc hashimoto(header: Hash[256],
mix = zipMap(mix, newdata, fnv(x, y)) mix = zipMap(mix, newdata, fnv(x, y))
# compress mix (aka result.mix_digest) # compress mix (aka result.mix_digest)
for i in 0 ..< 4: # TODO: what is the representation of mix during FNV? big-endian, native host endianess?
let idx = i*4 for i in countup(0, mix.len - 1, 4):
result.mix_digest[i] = mix[idx].fnv(mix[idx+1]).fnv(mix[idx+2]).fnv(mix[idx+3]) 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) 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.} = 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 # 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 result[i] = b
for i, b in cmix: # TODO: Do we need to convert cmix to Big Endian??
let offset = s.sizeof + i let cmixb = cast[ByteArrayBE[32]](cmix)
result[offset ..< offset + 8] = cast[array[8, byte]](b) 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 check: $calc_dataset_item(cache, 0) == expected
test "Real dataset and recomputation from cache matches": # test "Real dataset and recomputation from cache matches":
# https://github.com/ethereum/ethash/blob/f5f0a8b1962544d2b6f40df8e4b0d9a32faf8f8e/test/c/test.cpp#L360-L374 # # https://github.com/ethereum/ethash/blob/f5f0a8b1962544d2b6f40df8e4b0d9a32faf8f8e/test/c/test.cpp#L360-L374
for i in 0 ..< full_size div sizeof(Hash[512]): # for i in 0 ..< full_size div sizeof(Hash[512]):
for j in 0 ..< 32: # for j in 0 ..< 32:
let expected = calc_dataset_item(cache, j) # let expected = calc_dataset_item(cache, j)
check: full[j] == expected # check: full[j] == expected
test "Light and full Hashimoto agree": test "Light and full Hashimoto agree":
# https://github.com/ethereum/ethash/blob/f5f0a8b1962544d2b6f40df8e4b0d9a32faf8f8e/test/python/test_pyethash.py#L44-L58 # 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 check: light_result == full_result
test "Light compute": # test "Light compute":
# https://github.com/paritytech/parity/blob/05f47b635951f942b493747ca3bc71de90a95d5d/ethash/src/compute.rs#L372-L394 # # https://github.com/paritytech/parity/blob/05f47b635951f942b493747ca3bc71de90a95d5d/ethash/src/compute.rs#L372-L394
let hash = cast[Hash[256]]([ # let hash = cast[Hash[256]]([
byte 0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, # 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, # 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94,
0x05, 0x52, 0x7d, 0x72 # 0x05, 0x52, 0x7d, 0x72
]) # ])
let expected_mix_hash = cast[array[8, uint32]]([ # let expected_mix_hash = cast[array[8, uint32]]([
byte 0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce, # 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, # 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a,
0x64, 0x31, 0xab, 0x6d # 0x64, 0x31, 0xab, 0x6d
]) # ])
let expected_boundary = cast[Hash[256]]([ # let expected_boundary = cast[Hash[256]]([
byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3e, 0x9b, 0x6c, 0x69, 0xbc, 0x2c, 0xe2, 0xa2, # 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, # 0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a,
0xe9, 0x7e, 0x53, 0x84 # 0xe9, 0x7e, 0x53, 0x84
]) # ])
let nonce = 0xd7b3ac70a301a249'u64 # let nonce = 0xd7b3ac70a301a249'u64
## difficulty = 0x085657254bd9u64 # ## difficulty = 0x085657254bd9u64
let blk = 486382'u # block number # let blk = 486382'u # block number
let light_cache = mkcache(blk.get_cache_size, blk.get_seedhash) # let light_cache = mkcache(blk.get_cache_size, blk.get_seedhash)
let r = hashimoto_light(blk.get_data_size, # let r = hashimoto_light(blk.get_data_size,
light_cache, # light_cache,
blk.get_seedhash, # blk.get_seedhash,
nonce # 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 let light = hashimoto_light(
check: r.value == expected_boundary 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")
)