[Tests] SHA256 + official shuffling vectors (#263)
* Change digests to SHA2-256 (from Keccak256) * Fix sha256 digest initialization - pass shuffling test * Add comments + remove old shuffling tests * Remove stale tree hashing tests * Small toOpenArray optim + notes on in-place hashing * Revert "Revert "Update test repo"" This reverts commitf385467cd3
. * Revert "Revert "Fix SIGFPE on shuffling for 0"" This reverts commit226d380f87
. * Revert "Revert "Implement shuffling test (pending typedesc and shuffling algo fix)"" This reverts commit813cb6fbb8
. * withEth2hash templates now needs ctx.init() * Use init-update-finish to avoid burnMem
This commit is contained in:
parent
d977c96ae1
commit
e5047d93a4
|
@ -7,21 +7,20 @@
|
|||
|
||||
# Serenity hash function / digest
|
||||
#
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#hash
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#hash
|
||||
#
|
||||
# In Phase 0 the beacon chain is deployed with the same hash function as
|
||||
# Ethereum 1.0, i.e. Keccak-256 (also incorrectly known as SHA3).
|
||||
# In Phase 0 the beacon chain is deployed with SHA256 (SHA2-256).
|
||||
# Note that is is different from Keccak256 (often mistakenly called SHA3-256)
|
||||
# and SHA3-256.
|
||||
#
|
||||
# Note: We aim to migrate to a S[T/N]ARK-friendly hash function in a future
|
||||
# Ethereum 2.0 deployment phase.
|
||||
# In Eth1.0, the default hash function is Keccak256 and SHA256 is available as a precompiled contract.
|
||||
#
|
||||
# https://crypto.stackexchange.com/questions/15727/what-are-the-key-differences-between-the-draft-sha-3-standard-and-the-keccak-sub
|
||||
#
|
||||
# In our code base, to enable a smooth transition, we call this function
|
||||
# `eth2hash`, and it outputs a `Eth2Digest`. Easy to sed :)
|
||||
# In our code base, to enable a smooth transition
|
||||
# (already did Blake2b --> Keccak256 --> SHA2-256),
|
||||
# we call this function `eth2hash`, and it outputs a `Eth2Digest`. Easy to sed :)
|
||||
|
||||
import
|
||||
nimcrypto/[keccak, hash], eth/common/eth_types_json_serialization,
|
||||
nimcrypto/[sha2, hash], eth/common/eth_types_json_serialization,
|
||||
hashes
|
||||
|
||||
export
|
||||
|
@ -29,17 +28,21 @@ export
|
|||
|
||||
type
|
||||
Eth2Digest* = MDigest[32 * 8] ## `hash32` from spec
|
||||
Eth2Hash* = keccak256 ## Context for hash function
|
||||
Eth2Hash* = sha256 ## Context for hash function
|
||||
|
||||
func shortLog*(x: Eth2Digest): string =
|
||||
# result = is needed to fix https://github.com/status-im/nim-beacon-chain/issues/209
|
||||
result = ($x)[0..7]
|
||||
|
||||
func eth2hash*(v: openArray[byte]): Eth2Digest =
|
||||
var ctx: keccak256 # use explicit type so we can rely on init being useless
|
||||
# We can avoid this step for Keccak/SHA3 digests because `ctx` is already
|
||||
# empty, but if digest will be changed next line must be enabled.
|
||||
# ctx.init()
|
||||
# TODO: expose an in-place digest function
|
||||
# when hashing in loop or into a buffer
|
||||
# See: https://github.com/cheatfate/nimcrypto/blob/b90ba3abd/nimcrypto/sha2.nim#L570
|
||||
func eth2hash*(v: openArray[byte]): Eth2Digest {.inline.} =
|
||||
# We use the init-update-finish interface to avoid
|
||||
# the expensive burning/clearing memory (20~30% perf)
|
||||
# TODO: security implication?
|
||||
var ctx: sha256
|
||||
ctx.init()
|
||||
ctx.update(v)
|
||||
result = ctx.finish()
|
||||
|
||||
|
@ -47,14 +50,14 @@ template withEth2Hash*(body: untyped): Eth2Digest =
|
|||
## This little helper will init the hash function and return the sliced
|
||||
## hash:
|
||||
## let hashOfData = withHash: h.update(data)
|
||||
var h {.inject.}: keccak256
|
||||
# TODO no need, as long as using keccak256: h.init()
|
||||
var h {.inject.}: sha256
|
||||
h.init()
|
||||
body
|
||||
var res = h.finish()
|
||||
res
|
||||
|
||||
func hash*(x: Eth2Digest): Hash =
|
||||
## Hash for Keccak digests for Nim hash tables
|
||||
## Hash for digests for Nim hash tables
|
||||
# Stub for BeaconChainDB
|
||||
|
||||
# We just slice the first 4 or 8 bytes of the block hash
|
||||
|
|
|
@ -12,8 +12,9 @@ import
|
|||
../ssz, ../beacon_node_types,
|
||||
./crypto, ./datatypes, ./digest, ./helpers
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#get_shuffling
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#get_permuted_index
|
||||
# TODO: Proceed to renaming and signature changes
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#get_shuffled_index
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#compute_committee
|
||||
func get_shuffled_seq*(seed: Eth2Digest,
|
||||
list_size: uint64,
|
||||
): seq[ValidatorIndex] =
|
||||
|
@ -25,8 +26,16 @@ func get_shuffled_seq*(seed: Eth2Digest,
|
|||
##
|
||||
## Invert the inner/outer loops from the spec, essentially. Most useful
|
||||
## hash result re-use occurs within a round.
|
||||
|
||||
# Empty size -> empty list.
|
||||
if list_size == 0:
|
||||
return
|
||||
|
||||
var
|
||||
# Share these buffers.
|
||||
# TODO: Redo to follow spec.
|
||||
# We can have an "Impl" private version that takes buffer as parameters
|
||||
# so that we avoid alloc on repeated calls from compute_committee
|
||||
pivot_buffer: array[(32+1), byte]
|
||||
source_buffer: array[(32+1+4), byte]
|
||||
shuffled_active_validator_indices = mapIt(
|
||||
|
@ -44,7 +53,7 @@ func get_shuffled_seq*(seed: Eth2Digest,
|
|||
source_buffer[32] = round_bytes1
|
||||
|
||||
# Only one pivot per round.
|
||||
let pivot = bytes_to_int(eth2hash(pivot_buffer).data[0..7]) mod list_size
|
||||
let pivot = bytes_to_int(eth2hash(pivot_buffer).data.toOpenArray(0, 7)) mod list_size
|
||||
|
||||
## Only need to run, per round, position div 256 hashes, so precalculate
|
||||
## them. This consumes memory, but for low-memory devices, it's possible
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
import
|
||||
endians, typetraits, options, algorithm, math,
|
||||
faststreams/input_stream, serialization, eth/common, nimcrypto/keccak,
|
||||
faststreams/input_stream, serialization, eth/common, nimcrypto/sha2,
|
||||
./spec/[bitfield, crypto, datatypes, digest]
|
||||
|
||||
# ################### Helper functions ###################################
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
import # Unit test
|
||||
./test_attestation_pool,
|
||||
./test_beacon_chain_db,
|
||||
./test_beacon_node,
|
||||
|
@ -15,8 +15,10 @@ import
|
|||
./test_helpers,
|
||||
./test_ssz,
|
||||
./test_state_transition,
|
||||
./test_sync_protocol,
|
||||
./test_validator
|
||||
./test_sync_protocol
|
||||
# ./test_validator # Empty!
|
||||
|
||||
# TODO - re-enable once official test fixtures arrive
|
||||
import # Official fixtures
|
||||
# TODO - re-enable
|
||||
#./official/test_fixture_state
|
||||
./official/test_fixture_shuffling
|
|
@ -1 +1 @@
|
|||
Subproject commit da49e682bf93c43ffc207e4b1b948962c5068196
|
||||
Subproject commit 80c3652796488e62c37087a9bffae60c6b1cefa5
|
|
@ -12,14 +12,15 @@ export nimcrypto.toHex
|
|||
type
|
||||
# TODO: use ref object to avoid allocating
|
||||
# so much on the stack - pending https://github.com/status-im/nim-json-serialization/issues/3
|
||||
StateTest* = object
|
||||
StateTests* = object
|
||||
title*: string
|
||||
summary*: string
|
||||
test_suite*: string
|
||||
fork*: string
|
||||
test_cases*: seq[TestCase]
|
||||
test_cases*: seq[StateTestCase]
|
||||
|
||||
TestConstants* = object
|
||||
# TODO - 0.5.1 constants
|
||||
SHARD_COUNT*: int
|
||||
TARGET_COMMITTEE_SIZE*: int
|
||||
MAX_BALANCE_CHURN_QUOTIENT*: int
|
||||
|
@ -66,13 +67,30 @@ type
|
|||
DOMAIN_VOLUNTARY_EXIT*: SignatureDomain
|
||||
DOMAIN_TRANSFER*: SignatureDomain
|
||||
|
||||
TestCase* = object
|
||||
StateTestCase* = object
|
||||
name*: string
|
||||
config*: TestConstants
|
||||
verify_signatures*: bool
|
||||
initial_state*: BeaconState
|
||||
blocks*: seq[BeaconBlock]
|
||||
expected_state*: BeaconState
|
||||
|
||||
ShufflingTests* = object
|
||||
title*: string
|
||||
summary*: string
|
||||
forks_timeline*: string
|
||||
forks*: seq[string]
|
||||
config*: string
|
||||
runner*: string
|
||||
handler*: string
|
||||
test_cases*: seq[ShufflingTestCase]
|
||||
|
||||
ShufflingTestCase* = object
|
||||
seed*: Eth2Digest
|
||||
count*: uint64
|
||||
shuffled*: seq[ValidatorIndex]
|
||||
|
||||
Tests* = StateTests or ShufflingTests
|
||||
|
||||
# #######################
|
||||
# Default init
|
||||
|
@ -89,9 +107,27 @@ proc readValue*[N: static int](r: var JsonReader, a: var array[N, byte]) {.inlin
|
|||
# if so export that to nim-eth
|
||||
hexToByteArray(r.readValue(string), a)
|
||||
|
||||
proc parseStateTests*(jsonPath: string): StateTest =
|
||||
proc readValue*(r: var JsonReader, a: var ValidatorIndex) {.inline.} =
|
||||
a = r.readValue(uint32)
|
||||
|
||||
# TODO: cannot pass a typedesc
|
||||
# proc parseTests*(jsonPath: string, T: typedesc[Tests]): T =
|
||||
# # TODO: due to generic early symbol resolution
|
||||
# # we cannot use a generic proc
|
||||
# # Otherwise we get:
|
||||
# # "Error: undeclared identifier: 'ReaderType'"
|
||||
# # Templates, even untyped don't work
|
||||
# try:
|
||||
# result = Json.loadFile(jsonPath, T)
|
||||
# except SerializationError as err:
|
||||
# writeStackTrace()
|
||||
# stderr.write "Json load issue for file \"", jsonPath, "\"\n"
|
||||
# stderr.write err.formatMsg(jsonPath), "\n"
|
||||
# quit 1
|
||||
|
||||
proc parseTests*(jsonPath: string): ShufflingTests =
|
||||
try:
|
||||
result = Json.loadFile(jsonPath, StateTest)
|
||||
result = Json.loadFile(jsonPath, ShufflingTests)
|
||||
except SerializationError as err:
|
||||
writeStackTrace()
|
||||
stderr.write "Json load issue for file \"", jsonPath, "\"\n"
|
|
@ -0,0 +1,30 @@
|
|||
# beacon_chain
|
||||
# Copyright (c) 2018 Status Research & Development GmbH
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
# Standard libs
|
||||
ospaths, strutils, json, unittest,
|
||||
# Third parties
|
||||
|
||||
# Beacon chain internals
|
||||
../../beacon_chain/spec/validator,
|
||||
# Test utilities
|
||||
./fixtures_utils
|
||||
|
||||
const TestFolder = currentSourcePath.rsplit(DirSep, 1)[0]
|
||||
const TestsPath = "fixtures" / "json_tests" / "shuffling" / "core" / "shuffling_full.json"
|
||||
|
||||
var shufflingTests: ShufflingTests
|
||||
|
||||
suite "Official - Shuffling tests":
|
||||
test "Parsing the official shuffling tests":
|
||||
shufflingTests = parseTests(TestFolder / TestsPath)
|
||||
|
||||
test "Shuffling a sequence of N validators":
|
||||
for t in shufflingTests.test_cases:
|
||||
let implResult = get_shuffled_seq(t.seed, t.count)
|
||||
check: implResult == t.shuffled
|
|
@ -14,17 +14,17 @@ import
|
|||
../../beacon_chain/spec/[datatypes, crypto, digest, beaconstate],
|
||||
../../beacon_chain/[ssz, state_transition],
|
||||
# Test utilities
|
||||
./state_test_utils
|
||||
./fixtures_utils
|
||||
|
||||
const TestFolder = currentSourcePath.rsplit(DirSep, 1)[0]
|
||||
const TestsPath = "fixtures" / "json_tests" / "state" / "sanity-check_default-config_100-vals.json"
|
||||
|
||||
|
||||
var stateTests: StateTest
|
||||
var stateTests: StateTests
|
||||
suite "Official - State tests": # Initializing a beacon state from the deposits
|
||||
# Source: https://github.com/ethereum/eth2.0-specs/blob/2baa242ac004b0475604c4c4ef4315e14f56c5c7/tests/phase0/test_sanity.py#L55-L460
|
||||
test "Parsing the official state tests into Nimbus beacon types":
|
||||
stateTests = parseStateTests(TestFolder / TestsPath)
|
||||
stateTests = parseTests(TestFolder / TestsPath, StateTests) # TODO pending typedesc fix in fixture_utils.nim
|
||||
doAssert $stateTests.test_cases[0].name == "test_empty_block_transition"
|
||||
|
||||
test "[For information - Non-blocking] Block root signing":
|
||||
|
|
|
@ -78,18 +78,18 @@ suite "Simple serialization":
|
|||
slot: 42.Slot, signature: sign(SigKey.random(), 0'u64, ""))
|
||||
SSZ.roundripTest BeaconState(slot: 42.Slot)
|
||||
|
||||
suite "Tree hashing":
|
||||
# TODO The test values are taken from an earlier version of SSZ and have
|
||||
# nothing to do with upstream - needs verification and proper test suite
|
||||
# suite "Tree hashing":
|
||||
# # TODO The test values are taken from an earlier version of SSZ and have
|
||||
# # nothing to do with upstream - needs verification and proper test suite
|
||||
|
||||
test "Hash BeaconBlock":
|
||||
let vr = BeaconBlock()
|
||||
check:
|
||||
$hash_tree_root(vr) ==
|
||||
"8951C9C64ABA469EBA78F5D9F9A0666FB697B8C4D86901445777E4445D0B1543"
|
||||
# test "Hash BeaconBlock":
|
||||
# let vr = BeaconBlock()
|
||||
# check:
|
||||
# $hash_tree_root(vr) ==
|
||||
# "8951C9C64ABA469EBA78F5D9F9A0666FB697B8C4D86901445777E4445D0B1543"
|
||||
|
||||
test "Hash BeaconState":
|
||||
let vr = BeaconState()
|
||||
check:
|
||||
$hash_tree_root(vr) ==
|
||||
"66F9BF92A690F1FBD36488D98BE70DA6C84100EDF935BC6D0B30FF14A2976455"
|
||||
# test "Hash BeaconState":
|
||||
# let vr = BeaconState()
|
||||
# check:
|
||||
# $hash_tree_root(vr) ==
|
||||
# "66F9BF92A690F1FBD36488D98BE70DA6C84100EDF935BC6D0B30FF14A2976455"
|
||||
|
|
|
@ -9,76 +9,6 @@ import
|
|||
../beacon_chain/spec/[helpers, datatypes, digest, validator, beaconstate],
|
||||
../beacon_chain/extras
|
||||
|
||||
func sumCommittees(v: openArray[seq[ValidatorIndex]], reqCommitteeLen: int): int =
|
||||
for x in v:
|
||||
## This only holds when num_validators is divisible by
|
||||
## SLOTS_PER_EPOCH * get_committee_count_per_slot(len(validators))
|
||||
## as, in general, not all committees can be equally sized.
|
||||
doAssert x.len == reqCommitteeLen
|
||||
inc result, x.len
|
||||
|
||||
func checkPermutation(index: int, list_size: uint64,
|
||||
permuted_index: int, seed: Eth2Digest): bool =
|
||||
let
|
||||
s = get_shuffled_seq(seed, list_size)
|
||||
s[index] == permuted_index.ValidatorIndex
|
||||
|
||||
suite "Validators":
|
||||
## For now just test that we can compile and execute block processing with mock data.
|
||||
## https://github.com/status-im/nim-beacon-chain/issues/1
|
||||
## https://github.com/sigp/lighthouse/blob/ba548e49a52687a655c61b443b6835d79c6d4236/beacon_chain/validator_shuffling/src/shuffle.rs
|
||||
test "Validator shuffling":
|
||||
let
|
||||
num_validators = 4096
|
||||
genState = get_genesis_beacon_state(
|
||||
makeInitialDeposits(num_validators, flags = {skipValidation}), 0,
|
||||
Eth1Data(), {skipValidation})
|
||||
s = get_shuffling(
|
||||
Eth2Digest(), genState.validator_registry, GENESIS_EPOCH)
|
||||
committees = get_epoch_committee_count(genState, GENESIS_EPOCH).int
|
||||
check:
|
||||
# def b(s): return "Eth2Digest(data: [0x" + "'u8, 0x".join((s[i:i+2] for i in range(0, 64, 2))) + "'u8])"
|
||||
# TODO read YAML file directly from test case generator
|
||||
checkPermutation(0, 1, 0, Eth2Digest(data: [0xc0'u8, 0xc7'u8, 0xf2'u8, 0x26'u8, 0xfb'u8, 0xd5'u8, 0x74'u8, 0xa8'u8, 0xc6'u8, 0x3d'u8, 0xc2'u8, 0x68'u8, 0x64'u8, 0xc2'u8, 0x78'u8, 0x33'u8, 0xea'u8, 0x93'u8, 0x1e'u8, 0x7c'u8, 0x70'u8, 0xb3'u8, 0x44'u8, 0x09'u8, 0xba'u8, 0x76'u8, 0x5f'u8, 0x3d'u8, 0x20'u8, 0x31'u8, 0x63'u8, 0x3d'u8]))
|
||||
checkPermutation(0, 2, 0, Eth2Digest(data: [0xb2'u8, 0x04'u8, 0x20'u8, 0xb2'u8, 0xb7'u8, 0xb1'u8, 0xc6'u8, 0x46'u8, 0x00'u8, 0xcb'u8, 0xe9'u8, 0x62'u8, 0x54'u8, 0x40'u8, 0x52'u8, 0xd0'u8, 0xbb'u8, 0xe1'u8, 0x3d'u8, 0xa4'u8, 0x03'u8, 0x95'u8, 0x0d'u8, 0x19'u8, 0x8d'u8, 0x4f'u8, 0x4e'u8, 0xa2'u8, 0x87'u8, 0x62'u8, 0x95'u8, 0x3f'u8]))
|
||||
checkPermutation(1, 2, 0, Eth2Digest(data: [0x11'u8, 0xf1'u8, 0x32'u8, 0x2c'u8, 0x3a'u8, 0x4c'u8, 0xfc'u8, 0xe2'u8, 0x0e'u8, 0xfb'u8, 0x7d'u8, 0x7e'u8, 0xca'u8, 0x50'u8, 0x29'u8, 0x14'u8, 0x70'u8, 0x04'u8, 0x3d'u8, 0x6e'u8, 0x8a'u8, 0x2c'u8, 0x62'u8, 0x95'u8, 0x6e'u8, 0x68'u8, 0x75'u8, 0x71'u8, 0x60'u8, 0x7d'u8, 0x3f'u8, 0x0e'u8]))
|
||||
checkPermutation(0, 3, 2, Eth2Digest(data: [0x5b'u8, 0xd0'u8, 0xaf'u8, 0x3f'u8, 0x74'u8, 0xfe'u8, 0x69'u8, 0x86'u8, 0xbb'u8, 0x99'u8, 0xb3'u8, 0xec'u8, 0xc0'u8, 0xea'u8, 0x15'u8, 0xa4'u8, 0x03'u8, 0x45'u8, 0x6c'u8, 0xe7'u8, 0x08'u8, 0xc0'u8, 0x5c'u8, 0xee'u8, 0xed'u8, 0xdc'u8, 0x0a'u8, 0x42'u8, 0x05'u8, 0xca'u8, 0xf0'u8, 0x72'u8]))
|
||||
checkPermutation(1, 3, 1, Eth2Digest(data: [0xba'u8, 0x06'u8, 0xff'u8, 0x9b'u8, 0xde'u8, 0x03'u8, 0xf3'u8, 0x7e'u8, 0xdd'u8, 0xea'u8, 0xcb'u8, 0x26'u8, 0x1a'u8, 0x51'u8, 0x10'u8, 0x96'u8, 0x76'u8, 0xd5'u8, 0x49'u8, 0xc1'u8, 0xbe'u8, 0xa3'u8, 0xb8'u8, 0x1e'u8, 0xdd'u8, 0x82'u8, 0xdf'u8, 0x68'u8, 0xcc'u8, 0x03'u8, 0xa9'u8, 0x7f'u8]))
|
||||
checkPermutation(2, 3, 2, Eth2Digest(data: [0xf5'u8, 0x8a'u8, 0x89'u8, 0x70'u8, 0xc6'u8, 0x3c'u8, 0xa8'u8, 0x6d'u8, 0xd3'u8, 0xb8'u8, 0xb8'u8, 0xa6'u8, 0x15'u8, 0x30'u8, 0x2e'u8, 0xc0'u8, 0x6c'u8, 0xdd'u8, 0xea'u8, 0x12'u8, 0x79'u8, 0xbf'u8, 0x4a'u8, 0x27'u8, 0x25'u8, 0xc7'u8, 0x81'u8, 0xce'u8, 0x6a'u8, 0xba'u8, 0x34'u8, 0x8d'u8]))
|
||||
checkPermutation(0, 1024, 1005, Eth2Digest(data: [0x38'u8, 0x35'u8, 0x56'u8, 0xe2'u8, 0x3f'u8, 0xcb'u8, 0x9e'u8, 0x73'u8, 0xc2'u8, 0x3a'u8, 0xd3'u8, 0x3c'u8, 0xfb'u8, 0x50'u8, 0xf4'u8, 0xc0'u8, 0x98'u8, 0xf4'u8, 0x96'u8, 0x88'u8, 0xa8'u8, 0x4b'u8, 0x12'u8, 0x8c'u8, 0x28'u8, 0x85'u8, 0x96'u8, 0x0e'u8, 0x5f'u8, 0x1b'u8, 0x39'u8, 0x82'u8]))
|
||||
checkPermutation(1023, 1024, 934, Eth2Digest(data: [0x2e'u8, 0xe5'u8, 0xda'u8, 0xb3'u8, 0x0a'u8, 0xd1'u8, 0x58'u8, 0x0c'u8, 0xda'u8, 0xbb'u8, 0x17'u8, 0x5a'u8, 0x4b'u8, 0x15'u8, 0x12'u8, 0xca'u8, 0xc5'u8, 0x56'u8, 0x68'u8, 0x66'u8, 0xd6'u8, 0x5a'u8, 0x15'u8, 0xe9'u8, 0xe2'u8, 0x2c'u8, 0x84'u8, 0x44'u8, 0xf4'u8, 0x60'u8, 0xc9'u8, 0xdc'u8]))
|
||||
checkPermutation(3925, 4040, 32, Eth2Digest(data: [0x34'u8, 0xa3'u8, 0xc1'u8, 0x3f'u8, 0x21'u8, 0x1e'u8, 0x63'u8, 0xc5'u8, 0x6e'u8, 0x9e'u8, 0x11'u8, 0x87'u8, 0xf3'u8, 0x1a'u8, 0x56'u8, 0xa4'u8, 0x23'u8, 0x0d'u8, 0x8d'u8, 0x5b'u8, 0xf5'u8, 0xe5'u8, 0x84'u8, 0xf0'u8, 0xe4'u8, 0xfe'u8, 0x93'u8, 0x94'u8, 0x6a'u8, 0xf9'u8, 0x1c'u8, 0xce'u8]))
|
||||
checkPermutation(885, 2417, 1822, Eth2Digest(data: [0x13'u8, 0x46'u8, 0xe3'u8, 0x97'u8, 0x08'u8, 0x15'u8, 0x10'u8, 0x71'u8, 0x54'u8, 0xb5'u8, 0x8b'u8, 0x1e'u8, 0xff'u8, 0x41'u8, 0x1b'u8, 0xfc'u8, 0xa3'u8, 0x34'u8, 0x2e'u8, 0xa0'u8, 0xd8'u8, 0x28'u8, 0x2a'u8, 0x86'u8, 0x30'u8, 0x4d'u8, 0x79'u8, 0xd6'u8, 0x2d'u8, 0x5f'u8, 0x3c'u8, 0x52'u8]))
|
||||
checkPermutation(840, 1805, 808, Eth2Digest(data: [0x08'u8, 0x10'u8, 0xc1'u8, 0x04'u8, 0xb7'u8, 0x5e'u8, 0x25'u8, 0xbf'u8, 0x89'u8, 0xc0'u8, 0x06'u8, 0x6d'u8, 0xee'u8, 0xbc'u8, 0x34'u8, 0x61'u8, 0x93'u8, 0x7f'u8, 0xc0'u8, 0xe7'u8, 0x2a'u8, 0xe0'u8, 0x4e'u8, 0xe7'u8, 0x4f'u8, 0x24'u8, 0x56'u8, 0x16'u8, 0xc1'u8, 0x57'u8, 0x18'u8, 0xdf'u8]))
|
||||
checkPermutation(881, 1788, 582, Eth2Digest(data: [0x34'u8, 0xad'u8, 0xb3'u8, 0x5f'u8, 0x3f'u8, 0xc2'u8, 0x88'u8, 0x0d'u8, 0x22'u8, 0x0e'u8, 0x52'u8, 0x01'u8, 0x20'u8, 0xa0'u8, 0x32'u8, 0xbb'u8, 0xaa'u8, 0x0f'u8, 0x4b'u8, 0xd7'u8, 0xa5'u8, 0xfc'u8, 0xf1'u8, 0xc2'u8, 0x26'u8, 0x9d'u8, 0xe2'u8, 0x10'u8, 0x75'u8, 0xe7'u8, 0xa4'u8, 0x64'u8]))
|
||||
checkPermutation(1362, 1817, 1018, Eth2Digest(data: [0xc9'u8, 0xb0'u8, 0xc7'u8, 0x6e'u8, 0x11'u8, 0xf4'u8, 0xc3'u8, 0xc3'u8, 0xc3'u8, 0x8b'u8, 0x44'u8, 0x7a'u8, 0xca'u8, 0x53'u8, 0x52'u8, 0xd9'u8, 0x31'u8, 0x32'u8, 0xad'u8, 0x56'u8, 0x78'u8, 0xda'u8, 0x42'u8, 0x0c'u8, 0xa2'u8, 0xe6'u8, 0x9d'u8, 0x92'u8, 0x58'u8, 0x8e'u8, 0x0f'u8, 0xba'u8]))
|
||||
checkPermutation(28, 111, 0, Eth2Digest(data: [0x29'u8, 0x31'u8, 0x45'u8, 0xc3'u8, 0x1a'u8, 0xeb'u8, 0x3e'u8, 0xb2'u8, 0x9c'u8, 0xcd'u8, 0xf3'u8, 0x32'u8, 0x7d'u8, 0x0f'u8, 0x3d'u8, 0xd4'u8, 0x59'u8, 0x2c'u8, 0xdf'u8, 0xb2'u8, 0xfa'u8, 0xd3'u8, 0x70'u8, 0x32'u8, 0x29'u8, 0xc6'u8, 0xc2'u8, 0xe7'u8, 0x20'u8, 0xdc'u8, 0x79'u8, 0x2f'u8]))
|
||||
checkPermutation(959, 2558, 2094, Eth2Digest(data: [0xc9'u8, 0xf4'u8, 0xc5'u8, 0xfb'u8, 0xb2'u8, 0xa3'u8, 0x97'u8, 0xfd'u8, 0x8e'u8, 0xa3'u8, 0x6d'u8, 0xbf'u8, 0xce'u8, 0xc0'u8, 0xd7'u8, 0x33'u8, 0xd0'u8, 0xaf'u8, 0x7e'u8, 0xc3'u8, 0xa0'u8, 0x3d'u8, 0x78'u8, 0x9a'u8, 0x66'u8, 0x23'u8, 0x1f'u8, 0x3b'u8, 0xc7'u8, 0xca'u8, 0xfa'u8, 0x5e'u8]))
|
||||
checkPermutation(887, 2406, 831, Eth2Digest(data: [0x56'u8, 0x57'u8, 0x29'u8, 0xe0'u8, 0xd5'u8, 0xde'u8, 0x52'u8, 0x4e'u8, 0x6d'u8, 0xee'u8, 0x54'u8, 0xd1'u8, 0xb8'u8, 0xb5'u8, 0x88'u8, 0x2a'u8, 0xd8'u8, 0xe5'u8, 0x5c'u8, 0x18'u8, 0xa3'u8, 0x04'u8, 0x62'u8, 0xac'u8, 0x02'u8, 0xc4'u8, 0xbb'u8, 0x86'u8, 0xc2'u8, 0x7d'u8, 0x26'u8, 0xcb'u8]))
|
||||
checkPermutation(3526, 3674, 3531, Eth2Digest(data: [0x29'u8, 0x51'u8, 0x39'u8, 0x5b'u8, 0x1a'u8, 0x1b'u8, 0xbd'u8, 0xa8'u8, 0xd5'u8, 0x3b'u8, 0x77'u8, 0x6c'u8, 0x7f'u8, 0xc8'u8, 0xbd'u8, 0xad'u8, 0x60'u8, 0x30'u8, 0xde'u8, 0x94'u8, 0x3c'u8, 0x4e'u8, 0x3f'u8, 0x93'u8, 0x82'u8, 0x02'u8, 0xac'u8, 0x55'u8, 0x3f'u8, 0x44'u8, 0x38'u8, 0x1d'u8]))
|
||||
checkPermutation(978, 3175, 2257, Eth2Digest(data: [0x74'u8, 0xaa'u8, 0xc2'u8, 0x35'u8, 0x23'u8, 0xcb'u8, 0x45'u8, 0xb7'u8, 0xee'u8, 0x52'u8, 0xd5'u8, 0xd2'u8, 0xf7'u8, 0xb2'u8, 0xd2'u8, 0x4e'u8, 0xbc'u8, 0x6b'u8, 0xf2'u8, 0xd6'u8, 0x3e'u8, 0xf1'u8, 0x89'u8, 0xef'u8, 0xcc'u8, 0xab'u8, 0xc4'u8, 0xa1'u8, 0x6b'u8, 0xb1'u8, 0x7c'u8, 0xd8'u8]))
|
||||
checkPermutation(37, 231, 48, Eth2Digest(data: [0xe4'u8, 0x08'u8, 0x3e'u8, 0x61'u8, 0xb3'u8, 0x19'u8, 0x31'u8, 0xba'u8, 0xd6'u8, 0x62'u8, 0x39'u8, 0x27'u8, 0x58'u8, 0xe8'u8, 0xbc'u8, 0x30'u8, 0xa4'u8, 0xce'u8, 0x7b'u8, 0x26'u8, 0xb6'u8, 0x89'u8, 0x7c'u8, 0x22'u8, 0x21'u8, 0xa3'u8, 0x35'u8, 0x8f'u8, 0x25'u8, 0xfd'u8, 0xc1'u8, 0xd8'u8]))
|
||||
checkPermutation(340, 693, 234, Eth2Digest(data: [0x80'u8, 0x89'u8, 0xc1'u8, 0xf2'u8, 0x42'u8, 0xaa'u8, 0x48'u8, 0xc6'u8, 0x61'u8, 0x11'u8, 0x80'u8, 0xf2'u8, 0x21'u8, 0xc1'u8, 0x20'u8, 0xe9'u8, 0x30'u8, 0xad'u8, 0xee'u8, 0xca'u8, 0xf3'u8, 0x08'u8, 0x4b'u8, 0x2b'u8, 0x85'u8, 0xf9'u8, 0xb1'u8, 0xdf'u8, 0xeb'u8, 0xe3'u8, 0x4f'u8, 0x63'u8]))
|
||||
checkPermutation(0, 9, 1, Eth2Digest(data: [0x7f'u8, 0xda'u8, 0x0a'u8, 0xb6'u8, 0xa7'u8, 0x46'u8, 0xb6'u8, 0xb0'u8, 0x20'u8, 0x6f'u8, 0xeb'u8, 0xb8'u8, 0x25'u8, 0x98'u8, 0x91'u8, 0xe0'u8, 0xe6'u8, 0xf8'u8, 0x8b'u8, 0xf5'u8, 0x21'u8, 0x43'u8, 0xb2'u8, 0x0d'u8, 0x6c'u8, 0x78'u8, 0xca'u8, 0xf7'u8, 0xca'u8, 0xf8'u8, 0xe7'u8, 0xb3'u8]))
|
||||
checkPermutation(200, 1108, 952, Eth2Digest(data: [0x87'u8, 0xb2'u8, 0x10'u8, 0xd0'u8, 0x00'u8, 0xb5'u8, 0xf5'u8, 0x7e'u8, 0x98'u8, 0x34'u8, 0x38'u8, 0x8d'u8, 0x4b'u8, 0xc2'u8, 0xb8'u8, 0x6a'u8, 0xe8'u8, 0xb3'u8, 0x13'u8, 0x83'u8, 0xfa'u8, 0x10'u8, 0xa3'u8, 0x4b'u8, 0x02'u8, 0x95'u8, 0x46'u8, 0xc2'u8, 0xeb'u8, 0xab'u8, 0xb8'u8, 0x07'u8]))
|
||||
checkPermutation(1408, 1531, 584, Eth2Digest(data: [0x06'u8, 0x70'u8, 0xa7'u8, 0x8b'u8, 0x38'u8, 0xe0'u8, 0x41'u8, 0x9a'u8, 0xae'u8, 0xad'u8, 0x5d'u8, 0x1c'u8, 0xc8'u8, 0xf4'u8, 0x0f'u8, 0x58'u8, 0x04'u8, 0x4b'u8, 0x70'u8, 0x76'u8, 0xce'u8, 0xd8'u8, 0x19'u8, 0x3c'u8, 0x08'u8, 0xb5'u8, 0x80'u8, 0xdd'u8, 0x95'u8, 0xa1'u8, 0x35'u8, 0x55'u8]))
|
||||
checkPermutation(1704, 1863, 1022, Eth2Digest(data: [0xdb'u8, 0xf7'u8, 0x86'u8, 0x65'u8, 0x19'u8, 0x0a'u8, 0x61'u8, 0x33'u8, 0x19'u8, 0x1e'u8, 0x91'u8, 0xab'u8, 0x35'u8, 0xb1'u8, 0x10'u8, 0x6e'u8, 0x89'u8, 0x84'u8, 0xdf'u8, 0xc0'u8, 0xdf'u8, 0xa3'u8, 0x60'u8, 0x18'u8, 0x00'u8, 0x4f'u8, 0x88'u8, 0x0b'u8, 0x43'u8, 0x1c'u8, 0x2a'u8, 0x14'u8]))
|
||||
checkPermutation(793, 3938, 2607, Eth2Digest(data: [0x54'u8, 0xbf'u8, 0x01'u8, 0x92'u8, 0x29'u8, 0x2f'u8, 0xfa'u8, 0xe0'u8, 0xbf'u8, 0x39'u8, 0xb3'u8, 0x9f'u8, 0x12'u8, 0xe0'u8, 0x54'u8, 0x0b'u8, 0x97'u8, 0x59'u8, 0x1a'u8, 0xf0'u8, 0xa2'u8, 0x98'u8, 0x0d'u8, 0x32'u8, 0xf2'u8, 0x77'u8, 0xbd'u8, 0x33'u8, 0x20'u8, 0x13'u8, 0x95'u8, 0xd3'u8]))
|
||||
checkPermutation(14, 28, 10, Eth2Digest(data: [0x43'u8, 0x05'u8, 0x44'u8, 0x17'u8, 0xc6'u8, 0x05'u8, 0x64'u8, 0x04'u8, 0xc5'u8, 0x86'u8, 0xc9'u8, 0x07'u8, 0xdf'u8, 0xc5'u8, 0xfc'u8, 0xeb'u8, 0x66'u8, 0xeb'u8, 0xef'u8, 0x54'u8, 0x1d'u8, 0x14'u8, 0x3b'u8, 0x00'u8, 0xa3'u8, 0xb6'u8, 0x76'u8, 0xf3'u8, 0xc0'u8, 0xfb'u8, 0xf4'u8, 0xc5'u8]))
|
||||
checkPermutation(2909, 3920, 726, Eth2Digest(data: [0x5e'u8, 0xab'u8, 0xf2'u8, 0x89'u8, 0xfd'u8, 0xcf'u8, 0xe0'u8, 0xa3'u8, 0xab'u8, 0xa3'u8, 0x3a'u8, 0x18'u8, 0x5f'u8, 0xb1'u8, 0xa4'u8, 0xae'u8, 0x2f'u8, 0x2b'u8, 0x6f'u8, 0x78'u8, 0xda'u8, 0xf6'u8, 0x1f'u8, 0x5d'u8, 0x35'u8, 0x69'u8, 0x71'u8, 0xe0'u8, 0xcb'u8, 0x27'u8, 0x02'u8, 0x07'u8]))
|
||||
checkPermutation(1943, 1959, 1292, Eth2Digest(data: [0xca'u8, 0x86'u8, 0x32'u8, 0x2d'u8, 0xb5'u8, 0x69'u8, 0x27'u8, 0xd7'u8, 0x27'u8, 0x10'u8, 0x1e'u8, 0x31'u8, 0xc9'u8, 0x3f'u8, 0x61'u8, 0x6f'u8, 0x74'u8, 0x63'u8, 0x17'u8, 0xd2'u8, 0x9a'u8, 0xa1'u8, 0x0d'u8, 0x88'u8, 0xf3'u8, 0x71'u8, 0x59'u8, 0x29'u8, 0x63'u8, 0xde'u8, 0x92'u8, 0xaa'u8]))
|
||||
checkPermutation(1647, 2094, 1805, Eth2Digest(data: [0x3c'u8, 0xfe'u8, 0x27'u8, 0x42'u8, 0x30'u8, 0xa1'u8, 0x12'u8, 0xbc'u8, 0x68'u8, 0x61'u8, 0x48'u8, 0x82'u8, 0x64'u8, 0x53'u8, 0x39'u8, 0xfd'u8, 0xa2'u8, 0xf1'u8, 0x34'u8, 0x50'u8, 0x1a'u8, 0x04'u8, 0x20'u8, 0x79'u8, 0xd6'u8, 0x20'u8, 0xec'u8, 0x65'u8, 0xcf'u8, 0x8d'u8, 0x3f'u8, 0xa6'u8]))
|
||||
checkPermutation(1012, 1877, 216, Eth2Digest(data: [0x7b'u8, 0x5f'u8, 0xf8'u8, 0xa8'u8, 0x48'u8, 0xaf'u8, 0x32'u8, 0xd8'u8, 0x5c'u8, 0x6d'u8, 0x37'u8, 0xc2'u8, 0x6e'u8, 0x61'u8, 0xa5'u8, 0x7e'u8, 0x96'u8, 0x78'u8, 0x0f'u8, 0xce'u8, 0xbc'u8, 0x35'u8, 0x0a'u8, 0xd1'u8, 0x84'u8, 0x5e'u8, 0x83'u8, 0xfe'u8, 0x5e'u8, 0x46'u8, 0x79'u8, 0xac'u8]))
|
||||
checkPermutation(35, 2081, 1458, Eth2Digest(data: [0x40'u8, 0x69'u8, 0x1a'u8, 0xa3'u8, 0x1a'u8, 0x49'u8, 0xc2'u8, 0x39'u8, 0x1e'u8, 0x02'u8, 0x5e'u8, 0xc2'u8, 0x72'u8, 0xc8'u8, 0x12'u8, 0x51'u8, 0x0c'u8, 0xb0'u8, 0x7c'u8, 0x05'u8, 0x5f'u8, 0x62'u8, 0x01'u8, 0xe8'u8, 0x44'u8, 0x79'u8, 0x49'u8, 0x93'u8, 0x26'u8, 0x33'u8, 0x06'u8, 0x28'u8]))
|
||||
checkPermutation(1136, 2189, 1579, Eth2Digest(data: [0x31'u8, 0xa0'u8, 0xde'u8, 0xb2'u8, 0xc8'u8, 0xc5'u8, 0xf8'u8, 0x09'u8, 0xf4'u8, 0x13'u8, 0xb7'u8, 0xa3'u8, 0x6e'u8, 0xc6'u8, 0x80'u8, 0xee'u8, 0x8b'u8, 0x19'u8, 0xbb'u8, 0xb9'u8, 0xa3'u8, 0x9c'u8, 0x4e'u8, 0x20'u8, 0x73'u8, 0x26'u8, 0x15'u8, 0x58'u8, 0x64'u8, 0xbc'u8, 0x8b'u8, 0xe5'u8]))
|
||||
checkPermutation(1775, 3434, 707, Eth2Digest(data: [0x92'u8, 0xf3'u8, 0x0d'u8, 0x85'u8, 0x56'u8, 0x38'u8, 0x2b'u8, 0x72'u8, 0xa5'u8, 0x79'u8, 0x7d'u8, 0xb8'u8, 0x11'u8, 0x48'u8, 0x6e'u8, 0x7a'u8, 0x21'u8, 0x3e'u8, 0x01'u8, 0x45'u8, 0xd6'u8, 0xc9'u8, 0x46'u8, 0xe5'u8, 0x12'u8, 0x1a'u8, 0xa6'u8, 0xa8'u8, 0xf7'u8, 0x61'u8, 0xd1'u8, 0x64'u8]))
|
||||
checkPermutation(1109, 2010, 433, Eth2Digest(data: [0x09'u8, 0x3f'u8, 0xb9'u8, 0x76'u8, 0xf2'u8, 0x49'u8, 0x73'u8, 0x61'u8, 0x89'u8, 0x70'u8, 0x12'u8, 0xdf'u8, 0xa6'u8, 0xdc'u8, 0x01'u8, 0x90'u8, 0x09'u8, 0xed'u8, 0xa2'u8, 0xe4'u8, 0x8b'u8, 0xbe'u8, 0xb4'u8, 0xb7'u8, 0xc5'u8, 0x6d'u8, 0x4a'u8, 0xa5'u8, 0xda'u8, 0x7d'u8, 0x5f'u8, 0x87'u8]))
|
||||
checkPermutation(359, 538, 115, Eth2Digest(data: [0xa7'u8, 0x9b'u8, 0x35'u8, 0xbe'u8, 0xac'u8, 0xbe'u8, 0x48'u8, 0xc6'u8, 0x62'u8, 0xd6'u8, 0x08'u8, 0x84'u8, 0xc7'u8, 0x04'u8, 0x04'u8, 0x00'u8, 0x24'u8, 0xc5'u8, 0x5a'u8, 0xb8'u8, 0x79'u8, 0xe5'u8, 0xf6'u8, 0x15'u8, 0x21'u8, 0x01'u8, 0x3c'u8, 0x5f'u8, 0x45'u8, 0xeb'u8, 0x3b'u8, 0x70'u8]))
|
||||
checkPermutation(1259, 1473, 1351, Eth2Digest(data: [0x02'u8, 0xc5'u8, 0x3c'u8, 0x9c'u8, 0x6d'u8, 0xdf'u8, 0x25'u8, 0x97'u8, 0x16'u8, 0xff'u8, 0x02'u8, 0xe4'u8, 0x9a'u8, 0x29'u8, 0x4e'u8, 0xba'u8, 0x33'u8, 0xe4'u8, 0xad'u8, 0x25'u8, 0x5d'u8, 0x7e'u8, 0x90'u8, 0xdb'u8, 0xef'u8, 0xdb'u8, 0xc9'u8, 0x91'u8, 0xad'u8, 0xf6'u8, 0x03'u8, 0xe5'u8]))
|
||||
checkPermutation(2087, 2634, 1497, Eth2Digest(data: [0xa5'u8, 0xa4'u8, 0xc5'u8, 0x7c'u8, 0x57'u8, 0x05'u8, 0xec'u8, 0x69'u8, 0x7a'u8, 0x74'u8, 0xe6'u8, 0xc7'u8, 0x16'u8, 0x11'u8, 0x91'u8, 0xb1'u8, 0x8f'u8, 0x58'u8, 0xca'u8, 0x88'u8, 0x2a'u8, 0x0f'u8, 0xcc'u8, 0x18'u8, 0xf6'u8, 0x8d'u8, 0xc3'u8, 0xb5'u8, 0x7a'u8, 0x1a'u8, 0xa5'u8, 0xb6'u8]))
|
||||
checkPermutation(2069, 2511, 1837, Eth2Digest(data: [0xe7'u8, 0x05'u8, 0x1e'u8, 0xbc'u8, 0x07'u8, 0xf2'u8, 0xe7'u8, 0xb4'u8, 0xd4'u8, 0xb2'u8, 0x8f'u8, 0x48'u8, 0xd1'u8, 0xe4'u8, 0x2d'u8, 0x7b'u8, 0x9d'u8, 0xce'u8, 0xc3'u8, 0x1c'u8, 0x24'u8, 0x0c'u8, 0xa6'u8, 0xe1'u8, 0xa0'u8, 0xc0'u8, 0x61'u8, 0x39'u8, 0xcc'u8, 0xfc'u8, 0x4b'u8, 0x8f'u8]))
|
||||
checkPermutation(1660, 3932, 3046, Eth2Digest(data: [0x86'u8, 0x87'u8, 0xc0'u8, 0x29'u8, 0xff'u8, 0xc4'u8, 0x43'u8, 0x87'u8, 0x95'u8, 0x27'u8, 0xa6'u8, 0x4c'u8, 0x31'u8, 0xb7'u8, 0xac'u8, 0xbb'u8, 0x38'u8, 0xab'u8, 0x6e'u8, 0x34'u8, 0x37'u8, 0x79'u8, 0xd0'u8, 0xb2'u8, 0xc6'u8, 0xe2'u8, 0x50'u8, 0x04'u8, 0x6f'u8, 0xdb'u8, 0x9d'u8, 0xe8'u8]))
|
||||
checkPermutation(379, 646, 32, Eth2Digest(data: [0x17'u8, 0xe8'u8, 0x54'u8, 0xf4'u8, 0xe8'u8, 0x04'u8, 0x01'u8, 0x34'u8, 0x5e'u8, 0x13'u8, 0xf7'u8, 0x2a'u8, 0xf4'u8, 0x5b'u8, 0x22'u8, 0x1c'u8, 0x9f'u8, 0x7a'u8, 0x84'u8, 0x0f'u8, 0x6a'u8, 0x8c'u8, 0x13'u8, 0x28'u8, 0xdd'u8, 0xf9'u8, 0xc9'u8, 0xca'u8, 0x9a'u8, 0x08'u8, 0x83'u8, 0x79'u8]))
|
||||
s.len == committees
|
||||
sumCommittees(s, num_validators div committees) ==
|
||||
get_active_validator_indices(genState, GENESIS_EPOCH).len()
|
||||
# TODO: Empty!
|
||||
discard
|
||||
|
|
Loading…
Reference in New Issue