mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-02-20 10:18:35 +00:00
Switch hash functions, prevent underflow & verify that shuffling works (#149)
* prevent balance underflow, per spec implementation note * verify that permutation shuffing works: add YAML dependency to be used for ingesting test cases; switch from blake2 to keccak256 to match EF test cases; remove inefficient naive-spec-version of shuffling algorithm now that protolambda's can be tested directly
This commit is contained in:
parent
68a39a21be
commit
81d5becc7b
@ -22,7 +22,8 @@ requires "nim >= 0.19.0",
|
|||||||
"serialization",
|
"serialization",
|
||||||
"json_serialization",
|
"json_serialization",
|
||||||
"json_rpc",
|
"json_rpc",
|
||||||
"chronos"
|
"chronos",
|
||||||
|
"yaml"
|
||||||
|
|
||||||
### Helper functions
|
### Helper functions
|
||||||
proc test(name: string, defaultLang = "c") =
|
proc test(name: string, defaultLang = "c") =
|
||||||
|
@ -121,6 +121,10 @@ func exit_validator*(state: var BeaconState,
|
|||||||
|
|
||||||
validator.exit_epoch = get_entry_exit_effect_epoch(get_current_epoch(state))
|
validator.exit_epoch = get_entry_exit_effect_epoch(get_current_epoch(state))
|
||||||
|
|
||||||
|
func reduce_balance*(balance: var uint64, amount: uint64) =
|
||||||
|
# Not in spec, but useful to avoid underflow.
|
||||||
|
balance -= min(amount, balance)
|
||||||
|
|
||||||
func slash_validator*(state: var BeaconState, index: ValidatorIndex) =
|
func slash_validator*(state: var BeaconState, index: ValidatorIndex) =
|
||||||
## Slash the validator with index ``index``.
|
## Slash the validator with index ``index``.
|
||||||
## Note that this function mutates ``state``.
|
## Note that this function mutates ``state``.
|
||||||
@ -140,7 +144,7 @@ func slash_validator*(state: var BeaconState, index: ValidatorIndex) =
|
|||||||
WHISTLEBLOWER_REWARD_QUOTIENT
|
WHISTLEBLOWER_REWARD_QUOTIENT
|
||||||
|
|
||||||
state.validator_balances[whistleblower_index] += whistleblower_reward
|
state.validator_balances[whistleblower_index] += whistleblower_reward
|
||||||
state.validator_balances[index] -= whistleblower_reward
|
reduce_balance(state.validator_balances[index], whistleblower_reward)
|
||||||
validator.slashed_epoch = get_current_epoch(state)
|
validator.slashed_epoch = get_current_epoch(state)
|
||||||
|
|
||||||
# Spec bug in v0.3.0, fixed since: it has LATEST_PENALIZED_EXIT_LENGTH
|
# Spec bug in v0.3.0, fixed since: it has LATEST_PENALIZED_EXIT_LENGTH
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
# `eth2hash`, and it outputs a `Eth2Digest`. Easy to sed :)
|
# `eth2hash`, and it outputs a `Eth2Digest`. Easy to sed :)
|
||||||
|
|
||||||
import
|
import
|
||||||
nimcrypto/[blake2, hash], eth/common/eth_types_json_serialization,
|
nimcrypto/[keccak, hash], eth/common/eth_types_json_serialization,
|
||||||
hashes
|
hashes
|
||||||
|
|
||||||
export
|
export
|
||||||
@ -29,7 +29,7 @@ export
|
|||||||
|
|
||||||
type
|
type
|
||||||
Eth2Digest* = MDigest[32 * 8] ## `hash32` from spec
|
Eth2Digest* = MDigest[32 * 8] ## `hash32` from spec
|
||||||
Eth2Hash* = blake2_512 ## Context for hash function
|
Eth2Hash* = keccak256 ## Context for hash function
|
||||||
|
|
||||||
func shortLog*(x: Eth2Digest): string =
|
func shortLog*(x: Eth2Digest): string =
|
||||||
($x)[0..7]
|
($x)[0..7]
|
||||||
|
@ -12,73 +12,11 @@ import
|
|||||||
../ssz,
|
../ssz,
|
||||||
./crypto, ./datatypes, ./digest, ./helpers
|
./crypto, ./datatypes, ./digest, ./helpers
|
||||||
|
|
||||||
# TODO remove once there are test vectors to check with directly
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_permuted_index
|
|
||||||
func get_permuted_index_spec(index: uint64, list_size: uint64, seed: Eth2Digest): uint64 =
|
|
||||||
## Return `p(index)` in a pseudorandom permutation `p` of `0...list_size-1`
|
|
||||||
## with ``seed`` as entropy.
|
|
||||||
##
|
|
||||||
## Utilizes 'swap or not' shuffling found in
|
|
||||||
## https://link.springer.com/content/pdf/10.1007%2F978-3-642-32009-5_1.pdf
|
|
||||||
## See the 'generalized domain' algorithm on page 3.
|
|
||||||
result = index
|
|
||||||
var pivot_buffer: array[(32+1), byte]
|
|
||||||
var source_buffer: array[(32+1+4), byte]
|
|
||||||
|
|
||||||
for round in 0 ..< SHUFFLE_ROUND_COUNT:
|
|
||||||
pivot_buffer[0..31] = seed.data
|
|
||||||
let round_bytes1 = int_to_bytes1(round)[0]
|
|
||||||
pivot_buffer[32] = round_bytes1
|
|
||||||
|
|
||||||
let
|
|
||||||
pivot = bytes_to_int(eth2hash(pivot_buffer).data[0..7]) mod list_size
|
|
||||||
flip = (pivot - result) mod list_size
|
|
||||||
position = max(result, flip)
|
|
||||||
|
|
||||||
## Tradeoff between slicing (if reusing one larger buffer) and additional
|
|
||||||
## copies here of seed and `int_to_bytes1(round)`.
|
|
||||||
source_buffer[0..31] = seed.data
|
|
||||||
source_buffer[32] = round_bytes1
|
|
||||||
source_buffer[33..36] = int_to_bytes4(position div 256)
|
|
||||||
|
|
||||||
let
|
|
||||||
source = eth2hash(source_buffer).data
|
|
||||||
byte_value = source[(position mod 256) div 8]
|
|
||||||
bit = (byte_value shr (position mod 8)) mod 2
|
|
||||||
|
|
||||||
if bit != 0:
|
|
||||||
result = flip
|
|
||||||
|
|
||||||
# TODO remove once there are test vectors to check with directly
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_shuffling
|
|
||||||
func get_shuffling_spec*(seed: Eth2Digest, validators: openArray[Validator],
|
|
||||||
epoch: Epoch): seq[seq[ValidatorIndex]] =
|
|
||||||
## Shuffles ``validators`` into crosslink committees seeded by ``seed`` and
|
|
||||||
## ``slot``.
|
|
||||||
## Returns a list of ``SLOTS_PER_EPOCH * committees_per_slot`` committees where
|
|
||||||
## each committee is itself a list of validator indices.
|
|
||||||
|
|
||||||
let
|
|
||||||
active_validator_indices = get_active_validator_indices(validators, epoch)
|
|
||||||
|
|
||||||
committees_per_epoch = get_epoch_committee_count(
|
|
||||||
len(active_validator_indices)).int
|
|
||||||
|
|
||||||
shuffled_active_validator_indices = mapIt(
|
|
||||||
active_validator_indices,
|
|
||||||
active_validator_indices[get_permuted_index_spec(
|
|
||||||
it, len(active_validator_indices).uint64, seed).int])
|
|
||||||
|
|
||||||
# Split the shuffled list into committees_per_epoch pieces
|
|
||||||
result = split(shuffled_active_validator_indices, committees_per_epoch)
|
|
||||||
assert result.len() == committees_per_epoch # what split should do..
|
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_shuffling
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_shuffling
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_permuted_index
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_permuted_index
|
||||||
func get_shuffling*(seed: Eth2Digest,
|
func get_shuffled_seq*(seed: Eth2Digest,
|
||||||
validators: openArray[Validator],
|
validators: openArray[Validator],
|
||||||
epoch: Epoch
|
): seq[ValidatorIndex] =
|
||||||
): seq[seq[ValidatorIndex]] =
|
|
||||||
## Via https://github.com/protolambda/eth2-shuffle/blob/master/shuffle.go
|
## Via https://github.com/protolambda/eth2-shuffle/blob/master/shuffle.go
|
||||||
## Shuffles ``validators`` into crosslink committees seeded by ``seed`` and
|
## Shuffles ``validators`` into crosslink committees seeded by ``seed`` and
|
||||||
## ``slot``.
|
## ``slot``.
|
||||||
@ -87,11 +25,7 @@ func get_shuffling*(seed: Eth2Digest,
|
|||||||
##
|
##
|
||||||
## Invert the inner/outer loops from the spec, essentially. Most useful
|
## Invert the inner/outer loops from the spec, essentially. Most useful
|
||||||
## hash result re-use occurs within a round.
|
## hash result re-use occurs within a round.
|
||||||
let
|
let list_size = validators.len.uint64
|
||||||
active_validator_indices = get_active_validator_indices(validators, epoch)
|
|
||||||
list_size = active_validator_indices.len.uint64
|
|
||||||
committees_per_epoch = get_epoch_committee_count(
|
|
||||||
len(active_validator_indices)).int
|
|
||||||
var
|
var
|
||||||
# Share these buffers.
|
# Share these buffers.
|
||||||
pivot_buffer: array[(32+1), byte]
|
pivot_buffer: array[(32+1), byte]
|
||||||
@ -116,7 +50,7 @@ func get_shuffling*(seed: Eth2Digest,
|
|||||||
## Only need to run, per round, position div 256 hashes, so precalculate
|
## Only need to run, per round, position div 256 hashes, so precalculate
|
||||||
## them. This consumes memory, but for low-memory devices, it's possible
|
## them. This consumes memory, but for low-memory devices, it's possible
|
||||||
## to mitigate by some light LRU caching and similar.
|
## to mitigate by some light LRU caching and similar.
|
||||||
for reduced_position in 0 ..< list_size.int div 256:
|
for reduced_position in 0 ..< sources.len:
|
||||||
source_buffer[33..36] = int_to_bytes4(reduced_position.uint64)
|
source_buffer[33..36] = int_to_bytes4(reduced_position.uint64)
|
||||||
sources[reduced_position] = eth2hash(source_buffer)
|
sources[reduced_position] = eth2hash(source_buffer)
|
||||||
|
|
||||||
@ -124,9 +58,9 @@ func get_shuffling*(seed: Eth2Digest,
|
|||||||
## efficiency gains exist in caching and re-using data.
|
## efficiency gains exist in caching and re-using data.
|
||||||
for index in 0 ..< list_size.int:
|
for index in 0 ..< list_size.int:
|
||||||
let
|
let
|
||||||
cur_idx_permutated = shuffled_active_validator_indices[index]
|
cur_idx_permuted = shuffled_active_validator_indices[index]
|
||||||
flip = (pivot - cur_idx_permutated.uint64) mod list_size
|
flip = ((list_size + pivot) - cur_idx_permuted.uint64) mod list_size
|
||||||
position = max(cur_idx_permutated, flip.int)
|
position = max(cur_idx_permuted, flip.int)
|
||||||
|
|
||||||
let
|
let
|
||||||
source = sources[position div 256].data
|
source = sources[position div 256].data
|
||||||
@ -136,8 +70,26 @@ func get_shuffling*(seed: Eth2Digest,
|
|||||||
if bit != 0:
|
if bit != 0:
|
||||||
shuffled_active_validator_indices[index] = flip.ValidatorIndex
|
shuffled_active_validator_indices[index] = flip.ValidatorIndex
|
||||||
|
|
||||||
|
result = shuffled_active_validator_indices
|
||||||
|
|
||||||
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_shuffling
|
||||||
|
func get_shuffling*(seed: Eth2Digest,
|
||||||
|
validators: openArray[Validator],
|
||||||
|
epoch: Epoch
|
||||||
|
): seq[seq[ValidatorIndex]] =
|
||||||
|
## This function is factored to facilitate testing with
|
||||||
|
## https://github.com/ethereum/eth2.0-test-generators/tree/master/permutated_index
|
||||||
|
## test vectors, which the split of get_shuffling obfuscates.
|
||||||
|
|
||||||
|
let
|
||||||
|
active_validator_indices = get_active_validator_indices(validators, epoch)
|
||||||
|
committees_per_epoch = get_epoch_committee_count(
|
||||||
|
len(active_validator_indices)).int
|
||||||
|
|
||||||
# Split the shuffled list into committees_per_epoch pieces
|
# Split the shuffled list into committees_per_epoch pieces
|
||||||
result = split(shuffled_active_validator_indices, committees_per_epoch)
|
result = split(
|
||||||
|
get_shuffled_seq(seed, validators),
|
||||||
|
committees_per_epoch)
|
||||||
assert result.len() == committees_per_epoch # what split should do..
|
assert result.len() == committees_per_epoch # what split should do..
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_previous_epoch_committee_count
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_previous_epoch_committee_count
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
import
|
import
|
||||||
endians, typetraits, options, algorithm,
|
endians, typetraits, options, algorithm,
|
||||||
eth/common, nimcrypto/blake2,
|
eth/common, nimcrypto/keccak,
|
||||||
./spec/[crypto, datatypes, digest]
|
./spec/[crypto, datatypes, digest]
|
||||||
|
|
||||||
# ################### Helper functions ###################################
|
# ################### Helper functions ###################################
|
||||||
|
@ -125,7 +125,7 @@ func slashValidator(state: var BeaconState, index: ValidatorIndex) =
|
|||||||
whistleblower_reward = get_effective_balance(state, index) div
|
whistleblower_reward = get_effective_balance(state, index) div
|
||||||
WHISTLEBLOWER_REWARD_QUOTIENT
|
WHISTLEBLOWER_REWARD_QUOTIENT
|
||||||
state.validator_balances[whistleblower_index] += whistleblower_reward
|
state.validator_balances[whistleblower_index] += whistleblower_reward
|
||||||
state.validator_balances[index] -= whistleblower_reward
|
reduce_balance(state.validator_balances[index], whistleblower_reward)
|
||||||
validator.slashed_epoch = get_current_epoch(state)
|
validator.slashed_epoch = get_current_epoch(state)
|
||||||
|
|
||||||
# v0.3.0 spec bug, fixed later, involving renamed constants. Use v0.3.0 name.
|
# v0.3.0 spec bug, fixed later, involving renamed constants. Use v0.3.0 name.
|
||||||
@ -397,8 +397,9 @@ proc processTransfers(state: var BeaconState, blck: BeaconBlock,
|
|||||||
notice "Transfer: incorrect signature"
|
notice "Transfer: incorrect signature"
|
||||||
return false
|
return false
|
||||||
|
|
||||||
state.validator_balances[
|
reduce_balance(
|
||||||
transfer.from_field.int] -= transfer.amount + transfer.fee
|
state.validator_balances[transfer.from_field.int],
|
||||||
|
transfer.amount + transfer.fee)
|
||||||
state.validator_balances[transfer.to.int] += transfer.amount
|
state.validator_balances[transfer.to.int] += transfer.amount
|
||||||
state.validator_balances[
|
state.validator_balances[
|
||||||
get_beacon_proposer_index(state, state.slot)] += transfer.fee
|
get_beacon_proposer_index(state, state.slot)] += transfer.fee
|
||||||
@ -543,7 +544,7 @@ func process_slashings(state: var BeaconState) =
|
|||||||
min(total_penalties * 3, total_balance) div total_balance,
|
min(total_penalties * 3, total_balance) div total_balance,
|
||||||
get_effective_balance(state, index.ValidatorIndex) div
|
get_effective_balance(state, index.ValidatorIndex) div
|
||||||
MIN_PENALTY_QUOTIENT)
|
MIN_PENALTY_QUOTIENT)
|
||||||
state.validator_balances[index] -= penalty
|
reduce_balance(state.validator_balances[index], penalty)
|
||||||
|
|
||||||
func process_exit_queue(state: var BeaconState) =
|
func process_exit_queue(state: var BeaconState) =
|
||||||
## Process the exit queue.
|
## Process the exit queue.
|
||||||
@ -804,8 +805,8 @@ func processEpoch(state: var BeaconState) =
|
|||||||
|
|
||||||
for v in active_validator_indices:
|
for v in active_validator_indices:
|
||||||
if v notin attesters:
|
if v notin attesters:
|
||||||
# TODO underflows?
|
reduce_balance(
|
||||||
statePtr.validator_balances[v] -= base_reward(statePtr[], v)
|
statePtr.validator_balances[v], base_reward(statePtr[], v))
|
||||||
|
|
||||||
if epochs_since_finality <= 4'u64:
|
if epochs_since_finality <= 4'u64:
|
||||||
# Case 1: epochs_since_finality <= 4
|
# Case 1: epochs_since_finality <= 4
|
||||||
@ -833,24 +834,28 @@ func processEpoch(state: var BeaconState) =
|
|||||||
else:
|
else:
|
||||||
# Case 2: epochs_since_finality > 4
|
# Case 2: epochs_since_finality > 4
|
||||||
for index in active_validator_indices:
|
for index in active_validator_indices:
|
||||||
# TODO underflows?
|
|
||||||
if index notin previous_epoch_attester_indices:
|
if index notin previous_epoch_attester_indices:
|
||||||
state.validator_balances[index] -=
|
reduce_balance(
|
||||||
inactivity_penalty(state, index, epochs_since_finality)
|
state.validator_balances[index],
|
||||||
|
inactivity_penalty(state, index, epochs_since_finality))
|
||||||
if index notin previous_epoch_boundary_attester_indices:
|
if index notin previous_epoch_boundary_attester_indices:
|
||||||
state.validator_balances[index] -=
|
reduce_balance(
|
||||||
inactivity_penalty(state, index, epochs_since_finality)
|
state.validator_balances[index],
|
||||||
|
inactivity_penalty(state, index, epochs_since_finality))
|
||||||
if index notin previous_epoch_head_attester_indices:
|
if index notin previous_epoch_head_attester_indices:
|
||||||
state.validator_balances[index] -= base_reward(state, index)
|
reduce_balance(
|
||||||
|
state.validator_balances[index], base_reward(state, index))
|
||||||
if state.validator_registry[index].slashed_epoch <= current_epoch:
|
if state.validator_registry[index].slashed_epoch <= current_epoch:
|
||||||
state.validator_balances[index] -=
|
reduce_balance(
|
||||||
|
state.validator_balances[index],
|
||||||
2'u64 * inactivity_penalty(
|
2'u64 * inactivity_penalty(
|
||||||
state, index, epochs_since_finality) + base_reward(state, index)
|
state, index, epochs_since_finality) + base_reward(state, index))
|
||||||
if index in previous_epoch_attester_indices:
|
if index in previous_epoch_attester_indices:
|
||||||
state.validator_balances[index] -=
|
reduce_balance(
|
||||||
|
state.validator_balances[index],
|
||||||
base_reward(state, index) -
|
base_reward(state, index) -
|
||||||
base_reward(state, index) * MIN_ATTESTATION_INCLUSION_DELAY div
|
base_reward(state, index) * MIN_ATTESTATION_INCLUSION_DELAY div
|
||||||
inclusion_distance(state, index)
|
inclusion_distance(state, index))
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#attestation-inclusion
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#attestation-inclusion
|
||||||
block:
|
block:
|
||||||
@ -872,8 +877,8 @@ func processEpoch(state: var BeaconState) =
|
|||||||
total_attesting_balance(crosslink_committee) div
|
total_attesting_balance(crosslink_committee) div
|
||||||
get_total_balance(state, crosslink_committee.committee)
|
get_total_balance(state, crosslink_committee.committee)
|
||||||
else:
|
else:
|
||||||
# TODO underflows?
|
reduce_balance(
|
||||||
state.validator_balances[index] -= base_reward(state, index)
|
state.validator_balances[index], base_reward(state, index))
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#ejections
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#ejections
|
||||||
process_ejections(state)
|
process_ejections(state)
|
||||||
|
@ -16,11 +16,19 @@ func sumCommittees(v: openArray[seq[ValidatorIndex]], reqCommitteeLen: int): int
|
|||||||
assert x.len == reqCommitteeLen
|
assert x.len == reqCommitteeLen
|
||||||
inc result, x.len
|
inc result, x.len
|
||||||
|
|
||||||
|
func checkPermutation(index: int, list_size: uint64,
|
||||||
|
permuted_index: int, seed: Eth2Digest): bool =
|
||||||
|
let
|
||||||
|
validators = repeat(
|
||||||
|
Validator(exit_epoch: FAR_FUTURE_EPOCH), list_size)
|
||||||
|
s = get_shuffled_seq(seed, validators)
|
||||||
|
s[index] == permuted_index.ValidatorIndex
|
||||||
|
|
||||||
suite "Validators":
|
suite "Validators":
|
||||||
## For now just test that we can compile and execute block processing with mock data.
|
## 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/status-im/nim-beacon-chain/issues/1
|
||||||
## https://github.com/sigp/lighthouse/blob/ba548e49a52687a655c61b443b6835d79c6d4236/beacon_chain/validator_shuffling/src/shuffle.rs
|
## https://github.com/sigp/lighthouse/blob/ba548e49a52687a655c61b443b6835d79c6d4236/beacon_chain/validator_shuffling/src/shuffle.rs
|
||||||
test "Smoke validator shuffling":
|
test "Validator shuffling":
|
||||||
let
|
let
|
||||||
num_validators = 32*1024
|
num_validators = 32*1024
|
||||||
validators = repeat(
|
validators = repeat(
|
||||||
@ -28,13 +36,50 @@ suite "Validators":
|
|||||||
exit_epoch: FAR_FUTURE_EPOCH
|
exit_epoch: FAR_FUTURE_EPOCH
|
||||||
), num_validators)
|
), num_validators)
|
||||||
s = get_shuffling(Eth2Digest(), validators, 0)
|
s = get_shuffling(Eth2Digest(), validators, 0)
|
||||||
#s_spec = get_shuffling_spec(Eth2Digest(), validators, 0)
|
|
||||||
#s = get_shuffling_spec(Eth2Digest(), validators, 0)
|
|
||||||
committees = get_epoch_committee_count(len(validators)).int
|
committees = get_epoch_committee_count(len(validators)).int
|
||||||
check:
|
check:
|
||||||
## Enable checking equivalence of spec and optimized versions.
|
# def b(s): return "Eth2Digest(data: [0x" + "'u8, 0x".join((s[i:i+2] for i in range(0, 64, 2))) + "'u8])"
|
||||||
## TODO enable checking against YAML test vectors
|
# TODO read YAML file directly from test case generator
|
||||||
#s == s_spec
|
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
|
s.len == committees
|
||||||
# 32k validators: SLOTS_PER_EPOCH slots * committee_count_per_slot =
|
# 32k validators: SLOTS_PER_EPOCH slots * committee_count_per_slot =
|
||||||
# get_epoch_committee_count committees.
|
# get_epoch_committee_count committees.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user