mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-02-17 13:06:34 +00:00
seperate tests 'sanity' and 'minimal-config' vs all
This commit is contained in:
parent
d9ac06e8ed
commit
55c337a35c
13
Makefile
13
Makefile
@ -3,8 +3,19 @@ SCRIPT_DIR = ./scripts
|
|||||||
BUILD_DIR = ./build
|
BUILD_DIR = ./build
|
||||||
UTILS_DIR = ./utils
|
UTILS_DIR = ./utils
|
||||||
|
|
||||||
.PHONY: clean all $(BUILD_DIR)/phase0
|
|
||||||
|
|
||||||
|
.PHONY: clean all test
|
||||||
|
|
||||||
|
|
||||||
|
all: $(BUILD_DIR)/phase0
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILD_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
test:
|
||||||
|
pytest -m "sanity and minimal_config" tests/
|
||||||
|
|
||||||
$(BUILD_DIR)/phase0:
|
$(BUILD_DIR)/phase0:
|
||||||
mkdir -p $@
|
mkdir -p $@
|
||||||
|
@ -1,28 +1,27 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from py_ecc import bls
|
|
||||||
|
|
||||||
from build.phase0 import spec
|
from build.phase0 import spec
|
||||||
|
|
||||||
from build.phase0.utils.merkle_minimal import (
|
from tests.phase0.helpers import (
|
||||||
calc_merkle_tree_from_leaves,
|
privkeys_list,
|
||||||
get_merkle_proof,
|
pubkeys_list,
|
||||||
get_merkle_root,
|
create_genesis_state,
|
||||||
)
|
|
||||||
from build.phase0.spec import (
|
|
||||||
Deposit,
|
|
||||||
DepositData,
|
|
||||||
DepositInput,
|
|
||||||
Eth1Data,
|
|
||||||
get_genesis_beacon_state,
|
|
||||||
verify_merkle_branch,
|
|
||||||
hash,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
privkeys_list = [i+1 for i in range(1000)]
|
DEFAULT_CONFIG = {} # no change
|
||||||
pubkeys_list = [bls.privtopub(privkey) for privkey in privkeys_list]
|
|
||||||
pubkey_to_privkey = {pubkey: privkey for privkey, pubkey in zip(privkeys_list, pubkeys_list)}
|
MINIMAL_CONFIG = {
|
||||||
|
"SHARD_COUNT": 8,
|
||||||
|
"MIN_ATTESTATION_INCLUSION_DELAY": 2,
|
||||||
|
"TARGET_COMMITTEE_SIZE": 4,
|
||||||
|
"SLOTS_PER_EPOCH": 8,
|
||||||
|
"GENESIS_EPOCH": spec.GENESIS_SLOT // 8,
|
||||||
|
"SLOTS_PER_HISTORICAL_ROOT": 64,
|
||||||
|
"LATEST_RANDAO_MIXES_LENGTH": 64,
|
||||||
|
"LATEST_ACTIVE_INDEX_ROOTS_LENGTH": 64,
|
||||||
|
"LATEST_SLASHED_EXIT_LENGTH": 64,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@ -53,19 +52,14 @@ def overwrite_spec_config(config):
|
|||||||
spec.BeaconState.fields['latest_slashed_balances'][1] = config[field]
|
spec.BeaconState.fields['latest_slashed_balances'][1] = config[field]
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture(
|
||||||
def config():
|
params=[
|
||||||
return {
|
pytest.param(MINIMAL_CONFIG, marks=pytest.mark.minimal_config),
|
||||||
"SHARD_COUNT": 8,
|
DEFAULT_CONFIG,
|
||||||
"MIN_ATTESTATION_INCLUSION_DELAY": 2,
|
]
|
||||||
"TARGET_COMMITTEE_SIZE": 4,
|
)
|
||||||
"SLOTS_PER_EPOCH": 8,
|
def config(request):
|
||||||
"GENESIS_EPOCH": spec.GENESIS_SLOT // 8,
|
return request.param
|
||||||
"SLOTS_PER_HISTORICAL_ROOT": 64,
|
|
||||||
"LATEST_RANDAO_MIXES_LENGTH": 64,
|
|
||||||
"LATEST_ACTIVE_INDEX_ROOTS_LENGTH": 64,
|
|
||||||
"LATEST_SLASHED_EXIT_LENGTH": 64,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
@ -73,52 +67,6 @@ def overwrite_config(config):
|
|||||||
overwrite_spec_config(config)
|
overwrite_spec_config(config)
|
||||||
|
|
||||||
|
|
||||||
def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves):
|
|
||||||
deposit_timestamp = 0
|
|
||||||
proof_of_possession = b'\x33' * 96
|
|
||||||
|
|
||||||
deposit_data_list = []
|
|
||||||
for i in range(num_validators):
|
|
||||||
pubkey = pubkeys_list[i]
|
|
||||||
privkey = pubkey_to_privkey[pubkey]
|
|
||||||
deposit_data = DepositData(
|
|
||||||
amount=spec.MAX_DEPOSIT_AMOUNT,
|
|
||||||
timestamp=deposit_timestamp,
|
|
||||||
deposit_input=DepositInput(
|
|
||||||
pubkey=pubkey,
|
|
||||||
withdrawal_credentials=privkey.to_bytes(32, byteorder='big'),
|
|
||||||
proof_of_possession=proof_of_possession,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
item = hash(deposit_data.serialize())
|
|
||||||
deposit_data_leaves.append(item)
|
|
||||||
tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves))
|
|
||||||
root = get_merkle_root((tuple(deposit_data_leaves)))
|
|
||||||
proof = list(get_merkle_proof(tree, item_index=i))
|
|
||||||
assert verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, i, root)
|
|
||||||
deposit_data_list.append(deposit_data)
|
|
||||||
|
|
||||||
genesis_validator_deposits = []
|
|
||||||
for i in range(num_validators):
|
|
||||||
genesis_validator_deposits.append(Deposit(
|
|
||||||
proof=list(get_merkle_proof(tree, item_index=i)),
|
|
||||||
index=i,
|
|
||||||
deposit_data=deposit_data_list[i]
|
|
||||||
))
|
|
||||||
return genesis_validator_deposits, root
|
|
||||||
|
|
||||||
|
|
||||||
def create_genesis_state(num_validators, deposit_data_leaves):
|
|
||||||
initial_deposits, deposit_root = create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves)
|
|
||||||
return get_genesis_beacon_state(
|
|
||||||
initial_deposits,
|
|
||||||
genesis_time=0,
|
|
||||||
genesis_eth1_data=Eth1Data(
|
|
||||||
deposit_root=deposit_root,
|
|
||||||
block_hash=spec.ZERO_HASH,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def num_validators():
|
def num_validators():
|
||||||
return 100
|
return 100
|
||||||
|
139
tests/phase0/helpers.py
Normal file
139
tests/phase0/helpers.py
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
|
from py_ecc import bls
|
||||||
|
|
||||||
|
import build.phase0.spec as spec
|
||||||
|
from build.phase0.utils.minimal_ssz import signed_root
|
||||||
|
from build.phase0.spec import (
|
||||||
|
AttestationData,
|
||||||
|
Deposit,
|
||||||
|
DepositInput,
|
||||||
|
DepositData,
|
||||||
|
Eth1Data,
|
||||||
|
get_block_root,
|
||||||
|
get_current_epoch,
|
||||||
|
get_domain,
|
||||||
|
get_empty_block,
|
||||||
|
get_epoch_start_slot,
|
||||||
|
get_genesis_beacon_state,
|
||||||
|
verify_merkle_branch,
|
||||||
|
hash,
|
||||||
|
)
|
||||||
|
from build.phase0.utils.merkle_minimal import (
|
||||||
|
calc_merkle_tree_from_leaves,
|
||||||
|
get_merkle_proof,
|
||||||
|
get_merkle_root,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
privkeys_list = [i+1 for i in range(1000)]
|
||||||
|
pubkeys_list = [bls.privtopub(privkey) for privkey in privkeys_list]
|
||||||
|
pubkey_to_privkey = {pubkey: privkey for privkey, pubkey in zip(privkeys_list, pubkeys_list)}
|
||||||
|
|
||||||
|
|
||||||
|
def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves):
|
||||||
|
deposit_timestamp = 0
|
||||||
|
proof_of_possession = b'\x33' * 96
|
||||||
|
|
||||||
|
deposit_data_list = []
|
||||||
|
for i in range(num_validators):
|
||||||
|
pubkey = pubkeys_list[i]
|
||||||
|
privkey = pubkey_to_privkey[pubkey]
|
||||||
|
deposit_data = DepositData(
|
||||||
|
amount=spec.MAX_DEPOSIT_AMOUNT,
|
||||||
|
timestamp=deposit_timestamp,
|
||||||
|
deposit_input=DepositInput(
|
||||||
|
pubkey=pubkey,
|
||||||
|
withdrawal_credentials=privkey.to_bytes(32, byteorder='big'),
|
||||||
|
proof_of_possession=proof_of_possession,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
item = hash(deposit_data.serialize())
|
||||||
|
deposit_data_leaves.append(item)
|
||||||
|
tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves))
|
||||||
|
root = get_merkle_root((tuple(deposit_data_leaves)))
|
||||||
|
proof = list(get_merkle_proof(tree, item_index=i))
|
||||||
|
assert verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, i, root)
|
||||||
|
deposit_data_list.append(deposit_data)
|
||||||
|
|
||||||
|
genesis_validator_deposits = []
|
||||||
|
for i in range(num_validators):
|
||||||
|
genesis_validator_deposits.append(Deposit(
|
||||||
|
proof=list(get_merkle_proof(tree, item_index=i)),
|
||||||
|
index=i,
|
||||||
|
deposit_data=deposit_data_list[i]
|
||||||
|
))
|
||||||
|
return genesis_validator_deposits, root
|
||||||
|
|
||||||
|
|
||||||
|
def create_genesis_state(num_validators, deposit_data_leaves):
|
||||||
|
initial_deposits, deposit_root = create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves)
|
||||||
|
return get_genesis_beacon_state(
|
||||||
|
initial_deposits,
|
||||||
|
genesis_time=0,
|
||||||
|
genesis_eth1_data=Eth1Data(
|
||||||
|
deposit_root=deposit_root,
|
||||||
|
block_hash=spec.ZERO_HASH,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
def build_empty_block_for_next_slot(state):
|
||||||
|
empty_block = get_empty_block()
|
||||||
|
empty_block.slot = state.slot + 1
|
||||||
|
previous_block_header = deepcopy(state.latest_block_header)
|
||||||
|
if previous_block_header.state_root == spec.ZERO_HASH:
|
||||||
|
previous_block_header.state_root = state.hash_tree_root()
|
||||||
|
empty_block.previous_block_root = previous_block_header.hash_tree_root()
|
||||||
|
return empty_block
|
||||||
|
|
||||||
|
|
||||||
|
def build_deposit_data(state, pubkey, privkey, amount):
|
||||||
|
deposit_input = DepositInput(
|
||||||
|
pubkey=pubkey,
|
||||||
|
withdrawal_credentials=privkey.to_bytes(32, byteorder='big'),
|
||||||
|
proof_of_possession=b'00'*96,
|
||||||
|
)
|
||||||
|
proof_of_possession = bls.sign(
|
||||||
|
message_hash=signed_root(deposit_input),
|
||||||
|
privkey=privkey,
|
||||||
|
domain=get_domain(
|
||||||
|
state.fork,
|
||||||
|
get_current_epoch(state),
|
||||||
|
spec.DOMAIN_DEPOSIT,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
deposit_input.proof_of_possession = proof_of_possession
|
||||||
|
deposit_data = DepositData(
|
||||||
|
amount=amount,
|
||||||
|
timestamp=0,
|
||||||
|
deposit_input=deposit_input,
|
||||||
|
)
|
||||||
|
return deposit_data
|
||||||
|
|
||||||
|
|
||||||
|
def build_attestation_data(state, slot, shard):
|
||||||
|
assert state.slot >= slot
|
||||||
|
|
||||||
|
block_root = build_empty_block_for_next_slot(state).previous_block_root
|
||||||
|
|
||||||
|
epoch_start_slot = get_epoch_start_slot(get_current_epoch(state))
|
||||||
|
if epoch_start_slot == slot:
|
||||||
|
epoch_boundary_root = block_root
|
||||||
|
else:
|
||||||
|
get_block_root(state, epoch_start_slot)
|
||||||
|
|
||||||
|
if slot < epoch_start_slot:
|
||||||
|
justified_block_root = state.previous_justified_root
|
||||||
|
else:
|
||||||
|
justified_block_root = state.current_justified_root
|
||||||
|
|
||||||
|
return AttestationData(
|
||||||
|
slot=slot,
|
||||||
|
shard=shard,
|
||||||
|
beacon_block_root=block_root,
|
||||||
|
source_epoch=state.current_justified_epoch,
|
||||||
|
source_root=justified_block_root,
|
||||||
|
target_root=epoch_boundary_root,
|
||||||
|
crosslink_data_root=spec.ZERO_HASH,
|
||||||
|
previous_crosslink=deepcopy(state.latest_crosslinks[shard]),
|
||||||
|
)
|
@ -1,8 +1,10 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from py_ecc import bls
|
from py_ecc import bls
|
||||||
import build.phase0.spec as spec
|
import build.phase0.spec as spec
|
||||||
|
|
||||||
@ -48,78 +50,15 @@ from build.phase0.utils.merkle_minimal import (
|
|||||||
get_merkle_proof,
|
get_merkle_proof,
|
||||||
get_merkle_root,
|
get_merkle_root,
|
||||||
)
|
)
|
||||||
# from state_test_gen import (
|
from tests.phase0.helpers import (
|
||||||
# generate_from_test,
|
build_attestation_data,
|
||||||
# dump_json,
|
build_deposit_data,
|
||||||
# dump_yaml,
|
build_empty_block_for_next_slot,
|
||||||
# )
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_empty_root():
|
# mark entire file as 'sanity'
|
||||||
return get_merkle_root((spec.ZERO_HASH,))
|
pytestmark = pytest.mark.sanity
|
||||||
|
|
||||||
|
|
||||||
def construct_empty_block_for_next_slot(state):
|
|
||||||
empty_block = get_empty_block()
|
|
||||||
empty_block.slot = state.slot + 1
|
|
||||||
previous_block_header = deepcopy(state.latest_block_header)
|
|
||||||
if previous_block_header.state_root == spec.ZERO_HASH:
|
|
||||||
previous_block_header.state_root = state.hash_tree_root()
|
|
||||||
empty_block.previous_block_root = previous_block_header.hash_tree_root()
|
|
||||||
return empty_block
|
|
||||||
|
|
||||||
|
|
||||||
def create_deposit_data(state, pubkey, privkey, amount):
|
|
||||||
deposit_input = DepositInput(
|
|
||||||
pubkey=pubkey,
|
|
||||||
withdrawal_credentials=privkey.to_bytes(32, byteorder='big'),
|
|
||||||
proof_of_possession=b'00'*96,
|
|
||||||
)
|
|
||||||
proof_of_possession = bls.sign(
|
|
||||||
message_hash=signed_root(deposit_input),
|
|
||||||
privkey=privkey,
|
|
||||||
domain=get_domain(
|
|
||||||
state.fork,
|
|
||||||
get_current_epoch(state),
|
|
||||||
spec.DOMAIN_DEPOSIT,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
deposit_input.proof_of_possession = proof_of_possession
|
|
||||||
deposit_data = DepositData(
|
|
||||||
amount=amount,
|
|
||||||
timestamp=0,
|
|
||||||
deposit_input=deposit_input,
|
|
||||||
)
|
|
||||||
return deposit_data
|
|
||||||
|
|
||||||
|
|
||||||
def build_attestation_data(state, slot, shard):
|
|
||||||
assert state.slot >= slot
|
|
||||||
|
|
||||||
block_root = construct_empty_block_for_next_slot(state).previous_block_root
|
|
||||||
|
|
||||||
epoch_start_slot = get_epoch_start_slot(get_current_epoch(state))
|
|
||||||
if epoch_start_slot == slot:
|
|
||||||
epoch_boundary_root = block_root
|
|
||||||
else:
|
|
||||||
get_block_root(state, epoch_start_slot)
|
|
||||||
|
|
||||||
if slot < epoch_start_slot:
|
|
||||||
justified_block_root = state.previous_justified_root
|
|
||||||
else:
|
|
||||||
justified_block_root = state.current_justified_root
|
|
||||||
|
|
||||||
return AttestationData(
|
|
||||||
slot=slot,
|
|
||||||
shard=shard,
|
|
||||||
beacon_block_root=block_root,
|
|
||||||
source_epoch=state.current_justified_epoch,
|
|
||||||
source_root=justified_block_root,
|
|
||||||
target_root=epoch_boundary_root,
|
|
||||||
crosslink_data_root=spec.ZERO_HASH,
|
|
||||||
previous_crosslink=deepcopy(state.latest_crosslinks[shard]),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_slot_transition(state):
|
def test_slot_transition(state):
|
||||||
test_state = deepcopy(state)
|
test_state = deepcopy(state)
|
||||||
@ -133,7 +72,7 @@ def test_slot_transition(state):
|
|||||||
def test_empty_block_transition(state):
|
def test_empty_block_transition(state):
|
||||||
test_state = deepcopy(state)
|
test_state = deepcopy(state)
|
||||||
|
|
||||||
block = construct_empty_block_for_next_slot(test_state)
|
block = build_empty_block_for_next_slot(test_state)
|
||||||
state_transition(test_state, block)
|
state_transition(test_state, block)
|
||||||
|
|
||||||
assert len(test_state.eth1_data_votes) == len(state.eth1_data_votes) + 1
|
assert len(test_state.eth1_data_votes) == len(state.eth1_data_votes) + 1
|
||||||
@ -144,7 +83,7 @@ def test_empty_block_transition(state):
|
|||||||
|
|
||||||
def test_skipped_slots(state):
|
def test_skipped_slots(state):
|
||||||
test_state = deepcopy(state)
|
test_state = deepcopy(state)
|
||||||
block = construct_empty_block_for_next_slot(test_state)
|
block = build_empty_block_for_next_slot(test_state)
|
||||||
block.slot += 3
|
block.slot += 3
|
||||||
|
|
||||||
state_transition(test_state, block)
|
state_transition(test_state, block)
|
||||||
@ -158,7 +97,7 @@ def test_skipped_slots(state):
|
|||||||
|
|
||||||
def test_empty_epoch_transition(state):
|
def test_empty_epoch_transition(state):
|
||||||
test_state = deepcopy(state)
|
test_state = deepcopy(state)
|
||||||
block = construct_empty_block_for_next_slot(test_state)
|
block = build_empty_block_for_next_slot(test_state)
|
||||||
block.slot += spec.SLOTS_PER_EPOCH
|
block.slot += spec.SLOTS_PER_EPOCH
|
||||||
|
|
||||||
state_transition(test_state, block)
|
state_transition(test_state, block)
|
||||||
@ -172,7 +111,7 @@ def test_empty_epoch_transition(state):
|
|||||||
|
|
||||||
def test_empty_epoch_transition_not_finalizing(state):
|
def test_empty_epoch_transition_not_finalizing(state):
|
||||||
test_state = deepcopy(state)
|
test_state = deepcopy(state)
|
||||||
block = construct_empty_block_for_next_slot(test_state)
|
block = build_empty_block_for_next_slot(test_state)
|
||||||
block.slot += spec.SLOTS_PER_EPOCH * 5
|
block.slot += spec.SLOTS_PER_EPOCH * 5
|
||||||
|
|
||||||
state_transition(test_state, block)
|
state_transition(test_state, block)
|
||||||
@ -226,7 +165,7 @@ def test_proposer_slashing(state, pubkeys, privkeys):
|
|||||||
#
|
#
|
||||||
# Add to state via block transition
|
# Add to state via block transition
|
||||||
#
|
#
|
||||||
block = construct_empty_block_for_next_slot(test_state)
|
block = build_empty_block_for_next_slot(test_state)
|
||||||
block.body.proposer_slashings.append(proposer_slashing)
|
block.body.proposer_slashings.append(proposer_slashing)
|
||||||
state_transition(test_state, block)
|
state_transition(test_state, block)
|
||||||
|
|
||||||
@ -251,7 +190,7 @@ def test_deposit_in_block(state, deposit_data_leaves, pubkeys, privkeys):
|
|||||||
index = len(test_deposit_data_leaves)
|
index = len(test_deposit_data_leaves)
|
||||||
pubkey = pubkeys[index]
|
pubkey = pubkeys[index]
|
||||||
privkey = privkeys[index]
|
privkey = privkeys[index]
|
||||||
deposit_data = create_deposit_data(pre_state, pubkey, privkey, spec.MAX_DEPOSIT_AMOUNT)
|
deposit_data = build_deposit_data(pre_state, pubkey, privkey, spec.MAX_DEPOSIT_AMOUNT)
|
||||||
|
|
||||||
item = hash(deposit_data.serialize())
|
item = hash(deposit_data.serialize())
|
||||||
test_deposit_data_leaves.append(item)
|
test_deposit_data_leaves.append(item)
|
||||||
@ -268,7 +207,7 @@ def test_deposit_in_block(state, deposit_data_leaves, pubkeys, privkeys):
|
|||||||
|
|
||||||
pre_state.latest_eth1_data.deposit_root = root
|
pre_state.latest_eth1_data.deposit_root = root
|
||||||
post_state = deepcopy(pre_state)
|
post_state = deepcopy(pre_state)
|
||||||
block = construct_empty_block_for_next_slot(post_state)
|
block = build_empty_block_for_next_slot(post_state)
|
||||||
block.body.deposits.append(deposit)
|
block.body.deposits.append(deposit)
|
||||||
|
|
||||||
state_transition(post_state, block)
|
state_transition(post_state, block)
|
||||||
@ -287,7 +226,7 @@ def test_deposit_top_up(state, pubkeys, privkeys, deposit_data_leaves):
|
|||||||
amount = spec.MAX_DEPOSIT_AMOUNT // 4
|
amount = spec.MAX_DEPOSIT_AMOUNT // 4
|
||||||
pubkey = pubkeys[validator_index]
|
pubkey = pubkeys[validator_index]
|
||||||
privkey = privkeys[validator_index]
|
privkey = privkeys[validator_index]
|
||||||
deposit_data = create_deposit_data(pre_state, pubkey, privkey, amount)
|
deposit_data = build_deposit_data(pre_state, pubkey, privkey, amount)
|
||||||
|
|
||||||
merkle_index = len(test_deposit_data_leaves)
|
merkle_index = len(test_deposit_data_leaves)
|
||||||
item = hash(deposit_data.serialize())
|
item = hash(deposit_data.serialize())
|
||||||
@ -304,7 +243,7 @@ def test_deposit_top_up(state, pubkeys, privkeys, deposit_data_leaves):
|
|||||||
)
|
)
|
||||||
|
|
||||||
pre_state.latest_eth1_data.deposit_root = root
|
pre_state.latest_eth1_data.deposit_root = root
|
||||||
block = construct_empty_block_for_next_slot(pre_state)
|
block = build_empty_block_for_next_slot(pre_state)
|
||||||
block.body.deposits.append(deposit)
|
block.body.deposits.append(deposit)
|
||||||
|
|
||||||
pre_balance = pre_state.validator_balances[validator_index]
|
pre_balance = pre_state.validator_balances[validator_index]
|
||||||
@ -365,7 +304,7 @@ def test_attestation(state, pubkeys, privkeys):
|
|||||||
#
|
#
|
||||||
# Add to state via block transition
|
# Add to state via block transition
|
||||||
#
|
#
|
||||||
attestation_block = construct_empty_block_for_next_slot(test_state)
|
attestation_block = build_empty_block_for_next_slot(test_state)
|
||||||
attestation_block.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
|
attestation_block.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
|
||||||
attestation_block.body.attestations.append(attestation)
|
attestation_block.body.attestations.append(attestation)
|
||||||
state_transition(test_state, attestation_block)
|
state_transition(test_state, attestation_block)
|
||||||
@ -377,7 +316,7 @@ def test_attestation(state, pubkeys, privkeys):
|
|||||||
#
|
#
|
||||||
pre_current_epoch_attestations = deepcopy(test_state.current_epoch_attestations)
|
pre_current_epoch_attestations = deepcopy(test_state.current_epoch_attestations)
|
||||||
|
|
||||||
epoch_block = construct_empty_block_for_next_slot(test_state)
|
epoch_block = build_empty_block_for_next_slot(test_state)
|
||||||
epoch_block.slot += spec.SLOTS_PER_EPOCH
|
epoch_block.slot += spec.SLOTS_PER_EPOCH
|
||||||
state_transition(test_state, epoch_block)
|
state_transition(test_state, epoch_block)
|
||||||
|
|
||||||
@ -417,7 +356,7 @@ def test_voluntary_exit(state, pubkeys, privkeys):
|
|||||||
#
|
#
|
||||||
# Add to state via block transition
|
# Add to state via block transition
|
||||||
#
|
#
|
||||||
initiate_exit_block = construct_empty_block_for_next_slot(post_state)
|
initiate_exit_block = build_empty_block_for_next_slot(post_state)
|
||||||
initiate_exit_block.body.voluntary_exits.append(voluntary_exit)
|
initiate_exit_block.body.voluntary_exits.append(voluntary_exit)
|
||||||
state_transition(post_state, initiate_exit_block)
|
state_transition(post_state, initiate_exit_block)
|
||||||
|
|
||||||
@ -428,7 +367,7 @@ def test_voluntary_exit(state, pubkeys, privkeys):
|
|||||||
#
|
#
|
||||||
# Process within epoch transition
|
# Process within epoch transition
|
||||||
#
|
#
|
||||||
exit_block = construct_empty_block_for_next_slot(post_state)
|
exit_block = build_empty_block_for_next_slot(post_state)
|
||||||
exit_block.slot += spec.SLOTS_PER_EPOCH
|
exit_block.slot += spec.SLOTS_PER_EPOCH
|
||||||
state_transition(post_state, exit_block)
|
state_transition(post_state, exit_block)
|
||||||
|
|
||||||
@ -476,7 +415,7 @@ def test_transfer(state, pubkeys, privkeys):
|
|||||||
#
|
#
|
||||||
# Add to state via block transition
|
# Add to state via block transition
|
||||||
#
|
#
|
||||||
block = construct_empty_block_for_next_slot(post_state)
|
block = build_empty_block_for_next_slot(post_state)
|
||||||
block.body.transfers.append(transfer)
|
block.body.transfers.append(transfer)
|
||||||
state_transition(post_state, block)
|
state_transition(post_state, block)
|
||||||
|
|
||||||
@ -503,7 +442,7 @@ def test_ejection(state):
|
|||||||
#
|
#
|
||||||
# trigger epoch transition
|
# trigger epoch transition
|
||||||
#
|
#
|
||||||
block = construct_empty_block_for_next_slot(post_state)
|
block = build_empty_block_for_next_slot(post_state)
|
||||||
block.slot += spec.SLOTS_PER_EPOCH
|
block.slot += spec.SLOTS_PER_EPOCH
|
||||||
state_transition(post_state, block)
|
state_transition(post_state, block)
|
||||||
|
|
||||||
@ -518,7 +457,7 @@ def test_historical_batch(state):
|
|||||||
|
|
||||||
post_state = deepcopy(pre_state)
|
post_state = deepcopy(pre_state)
|
||||||
|
|
||||||
block = construct_empty_block_for_next_slot(post_state)
|
block = build_empty_block_for_next_slot(post_state)
|
||||||
|
|
||||||
state_transition(post_state, block)
|
state_transition(post_state, block)
|
||||||
|
|
||||||
@ -527,106 +466,3 @@ def test_historical_batch(state):
|
|||||||
assert len(post_state.historical_roots) == len(pre_state.historical_roots) + 1
|
assert len(post_state.historical_roots) == len(pre_state.historical_roots) + 1
|
||||||
|
|
||||||
return pre_state, [block], post_state
|
return pre_state, [block], post_state
|
||||||
|
|
||||||
|
|
||||||
def sanity_tests(num_validators=100, config=None):
|
|
||||||
print(f"Buidling state with {num_validators} validators...")
|
|
||||||
if config:
|
|
||||||
overwrite_spec_config(config)
|
|
||||||
genesis_state = create_genesis_state(num_validators=num_validators)
|
|
||||||
print("done!")
|
|
||||||
print()
|
|
||||||
|
|
||||||
test_cases = []
|
|
||||||
|
|
||||||
print("Running some sanity check tests...\n")
|
|
||||||
test_slot_transition(genesis_state)
|
|
||||||
print("Passed slot transition test\n")
|
|
||||||
test_cases.append(
|
|
||||||
generate_from_test(test_empty_block_transition, genesis_state, config=config, fields=['slot'])
|
|
||||||
)
|
|
||||||
print("Passed empty block transition test\n")
|
|
||||||
test_cases.append(
|
|
||||||
generate_from_test(test_skipped_slots, genesis_state, config=config, fields=['slot', 'latest_block_roots'])
|
|
||||||
)
|
|
||||||
print("Passed skipped slot test\n")
|
|
||||||
test_cases.append(
|
|
||||||
generate_from_test(test_empty_epoch_transition, genesis_state, config=config, fields=['slot', 'latest_block_roots'])
|
|
||||||
)
|
|
||||||
print("Passed empty epoch transition test\n")
|
|
||||||
test_cases.append(
|
|
||||||
generate_from_test(test_empty_epoch_transition_not_finalizing, genesis_state, config=config, fields=['slot', 'finalized_epoch'])
|
|
||||||
)
|
|
||||||
print("Passed non-finalizing epoch test\n")
|
|
||||||
test_cases.append(
|
|
||||||
generate_from_test(test_proposer_slashing, genesis_state, config=config, fields=['validator_registry', 'validator_balances'])
|
|
||||||
)
|
|
||||||
print("Passed proposer slashing test\n")
|
|
||||||
test_cases.append(
|
|
||||||
generate_from_test(test_attestation, genesis_state, config=config, fields=['previous_epoch_attestations', 'current_epoch_attestations'])
|
|
||||||
)
|
|
||||||
print("Passed attestation test\n")
|
|
||||||
test_cases.append(
|
|
||||||
generate_from_test(test_deposit_in_block, genesis_state, config=config, fields=['validator_registry', 'validator_balances'])
|
|
||||||
)
|
|
||||||
print("Passed deposit test\n")
|
|
||||||
test_cases.append(
|
|
||||||
generate_from_test(test_deposit_top_up, genesis_state, config=config, fields=['validator_registry', 'validator_balances'])
|
|
||||||
)
|
|
||||||
print("Passed deposit top up test\n")
|
|
||||||
test_cases.append(
|
|
||||||
generate_from_test(test_voluntary_exit, genesis_state, config=config, fields=['validator_registry'])
|
|
||||||
)
|
|
||||||
print("Passed voluntary exit test\n")
|
|
||||||
test_cases.append(
|
|
||||||
generate_from_test(test_transfer, genesis_state, config=config, fields=['validator_balances'])
|
|
||||||
)
|
|
||||||
print("Passed transfer test\n")
|
|
||||||
test_cases.append(
|
|
||||||
generate_from_test(test_ejection, genesis_state, config=config, fields=['validator_registry'])
|
|
||||||
)
|
|
||||||
print("Passed ejection test\n")
|
|
||||||
test_cases.append(
|
|
||||||
generate_from_test(test_historical_batch, genesis_state, config=config, fields=['historical_roots'])
|
|
||||||
)
|
|
||||||
print("Passed historical batch test\n")
|
|
||||||
print("done!")
|
|
||||||
|
|
||||||
return test_cases
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
config = {
|
|
||||||
"SHARD_COUNT": 8,
|
|
||||||
"MIN_ATTESTATION_INCLUSION_DELAY": 2,
|
|
||||||
"TARGET_COMMITTEE_SIZE": 4,
|
|
||||||
"SLOTS_PER_EPOCH": 8,
|
|
||||||
"GENESIS_EPOCH": spec.GENESIS_SLOT // 8,
|
|
||||||
"SLOTS_PER_HISTORICAL_ROOT": 64,
|
|
||||||
"LATEST_RANDAO_MIXES_LENGTH": 64,
|
|
||||||
"LATEST_ACTIVE_INDEX_ROOTS_LENGTH": 64,
|
|
||||||
"LATEST_SLASHED_EXIT_LENGTH": 64,
|
|
||||||
}
|
|
||||||
|
|
||||||
test_cases = sanity_tests(32, config)
|
|
||||||
# uncomment below to run/generate against the default config
|
|
||||||
# test_cases = sanity_tests(100)
|
|
||||||
|
|
||||||
test = {}
|
|
||||||
metadata = {}
|
|
||||||
metadata['title'] = "Sanity tests"
|
|
||||||
metadata['summary'] = "Basic sanity checks from phase 0 spec pythonization. All tests are run with `verify_signatures` as set to False."
|
|
||||||
metadata['test_suite'] = "beacon_state"
|
|
||||||
metadata['fork'] = "tchaikovsky"
|
|
||||||
metadata['version'] = "v0.5.0"
|
|
||||||
test['metadata'] = metadata
|
|
||||||
test['test_cases'] = test_cases
|
|
||||||
|
|
||||||
if '--output-json' in sys.argv:
|
|
||||||
os.makedirs('output', exist_ok=True)
|
|
||||||
with open("output/sanity_check_tests.json", "w+") as outfile:
|
|
||||||
dump_json(test, outfile)
|
|
||||||
if '--output-yaml' in sys.argv:
|
|
||||||
os.makedirs('output', exist_ok=True)
|
|
||||||
with open("output/sanity_check_tests.yaml", "w+") as outfile:
|
|
||||||
dump_yaml(test, outfile)
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user