support array of uint64
This commit is contained in:
parent
f1dcee2749
commit
4fc9a84c57
|
@ -264,7 +264,7 @@ type
|
|||
## Needed to process attestations, older to newer
|
||||
|
||||
state_roots*: HashArray[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
|
||||
historical_roots*: List[Eth2Digest, HISTORICAL_ROOTS_LIMIT]
|
||||
historical_roots*: HashList[Eth2Digest, HISTORICAL_ROOTS_LIMIT]
|
||||
|
||||
# Eth1
|
||||
eth1_data*: Eth1Data
|
||||
|
@ -280,7 +280,7 @@ type
|
|||
randao_mixes*: HashArray[EPOCHS_PER_HISTORICAL_VECTOR, Eth2Digest]
|
||||
|
||||
# Slashings
|
||||
slashings*: array[EPOCHS_PER_SLASHINGS_VECTOR, uint64] ##\
|
||||
slashings*: HashArray[EPOCHS_PER_SLASHINGS_VECTOR, uint64] ##\
|
||||
## Per-epoch sums of slashed effective balances
|
||||
|
||||
# Attestations
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
import
|
||||
options, algorithm, options, strformat, typetraits,
|
||||
stew/[bitops2, bitseqs, endians2, objects, varints, ptrops],
|
||||
stew/[bitops2, byteutils, bitseqs, endians2, objects, varints, ptrops],
|
||||
stew/ranges/ptr_arith, stew/shims/macros,
|
||||
faststreams/[inputs, outputs, buffers],
|
||||
serialization, serialization/testing/tracing,
|
||||
|
@ -586,18 +586,27 @@ func hashTreeRootAux[T](x: T): Eth2Digest =
|
|||
unsupported T
|
||||
|
||||
func mergedDataHash(x: HashList|HashArray, dataIdx: int64): Eth2Digest =
|
||||
trs "DATA HASH ", dataIdx, " ", x.data.len
|
||||
when x.T is uint64:
|
||||
when cpuEndian == bigEndian:
|
||||
unsupported type x
|
||||
let
|
||||
pos = offset(cast[ptr byte](unsafeAddr x.data[0]), dataIdx.int * 32)
|
||||
pos2 = offset(pos, 32)
|
||||
|
||||
if dataIdx + 1 > x.data.len():
|
||||
zeroHashes[x.maxDepth]
|
||||
elif dataIdx + 1 == x.data.len():
|
||||
mergeBranches(
|
||||
hash_tree_root(x.data[dataIdx]),
|
||||
Eth2Digest())
|
||||
hash(makeOpenArray(pos, 32), makeOpenArray(pos2, 32))
|
||||
else:
|
||||
mergeBranches(
|
||||
hash_tree_root(x.data[dataIdx]),
|
||||
hash_tree_root(x.data[dataIdx + 1]))
|
||||
trs "DATA HASH ", dataIdx, " ", x.data.len
|
||||
|
||||
if dataIdx + 1 > x.data.len():
|
||||
zeroHashes[x.maxDepth]
|
||||
elif dataIdx + 1 == x.data.len():
|
||||
mergeBranches(
|
||||
hash_tree_root(x.data[dataIdx]),
|
||||
Eth2Digest())
|
||||
else:
|
||||
mergeBranches(
|
||||
hash_tree_root(x.data[dataIdx]),
|
||||
hash_tree_root(x.data[dataIdx + 1]))
|
||||
|
||||
func cachedHash*(x: HashList, vIdx: int64): Eth2Digest =
|
||||
doAssert vIdx >= 1
|
||||
|
@ -655,10 +664,7 @@ func hash_tree_root*(x: auto): Eth2Digest {.raises: [Defect], nbench.} =
|
|||
mixin toSszType
|
||||
|
||||
result = when x is HashArray:
|
||||
if x.hashes.len < 2:
|
||||
zeroHashes[log2trunc(uint64(x.data.len() + 1))]
|
||||
else:
|
||||
cachedHash(x, 1)
|
||||
cachedHash(x, 1)
|
||||
elif x is HashList:
|
||||
if x.hashes.len < 2:
|
||||
mixInLength(zeroHashes[x.maxDepth], x.data.len())
|
||||
|
|
|
@ -9,6 +9,13 @@ import
|
|||
const
|
||||
offsetSize* = 4
|
||||
|
||||
func hashChunks(maxLen: int64, T: type): int64 =
|
||||
# For simplificy of implementation, HashArray only supports a few types - this
|
||||
# could/should obviously be extended
|
||||
when T is uint64:
|
||||
maxLen * sizeof(T) div 32
|
||||
else: maxLen
|
||||
|
||||
type
|
||||
UintN* = SomeUnsignedInt # TODO: Add StUint here
|
||||
BasicType* = bool|UintN
|
||||
|
@ -33,7 +40,7 @@ type
|
|||
|
||||
HashArray*[maxLen: static int; T] = object
|
||||
data*: array[maxLen, T]
|
||||
hashes* {.dontSerialize.}: array[maxLen, Eth2Digest]
|
||||
hashes* {.dontSerialize.}: array[hashChunks(maxLen, T), Eth2Digest]
|
||||
|
||||
HashList*[T; maxLen: static int64] = object
|
||||
data*: List[T, maxLen]
|
||||
|
@ -98,7 +105,10 @@ template clearCache*(v: var Eth2Digest) =
|
|||
|
||||
proc clearTree*(a: var HashArray, dataIdx: auto) =
|
||||
## Clear all cache entries after data at dataIdx has been modified
|
||||
var idx = 1 shl (a.maxDepth - 1) + int(dataIdx div 2)
|
||||
when a.T is uint64:
|
||||
var idx = 1 shl (a.maxDepth - 1) + int(dataIdx div 8)
|
||||
else:
|
||||
var idx = 1 shl (a.maxDepth - 1) + int(dataIdx div 2)
|
||||
while idx != 0:
|
||||
clearCache(a.hashes[idx])
|
||||
idx = idx div 2
|
||||
|
@ -123,9 +133,13 @@ template layer*(vIdx: int64): int =
|
|||
## index 0 for the mixed-in-length
|
||||
log2trunc(vIdx.uint64).int
|
||||
|
||||
template maxChunks*(a: HashList|HashArray): int64 =
|
||||
## Layer where data is
|
||||
hashChunks(a.maxLen, a.T)
|
||||
|
||||
template maxDepth*(a: HashList|HashArray): int =
|
||||
## Layer where data is
|
||||
layer(a.maxLen)
|
||||
layer(a.maxChunks)
|
||||
|
||||
proc clearTree*(a: var HashList, dataIdx: auto) =
|
||||
if a.hashes.len == 0:
|
||||
|
|
|
@ -95,9 +95,8 @@ suiteReport "SSZ navigator":
|
|||
let root = hash_tree_root(leaves)
|
||||
check $root == "5248085B588FAB1DD1E03F3CD62201602B12E6560665935964F46E805977E8C5"
|
||||
|
||||
while leaves.len < leaves.maxLen:
|
||||
leaves.add c
|
||||
check hash_tree_root(leaves) == hash_tree_root(leaves.data)
|
||||
leaves.add c
|
||||
check hash_tree_root(leaves) == hash_tree_root(leaves.data)
|
||||
|
||||
suiteReport "SSZ dynamic navigator":
|
||||
timedTest "navigating fields":
|
||||
|
@ -155,3 +154,10 @@ suiteReport "hash":
|
|||
both: it.arr[0].data[0] = byte 1
|
||||
|
||||
both: it.li.add Eth2Digest()
|
||||
|
||||
|
||||
var y: HashArray[32, uint64]
|
||||
|
||||
doAssert hash_tree_root(y) == hash_tree_root(y.data)
|
||||
y[4] = 42'u64
|
||||
doAssert hash_tree_root(y) == hash_tree_root(y.data)
|
||||
|
|
Loading…
Reference in New Issue