backport 839 into dev
This commit is contained in:
parent
40aa82beb7
commit
fceebeec4e
|
@ -4,3 +4,4 @@
|
||||||
/.pytest_cache
|
/.pytest_cache
|
||||||
|
|
||||||
build/
|
build/
|
||||||
|
output/
|
||||||
|
|
|
@ -692,7 +692,8 @@ def get_temporary_block_header(block: BeaconBlock) -> BeaconBlockHeader:
|
||||||
previous_block_root=block.previous_block_root,
|
previous_block_root=block.previous_block_root,
|
||||||
state_root=ZERO_HASH,
|
state_root=ZERO_HASH,
|
||||||
block_body_root=hash_tree_root(block.body),
|
block_body_root=hash_tree_root(block.body),
|
||||||
signature=block.signature,
|
# signed_root(block) is used for block id purposes so signature is a stub
|
||||||
|
signature=EMPTY_SIGNATURE,
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1749,7 +1750,7 @@ def cache_state(state: BeaconState) -> None:
|
||||||
state.latest_block_header.state_root = previous_slot_state_root
|
state.latest_block_header.state_root = previous_slot_state_root
|
||||||
|
|
||||||
# store latest known block for previous slot
|
# store latest known block for previous slot
|
||||||
state.latest_block_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = hash_tree_root(state.latest_block_header)
|
state.latest_block_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = signed_root(state.latest_block_header)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Per-epoch processing
|
### Per-epoch processing
|
||||||
|
@ -2198,8 +2199,8 @@ def update_registry_and_shuffling_data(state: BeaconState) -> None:
|
||||||
state.current_shuffling_epoch = next_epoch
|
state.current_shuffling_epoch = next_epoch
|
||||||
state.current_shuffling_start_shard = (
|
state.current_shuffling_start_shard = (
|
||||||
state.current_shuffling_start_shard +
|
state.current_shuffling_start_shard +
|
||||||
get_current_epoch_committee_count(state) % SHARD_COUNT
|
get_current_epoch_committee_count(state)
|
||||||
)
|
) % SHARD_COUNT
|
||||||
state.current_shuffling_seed = generate_seed(state, state.current_shuffling_epoch)
|
state.current_shuffling_seed = generate_seed(state, state.current_shuffling_epoch)
|
||||||
else:
|
else:
|
||||||
# If processing at least one crosslink keeps failing, then reshuffle every power of two,
|
# If processing at least one crosslink keeps failing, then reshuffle every power of two,
|
||||||
|
@ -2315,7 +2316,7 @@ def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
|
||||||
# Verify that the slots match
|
# Verify that the slots match
|
||||||
assert block.slot == state.slot
|
assert block.slot == state.slot
|
||||||
# Verify that the parent matches
|
# Verify that the parent matches
|
||||||
assert block.previous_block_root == hash_tree_root(state.latest_block_header)
|
assert block.previous_block_root == signed_root(state.latest_block_header)
|
||||||
# Save current block as the new latest block
|
# Save current block as the new latest block
|
||||||
state.latest_block_header = get_temporary_block_header(block)
|
state.latest_block_header = get_temporary_block_header(block)
|
||||||
# Verify proposer is not slashed
|
# Verify proposer is not slashed
|
||||||
|
|
|
@ -4,12 +4,14 @@ import pytest
|
||||||
import build.phase0.spec as spec
|
import build.phase0.spec as spec
|
||||||
|
|
||||||
from build.phase0.spec import (
|
from build.phase0.spec import (
|
||||||
Deposit,
|
|
||||||
get_balance,
|
get_balance,
|
||||||
|
ZERO_HASH,
|
||||||
process_deposit,
|
process_deposit,
|
||||||
)
|
)
|
||||||
from tests.phase0.helpers import (
|
from tests.phase0.helpers import (
|
||||||
build_deposit,
|
build_deposit,
|
||||||
|
privkeys,
|
||||||
|
pubkeys,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,8 +19,10 @@ from tests.phase0.helpers import (
|
||||||
pytestmark = pytest.mark.voluntary_exits
|
pytestmark = pytest.mark.voluntary_exits
|
||||||
|
|
||||||
|
|
||||||
def test_success(state, deposit_data_leaves, pubkeys, privkeys):
|
def test_success(state):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
|
# fill previous deposits with zero-hash
|
||||||
|
deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry)
|
||||||
|
|
||||||
index = len(deposit_data_leaves)
|
index = len(deposit_data_leaves)
|
||||||
pubkey = pubkeys[index]
|
pubkey = pubkeys[index]
|
||||||
|
@ -47,8 +51,9 @@ def test_success(state, deposit_data_leaves, pubkeys, privkeys):
|
||||||
return pre_state, deposit, post_state
|
return pre_state, deposit, post_state
|
||||||
|
|
||||||
|
|
||||||
def test_success_top_up(state, deposit_data_leaves, pubkeys, privkeys):
|
def test_success_top_up(state):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
|
deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry)
|
||||||
|
|
||||||
validator_index = 0
|
validator_index = 0
|
||||||
amount = spec.MAX_DEPOSIT_AMOUNT // 4
|
amount = spec.MAX_DEPOSIT_AMOUNT // 4
|
||||||
|
@ -78,8 +83,9 @@ def test_success_top_up(state, deposit_data_leaves, pubkeys, privkeys):
|
||||||
return pre_state, deposit, post_state
|
return pre_state, deposit, post_state
|
||||||
|
|
||||||
|
|
||||||
def test_wrong_index(state, deposit_data_leaves, pubkeys, privkeys):
|
def test_wrong_index(state):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
|
deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry)
|
||||||
|
|
||||||
index = len(deposit_data_leaves)
|
index = len(deposit_data_leaves)
|
||||||
pubkey = pubkeys[index]
|
pubkey = pubkeys[index]
|
||||||
|
@ -106,8 +112,9 @@ def test_wrong_index(state, deposit_data_leaves, pubkeys, privkeys):
|
||||||
return pre_state, deposit, None
|
return pre_state, deposit, None
|
||||||
|
|
||||||
|
|
||||||
def test_bad_merkle_proof(state, deposit_data_leaves, pubkeys, privkeys):
|
def test_bad_merkle_proof(state):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
|
deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry)
|
||||||
|
|
||||||
index = len(deposit_data_leaves)
|
index = len(deposit_data_leaves)
|
||||||
pubkey = pubkeys[index]
|
pubkey = pubkeys[index]
|
||||||
|
|
|
@ -10,6 +10,7 @@ from build.phase0.spec import (
|
||||||
)
|
)
|
||||||
from tests.phase0.helpers import (
|
from tests.phase0.helpers import (
|
||||||
build_voluntary_exit,
|
build_voluntary_exit,
|
||||||
|
pubkey_to_privkey,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ from tests.phase0.helpers import (
|
||||||
pytestmark = pytest.mark.voluntary_exits
|
pytestmark = pytest.mark.voluntary_exits
|
||||||
|
|
||||||
|
|
||||||
def test_success(state, pub_to_priv):
|
def test_success(state):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
#
|
#
|
||||||
# setup pre_state
|
# setup pre_state
|
||||||
|
@ -30,7 +31,7 @@ def test_success(state, pub_to_priv):
|
||||||
#
|
#
|
||||||
current_epoch = get_current_epoch(pre_state)
|
current_epoch = get_current_epoch(pre_state)
|
||||||
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
|
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
|
||||||
privkey = pub_to_priv[pre_state.validator_registry[validator_index].pubkey]
|
privkey = pubkey_to_privkey[pre_state.validator_registry[validator_index].pubkey]
|
||||||
|
|
||||||
voluntary_exit = build_voluntary_exit(
|
voluntary_exit = build_voluntary_exit(
|
||||||
pre_state,
|
pre_state,
|
||||||
|
@ -52,11 +53,11 @@ def test_success(state, pub_to_priv):
|
||||||
return pre_state, voluntary_exit, post_state
|
return pre_state, voluntary_exit, post_state
|
||||||
|
|
||||||
|
|
||||||
def test_validator_not_active(state, pub_to_priv):
|
def test_validator_not_active(state):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
current_epoch = get_current_epoch(pre_state)
|
current_epoch = get_current_epoch(pre_state)
|
||||||
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
|
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
|
||||||
privkey = pub_to_priv[pre_state.validator_registry[validator_index].pubkey]
|
privkey = pubkey_to_privkey[pre_state.validator_registry[validator_index].pubkey]
|
||||||
|
|
||||||
#
|
#
|
||||||
# setup pre_state
|
# setup pre_state
|
||||||
|
@ -79,7 +80,7 @@ def test_validator_not_active(state, pub_to_priv):
|
||||||
return pre_state, voluntary_exit, None
|
return pre_state, voluntary_exit, None
|
||||||
|
|
||||||
|
|
||||||
def test_validator_already_exited(state, pub_to_priv):
|
def test_validator_already_exited(state):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
#
|
#
|
||||||
# setup pre_state
|
# setup pre_state
|
||||||
|
@ -89,7 +90,7 @@ def test_validator_already_exited(state, pub_to_priv):
|
||||||
|
|
||||||
current_epoch = get_current_epoch(pre_state)
|
current_epoch = get_current_epoch(pre_state)
|
||||||
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
|
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
|
||||||
privkey = pub_to_priv[pre_state.validator_registry[validator_index].pubkey]
|
privkey = pubkey_to_privkey[pre_state.validator_registry[validator_index].pubkey]
|
||||||
|
|
||||||
# but validator already has exited
|
# but validator already has exited
|
||||||
pre_state.validator_registry[validator_index].exit_epoch = current_epoch + 2
|
pre_state.validator_registry[validator_index].exit_epoch = current_epoch + 2
|
||||||
|
@ -110,7 +111,7 @@ def test_validator_already_exited(state, pub_to_priv):
|
||||||
return pre_state, voluntary_exit, None
|
return pre_state, voluntary_exit, None
|
||||||
|
|
||||||
|
|
||||||
def test_validator_already_initiated_exit(state, pub_to_priv):
|
def test_validator_already_initiated_exit(state):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
#
|
#
|
||||||
# setup pre_state
|
# setup pre_state
|
||||||
|
@ -120,7 +121,7 @@ def test_validator_already_initiated_exit(state, pub_to_priv):
|
||||||
|
|
||||||
current_epoch = get_current_epoch(pre_state)
|
current_epoch = get_current_epoch(pre_state)
|
||||||
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
|
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
|
||||||
privkey = pub_to_priv[pre_state.validator_registry[validator_index].pubkey]
|
privkey = pubkey_to_privkey[pre_state.validator_registry[validator_index].pubkey]
|
||||||
|
|
||||||
# but validator already has initiated exit
|
# but validator already has initiated exit
|
||||||
pre_state.validator_registry[validator_index].initiated_exit = True
|
pre_state.validator_registry[validator_index].initiated_exit = True
|
||||||
|
@ -141,14 +142,14 @@ def test_validator_already_initiated_exit(state, pub_to_priv):
|
||||||
return pre_state, voluntary_exit, None
|
return pre_state, voluntary_exit, None
|
||||||
|
|
||||||
|
|
||||||
def test_validator_not_active_long_enough(state, pub_to_priv):
|
def test_validator_not_active_long_enough(state):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
#
|
#
|
||||||
# setup pre_state
|
# setup pre_state
|
||||||
#
|
#
|
||||||
current_epoch = get_current_epoch(pre_state)
|
current_epoch = get_current_epoch(pre_state)
|
||||||
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
|
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
|
||||||
privkey = pub_to_priv[pre_state.validator_registry[validator_index].pubkey]
|
privkey = pubkey_to_privkey[pre_state.validator_registry[validator_index].pubkey]
|
||||||
|
|
||||||
# but validator already has initiated exit
|
# but validator already has initiated exit
|
||||||
pre_state.validator_registry[validator_index].initiated_exit = True
|
pre_state.validator_registry[validator_index].initiated_exit = True
|
||||||
|
|
|
@ -3,9 +3,6 @@ import pytest
|
||||||
from build.phase0 import spec
|
from build.phase0 import spec
|
||||||
|
|
||||||
from tests.phase0.helpers import (
|
from tests.phase0.helpers import (
|
||||||
privkeys_list,
|
|
||||||
pubkeys_list,
|
|
||||||
pubkey_to_privkey,
|
|
||||||
create_genesis_state,
|
create_genesis_state,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,21 +22,6 @@ MINIMAL_CONFIG = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def privkeys():
|
|
||||||
return privkeys_list
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def pubkeys():
|
|
||||||
return pubkeys_list
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def pub_to_priv():
|
|
||||||
return pubkey_to_privkey
|
|
||||||
|
|
||||||
|
|
||||||
def overwrite_spec_config(config):
|
def overwrite_spec_config(config):
|
||||||
for field in config:
|
for field in config:
|
||||||
setattr(spec, field, config[field])
|
setattr(spec, field, config[field])
|
||||||
|
|
|
@ -35,18 +35,20 @@ from build.phase0.utils.merkle_minimal import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
privkeys_list = [i + 1 for i in range(1000)]
|
privkeys = [i + 1 for i in range(1000)]
|
||||||
pubkeys_list = [bls.privtopub(privkey) for privkey in privkeys_list]
|
pubkeys = [bls.privtopub(privkey) for privkey in privkeys]
|
||||||
pubkey_to_privkey = {pubkey: privkey for privkey, pubkey in zip(privkeys_list, pubkeys_list)}
|
pubkey_to_privkey = {pubkey: privkey for privkey, pubkey in zip(privkeys, pubkeys)}
|
||||||
|
|
||||||
|
|
||||||
def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves):
|
def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves=None):
|
||||||
|
if not deposit_data_leaves:
|
||||||
|
deposit_data_leaves = []
|
||||||
deposit_timestamp = 0
|
deposit_timestamp = 0
|
||||||
proof_of_possession = b'\x33' * 96
|
proof_of_possession = b'\x33' * 96
|
||||||
|
|
||||||
deposit_data_list = []
|
deposit_data_list = []
|
||||||
for i in range(num_validators):
|
for i in range(num_validators):
|
||||||
pubkey = pubkeys_list[i]
|
pubkey = pubkeys[i]
|
||||||
deposit_data = DepositData(
|
deposit_data = DepositData(
|
||||||
amount=spec.MAX_DEPOSIT_AMOUNT,
|
amount=spec.MAX_DEPOSIT_AMOUNT,
|
||||||
timestamp=deposit_timestamp,
|
timestamp=deposit_timestamp,
|
||||||
|
@ -75,7 +77,7 @@ def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves):
|
||||||
return genesis_validator_deposits, root
|
return genesis_validator_deposits, root
|
||||||
|
|
||||||
|
|
||||||
def create_genesis_state(num_validators, deposit_data_leaves):
|
def create_genesis_state(num_validators, deposit_data_leaves=None):
|
||||||
initial_deposits, deposit_root = create_mock_genesis_validator_deposits(
|
initial_deposits, deposit_root = create_mock_genesis_validator_deposits(
|
||||||
num_validators,
|
num_validators,
|
||||||
deposit_data_leaves,
|
deposit_data_leaves,
|
||||||
|
@ -105,7 +107,7 @@ def build_empty_block_for_next_slot(state):
|
||||||
previous_block_header = deepcopy(state.latest_block_header)
|
previous_block_header = deepcopy(state.latest_block_header)
|
||||||
if previous_block_header.state_root == spec.ZERO_HASH:
|
if previous_block_header.state_root == spec.ZERO_HASH:
|
||||||
previous_block_header.state_root = state.hash_tree_root()
|
previous_block_header.state_root = state.hash_tree_root()
|
||||||
empty_block.previous_block_root = previous_block_header.hash_tree_root()
|
empty_block.previous_block_root = signed_root(previous_block_header)
|
||||||
return empty_block
|
return empty_block
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,8 @@ from tests.phase0.helpers import (
|
||||||
build_empty_block_for_next_slot,
|
build_empty_block_for_next_slot,
|
||||||
force_registry_change_at_next_epoch,
|
force_registry_change_at_next_epoch,
|
||||||
get_valid_proposer_slashing,
|
get_valid_proposer_slashing,
|
||||||
|
privkeys,
|
||||||
|
pubkeys,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,7 +118,7 @@ def test_empty_epoch_transition_not_finalizing(state):
|
||||||
return state, [block], test_state
|
return state, [block], test_state
|
||||||
|
|
||||||
|
|
||||||
def test_proposer_slashing(state, pubkeys, privkeys):
|
def test_proposer_slashing(state):
|
||||||
test_state = deepcopy(state)
|
test_state = deepcopy(state)
|
||||||
proposer_slashing = get_valid_proposer_slashing(state)
|
proposer_slashing = get_valid_proposer_slashing(state)
|
||||||
validator_index = proposer_slashing.proposer_index
|
validator_index = proposer_slashing.proposer_index
|
||||||
|
@ -142,9 +144,9 @@ def test_proposer_slashing(state, pubkeys, privkeys):
|
||||||
return state, [block], test_state
|
return state, [block], test_state
|
||||||
|
|
||||||
|
|
||||||
def test_deposit_in_block(state, deposit_data_leaves, pubkeys, privkeys):
|
def test_deposit_in_block(state):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
test_deposit_data_leaves = deepcopy(deposit_data_leaves)
|
test_deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry)
|
||||||
|
|
||||||
index = len(test_deposit_data_leaves)
|
index = len(test_deposit_data_leaves)
|
||||||
pubkey = pubkeys[index]
|
pubkey = pubkeys[index]
|
||||||
|
@ -179,9 +181,9 @@ def test_deposit_in_block(state, deposit_data_leaves, pubkeys, privkeys):
|
||||||
return pre_state, [block], post_state
|
return pre_state, [block], post_state
|
||||||
|
|
||||||
|
|
||||||
def test_deposit_top_up(state, pubkeys, privkeys, deposit_data_leaves):
|
def test_deposit_top_up(state):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
test_deposit_data_leaves = deepcopy(deposit_data_leaves)
|
test_deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry)
|
||||||
|
|
||||||
validator_index = 0
|
validator_index = 0
|
||||||
amount = spec.MAX_DEPOSIT_AMOUNT // 4
|
amount = spec.MAX_DEPOSIT_AMOUNT // 4
|
||||||
|
@ -218,7 +220,7 @@ def test_deposit_top_up(state, pubkeys, privkeys, deposit_data_leaves):
|
||||||
return pre_state, [block], post_state
|
return pre_state, [block], post_state
|
||||||
|
|
||||||
|
|
||||||
def test_attestation(state, pubkeys, privkeys):
|
def test_attestation(state):
|
||||||
test_state = deepcopy(state)
|
test_state = deepcopy(state)
|
||||||
slot = state.slot
|
slot = state.slot
|
||||||
shard = state.current_shuffling_start_shard
|
shard = state.current_shuffling_start_shard
|
||||||
|
@ -287,7 +289,7 @@ def test_attestation(state, pubkeys, privkeys):
|
||||||
return state, [attestation_block, epoch_block], test_state
|
return state, [attestation_block, epoch_block], test_state
|
||||||
|
|
||||||
|
|
||||||
def test_voluntary_exit(state, pubkeys, privkeys):
|
def test_voluntary_exit(state):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
validator_index = get_active_validator_indices(
|
validator_index = get_active_validator_indices(
|
||||||
pre_state.validator_registry,
|
pre_state.validator_registry,
|
||||||
|
@ -375,7 +377,7 @@ def test_no_exit_churn_too_long_since_change(state):
|
||||||
return pre_state, [block], post_state
|
return pre_state, [block], post_state
|
||||||
|
|
||||||
|
|
||||||
def test_transfer(state, pubkeys, privkeys):
|
def test_transfer(state):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
current_epoch = get_current_epoch(pre_state)
|
current_epoch = get_current_epoch(pre_state)
|
||||||
sender_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[-1]
|
sender_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[-1]
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
from .minimal_ssz import hash_tree_root
|
||||||
|
|
||||||
|
|
||||||
|
def jsonize(value, typ, include_hash_tree_roots=False):
|
||||||
|
if isinstance(typ, str) and typ[:4] == 'uint':
|
||||||
|
return value
|
||||||
|
elif typ == 'bool':
|
||||||
|
assert value in (True, False)
|
||||||
|
return value
|
||||||
|
elif isinstance(typ, list):
|
||||||
|
return [jsonize(element, typ[0], include_hash_tree_roots) for element in value]
|
||||||
|
elif isinstance(typ, str) and typ[:4] == 'byte':
|
||||||
|
return '0x' + value.hex()
|
||||||
|
elif hasattr(typ, 'fields'):
|
||||||
|
ret = {}
|
||||||
|
for field, subtype in typ.fields.items():
|
||||||
|
ret[field] = jsonize(getattr(value, field), subtype, include_hash_tree_roots)
|
||||||
|
if include_hash_tree_roots:
|
||||||
|
ret[field + "_hash_tree_root"] = '0x' + hash_tree_root(getattr(value, field), subtype).hex()
|
||||||
|
if include_hash_tree_roots:
|
||||||
|
ret["hash_tree_root"] = '0x' + hash_tree_root(value, typ).hex()
|
||||||
|
return ret
|
||||||
|
else:
|
||||||
|
print(value, typ)
|
||||||
|
raise Exception("Type not recognized")
|
||||||
|
|
||||||
|
|
||||||
|
def dejsonize(json, typ):
|
||||||
|
if isinstance(typ, str) and typ[:4] == 'uint':
|
||||||
|
return json
|
||||||
|
elif typ == 'bool':
|
||||||
|
assert json in (True, False)
|
||||||
|
return json
|
||||||
|
elif isinstance(typ, list):
|
||||||
|
return [dejsonize(element, typ[0]) for element in json]
|
||||||
|
elif isinstance(typ, str) and typ[:4] == 'byte':
|
||||||
|
return bytes.fromhex(json[2:])
|
||||||
|
elif hasattr(typ, 'fields'):
|
||||||
|
temp = {}
|
||||||
|
for field, subtype in typ.fields.items():
|
||||||
|
temp[field] = dejsonize(json[field], subtype)
|
||||||
|
if field + "_hash_tree_root" in json:
|
||||||
|
assert(json[field + "_hash_tree_root"][2:] ==
|
||||||
|
hash_tree_root(temp[field], subtype).hex())
|
||||||
|
ret = typ(**temp)
|
||||||
|
if "hash_tree_root" in json:
|
||||||
|
assert(json["hash_tree_root"][2:] ==
|
||||||
|
hash_tree_root(ret, typ).hex())
|
||||||
|
return ret
|
||||||
|
else:
|
||||||
|
print(json, typ)
|
||||||
|
raise Exception("Type not recognized")
|
Loading…
Reference in New Issue