2018-09-20 15:45:02 +00:00
|
|
|
# beacon_chain
|
|
|
|
# Copyright (c) 2018 Status Research & Development GmbH
|
|
|
|
# Licensed and distributed under either of
|
2019-11-25 15:30:02 +00:00
|
|
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
2018-09-20 15:45:02 +00:00
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2019-11-14 10:47:55 +00:00
|
|
|
{.used.}
|
|
|
|
|
2018-09-20 15:45:02 +00:00
|
|
|
import
|
2020-04-11 08:51:07 +00:00
|
|
|
unittest, options, json_serialization,
|
2020-05-20 17:05:22 +00:00
|
|
|
nimcrypto, eth/common, serialization/testing/generic_suite,
|
2019-12-05 10:27:00 +00:00
|
|
|
./testutil,
|
2019-07-03 07:35:05 +00:00
|
|
|
../beacon_chain/spec/[datatypes, digest],
|
2019-11-01 15:14:34 +00:00
|
|
|
../beacon_chain/ssz, ../beacon_chain/ssz/[navigator, dynamic_navigator]
|
2019-07-03 07:35:05 +00:00
|
|
|
|
|
|
|
type
|
|
|
|
SomeEnum = enum
|
|
|
|
A, B, C
|
|
|
|
|
|
|
|
Simple = object
|
|
|
|
flag: bool
|
|
|
|
# ignored {.dontSerialize.}: string
|
|
|
|
# data: array[256, bool]
|
|
|
|
|
|
|
|
template reject(stmt) =
|
2019-11-22 15:47:08 +00:00
|
|
|
doAssert(not compiles(stmt))
|
2019-07-03 07:35:05 +00:00
|
|
|
|
|
|
|
static:
|
2019-11-22 15:47:08 +00:00
|
|
|
doAssert isFixedSize(bool) == true
|
2019-07-03 07:35:05 +00:00
|
|
|
|
2019-11-22 15:47:08 +00:00
|
|
|
doAssert fixedPortionSize(array[10, bool]) == 10
|
|
|
|
doAssert fixedPortionSize(array[SomeEnum, uint64]) == 24
|
2020-05-21 13:21:29 +00:00
|
|
|
doAssert fixedPortionSize(array[3..5, List[byte, 256]]) == 12
|
2019-07-03 07:35:05 +00:00
|
|
|
|
2019-11-22 15:47:08 +00:00
|
|
|
doAssert isFixedSize(array[20, bool]) == true
|
|
|
|
doAssert isFixedSize(Simple) == true
|
2020-05-21 13:21:29 +00:00
|
|
|
doAssert isFixedSize(List[bool, 128]) == false
|
2019-07-03 07:35:05 +00:00
|
|
|
|
|
|
|
reject fixedPortionSize(int)
|
|
|
|
|
|
|
|
type
|
|
|
|
ObjWithFields = object
|
|
|
|
f0: uint8
|
|
|
|
f1: uint32
|
|
|
|
f2: EthAddress
|
2019-12-10 00:18:47 +00:00
|
|
|
f3: MDigest[256]
|
2019-07-03 07:35:05 +00:00
|
|
|
f4: seq[byte]
|
|
|
|
f5: ValidatorIndex
|
|
|
|
|
|
|
|
static:
|
2019-11-22 15:47:08 +00:00
|
|
|
doAssert fixedPortionSize(ObjWithFields) ==
|
|
|
|
1 + 4 + sizeof(EthAddress) + (256 div 8) + 4 + 8
|
2019-07-03 07:35:05 +00:00
|
|
|
|
|
|
|
executeRoundTripTests SSZ
|
|
|
|
|
|
|
|
type
|
|
|
|
Foo = object
|
|
|
|
bar: Bar
|
|
|
|
|
2020-05-21 13:21:29 +00:00
|
|
|
BarList = List[uint64, 128]
|
|
|
|
|
2019-07-03 07:35:05 +00:00
|
|
|
Bar = object
|
2020-05-21 13:21:29 +00:00
|
|
|
b: BarList
|
2019-07-03 07:35:05 +00:00
|
|
|
baz: Baz
|
|
|
|
|
|
|
|
Baz = object
|
|
|
|
i: uint64
|
|
|
|
|
2019-08-16 16:50:04 +00:00
|
|
|
proc toDigest[N: static int](x: array[N, byte]): Eth2Digest =
|
|
|
|
result.data[0 .. N-1] = x
|
|
|
|
|
2020-03-10 04:00:19 +00:00
|
|
|
suiteReport "SSZ navigator":
|
2019-12-05 10:27:00 +00:00
|
|
|
timedTest "simple object fields":
|
2020-05-21 13:21:29 +00:00
|
|
|
var foo = Foo(bar: Bar(b: BarList @[1'u64, 2, 3], baz: Baz(i: 10'u64)))
|
2019-07-03 07:35:05 +00:00
|
|
|
let encoded = SSZ.encode(foo)
|
|
|
|
|
|
|
|
check SSZ.decode(encoded, Foo) == foo
|
|
|
|
|
|
|
|
let mountedFoo = sszMount(encoded, Foo)
|
2020-05-21 13:21:29 +00:00
|
|
|
check mountedFoo.bar.b[] == BarList @[1'u64, 2, 3]
|
2019-07-03 07:35:05 +00:00
|
|
|
|
|
|
|
let mountedBar = mountedFoo.bar
|
|
|
|
check mountedBar.baz.i == 10'u64
|
|
|
|
|
2019-12-05 10:27:00 +00:00
|
|
|
timedTest "lists with max size":
|
2019-08-16 16:50:04 +00:00
|
|
|
let a = [byte 0x01, 0x02, 0x03].toDigest
|
|
|
|
let b = [byte 0x04, 0x05, 0x06].toDigest
|
|
|
|
let c = [byte 0x07, 0x08, 0x09].toDigest
|
|
|
|
|
2020-05-18 17:49:22 +00:00
|
|
|
let leaves = List[Eth2Digest, int64(1 shl 3)](@[a, b, c])
|
2019-08-28 12:07:00 +00:00
|
|
|
let root = hash_tree_root(leaves)
|
2019-08-16 16:50:04 +00:00
|
|
|
check $root == "5248085B588FAB1DD1E03F3CD62201602B12E6560665935964F46E805977E8C5"
|
|
|
|
|
2020-05-18 17:49:22 +00:00
|
|
|
let leaves2 = List[Eth2Digest, int64(1 shl 10)](@[a, b, c])
|
2019-08-28 12:07:00 +00:00
|
|
|
let root2 = hash_tree_root(leaves2)
|
2019-08-16 16:50:04 +00:00
|
|
|
check $root2 == "9FB7D518368DC14E8CC588FB3FD2749BEEF9F493FEF70AE34AF5721543C67173"
|
2019-11-01 15:14:34 +00:00
|
|
|
|
2020-03-10 04:00:19 +00:00
|
|
|
suiteReport "SSZ dynamic navigator":
|
2019-12-05 10:27:00 +00:00
|
|
|
timedTest "navigating fields":
|
2020-05-21 13:21:29 +00:00
|
|
|
var fooOrig = Foo(bar: Bar(b: BarList @[1'u64, 2, 3], baz: Baz(i: 10'u64)))
|
2019-11-01 15:14:34 +00:00
|
|
|
let fooEncoded = SSZ.encode(fooOrig)
|
|
|
|
|
2019-11-09 10:46:34 +00:00
|
|
|
var navFoo = DynamicSszNavigator.init(fooEncoded, Foo)
|
2019-11-01 15:14:34 +00:00
|
|
|
|
|
|
|
var navBar = navFoo.navigate("bar")
|
2020-05-21 13:21:29 +00:00
|
|
|
check navBar.toJson(pretty = false) == """{"b":[1,2,3],"baz":{"i":10}}"""
|
2019-11-01 15:14:34 +00:00
|
|
|
|
|
|
|
var navB = navBar.navigate("b")
|
2020-05-21 13:21:29 +00:00
|
|
|
check navB.toJson(pretty = false) == "[1,2,3]"
|
2019-11-01 15:14:34 +00:00
|
|
|
|
|
|
|
var navBaz = navBar.navigate("baz")
|
|
|
|
var navI = navBaz.navigate("i")
|
|
|
|
check navI.toJson == "10"
|
|
|
|
|
|
|
|
expect KeyError:
|
|
|
|
discard navBar.navigate("biz")
|
|
|
|
|