mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-01-24 17:39:05 +00:00
Merge pull request #1165 from ethereum/phase-generators
phase restricted generators
This commit is contained in:
commit
577f76aff5
@ -2,7 +2,7 @@ from typing import Callable, Iterable
|
|||||||
|
|
||||||
from eth2spec.phase0 import spec as spec_phase0
|
from eth2spec.phase0 import spec as spec_phase0
|
||||||
from eth2spec.phase1 import spec as spec_phase1
|
from eth2spec.phase1 import spec as spec_phase1
|
||||||
from eth2spec.test.epoch_processing import (
|
from eth2spec.test.phase_0.epoch_processing import (
|
||||||
test_process_crosslinks,
|
test_process_crosslinks,
|
||||||
test_process_registry_updates
|
test_process_registry_updates
|
||||||
)
|
)
|
||||||
@ -33,8 +33,10 @@ def create_suite(transition_name: str, config_name: str, get_cases: Callable[[],
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
gen_runner.run_generator("epoch_processing", [
|
gen_runner.run_generator("epoch_processing", [
|
||||||
create_suite('crosslinks', 'minimal', lambda: generate_from_tests(test_process_crosslinks)),
|
create_suite('crosslinks', 'minimal', lambda: generate_from_tests(test_process_crosslinks, 'phase0')),
|
||||||
create_suite('crosslinks', 'mainnet', lambda: generate_from_tests(test_process_crosslinks)),
|
create_suite('crosslinks', 'mainnet', lambda: generate_from_tests(test_process_crosslinks, 'phase0')),
|
||||||
create_suite('registry_updates', 'minimal', lambda: generate_from_tests(test_process_registry_updates)),
|
create_suite('registry_updates', 'minimal',
|
||||||
create_suite('registry_updates', 'mainnet', lambda: generate_from_tests(test_process_registry_updates)),
|
lambda: generate_from_tests(test_process_registry_updates, 'phase0')),
|
||||||
|
create_suite('registry_updates', 'mainnet',
|
||||||
|
lambda: generate_from_tests(test_process_registry_updates, 'phase0')),
|
||||||
])
|
])
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
from typing import Callable, Iterable
|
from typing import Callable, Iterable
|
||||||
|
|
||||||
from eth2spec.test.block_processing import (
|
from eth2spec.test.phase_0.block_processing import (
|
||||||
test_process_attestation,
|
test_process_attestation,
|
||||||
test_process_attester_slashing,
|
test_process_attester_slashing,
|
||||||
test_process_block_header,
|
test_process_block_header,
|
||||||
test_process_deposit,
|
test_process_deposit,
|
||||||
test_process_proposer_slashing,
|
test_process_proposer_slashing,
|
||||||
test_process_transfer,
|
test_process_transfer,
|
||||||
test_process_voluntary_exit
|
test_process_voluntary_exit,
|
||||||
)
|
)
|
||||||
|
|
||||||
from gen_base import gen_runner, gen_suite, gen_typing
|
from gen_base import gen_runner, gen_suite, gen_typing
|
||||||
@ -38,18 +38,18 @@ def create_suite(operation_name: str, config_name: str, get_cases: Callable[[],
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
gen_runner.run_generator("operations", [
|
gen_runner.run_generator("operations", [
|
||||||
create_suite('attestation', 'minimal', lambda: generate_from_tests(test_process_attestation)),
|
create_suite('attestation', 'minimal', lambda: generate_from_tests(test_process_attestation, 'phase0')),
|
||||||
create_suite('attestation', 'mainnet', lambda: generate_from_tests(test_process_attestation)),
|
create_suite('attestation', 'mainnet', lambda: generate_from_tests(test_process_attestation, 'phase0')),
|
||||||
create_suite('attester_slashing', 'minimal', lambda: generate_from_tests(test_process_attester_slashing)),
|
create_suite('attester_slashing', 'minimal', lambda: generate_from_tests(test_process_attester_slashing, 'phase0')),
|
||||||
create_suite('attester_slashing', 'mainnet', lambda: generate_from_tests(test_process_attester_slashing)),
|
create_suite('attester_slashing', 'mainnet', lambda: generate_from_tests(test_process_attester_slashing, 'phase0')),
|
||||||
create_suite('block_header', 'minimal', lambda: generate_from_tests(test_process_block_header)),
|
create_suite('block_header', 'minimal', lambda: generate_from_tests(test_process_block_header, 'phase0')),
|
||||||
create_suite('block_header', 'mainnet', lambda: generate_from_tests(test_process_block_header)),
|
create_suite('block_header', 'mainnet', lambda: generate_from_tests(test_process_block_header, 'phase0')),
|
||||||
create_suite('deposit', 'minimal', lambda: generate_from_tests(test_process_deposit)),
|
create_suite('deposit', 'minimal', lambda: generate_from_tests(test_process_deposit, 'phase0')),
|
||||||
create_suite('deposit', 'mainnet', lambda: generate_from_tests(test_process_deposit)),
|
create_suite('deposit', 'mainnet', lambda: generate_from_tests(test_process_deposit, 'phase0')),
|
||||||
create_suite('proposer_slashing', 'minimal', lambda: generate_from_tests(test_process_proposer_slashing)),
|
create_suite('proposer_slashing', 'minimal', lambda: generate_from_tests(test_process_proposer_slashing, 'phase0')),
|
||||||
create_suite('proposer_slashing', 'mainnet', lambda: generate_from_tests(test_process_proposer_slashing)),
|
create_suite('proposer_slashing', 'mainnet', lambda: generate_from_tests(test_process_proposer_slashing, 'phase0')),
|
||||||
create_suite('transfer', 'minimal', lambda: generate_from_tests(test_process_transfer)),
|
create_suite('transfer', 'minimal', lambda: generate_from_tests(test_process_transfer, 'phase0')),
|
||||||
create_suite('transfer', 'mainnet', lambda: generate_from_tests(test_process_transfer)),
|
create_suite('transfer', 'mainnet', lambda: generate_from_tests(test_process_transfer, 'phase0')),
|
||||||
create_suite('voluntary_exit', 'minimal', lambda: generate_from_tests(test_process_voluntary_exit)),
|
create_suite('voluntary_exit', 'minimal', lambda: generate_from_tests(test_process_voluntary_exit, 'phase0')),
|
||||||
create_suite('voluntary_exit', 'mainnet', lambda: generate_from_tests(test_process_voluntary_exit)),
|
create_suite('voluntary_exit', 'mainnet', lambda: generate_from_tests(test_process_voluntary_exit, 'phase0')),
|
||||||
])
|
])
|
||||||
|
@ -16,7 +16,7 @@ def create_suite(handler_name: str, config_name: str, get_cases: Callable[[], It
|
|||||||
spec_phase0.apply_constants_preset(presets)
|
spec_phase0.apply_constants_preset(presets)
|
||||||
spec_phase1.apply_constants_preset(presets)
|
spec_phase1.apply_constants_preset(presets)
|
||||||
|
|
||||||
return ("%sanity_s_%s" % (handler_name, config_name), handler_name, gen_suite.render_suite(
|
return ("sanity_%s_%s" % (handler_name, config_name), handler_name, gen_suite.render_suite(
|
||||||
title="sanity testing",
|
title="sanity testing",
|
||||||
summary="Sanity test suite, %s type, generated from pytests" % handler_name,
|
summary="Sanity test suite, %s type, generated from pytests" % handler_name,
|
||||||
forks_timeline="testing",
|
forks_timeline="testing",
|
||||||
@ -30,8 +30,8 @@ def create_suite(handler_name: str, config_name: str, get_cases: Callable[[], It
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
gen_runner.run_generator("sanity", [
|
gen_runner.run_generator("sanity", [
|
||||||
create_suite('blocks', 'minimal', lambda: generate_from_tests(test_blocks)),
|
create_suite('blocks', 'minimal', lambda: generate_from_tests(test_blocks, 'phase0')),
|
||||||
create_suite('blocks', 'mainnet', lambda: generate_from_tests(test_blocks)),
|
create_suite('blocks', 'mainnet', lambda: generate_from_tests(test_blocks, 'phase0')),
|
||||||
create_suite('slots', 'minimal', lambda: generate_from_tests(test_slots)),
|
create_suite('slots', 'minimal', lambda: generate_from_tests(test_slots, 'phase0')),
|
||||||
create_suite('slots', 'mainnet', lambda: generate_from_tests(test_slots)),
|
create_suite('slots', 'mainnet', lambda: generate_from_tests(test_slots, 'phase0')),
|
||||||
])
|
])
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
from eth2spec.phase0 import spec as spec_phase0
|
from eth2spec.phase0 import spec as spec
|
||||||
from eth2spec.phase1 import spec as spec_phase1
|
|
||||||
from eth_utils import (
|
from eth_utils import (
|
||||||
to_dict, to_tuple
|
to_dict, to_tuple
|
||||||
)
|
)
|
||||||
@ -8,7 +7,7 @@ from preset_loader import loader
|
|||||||
|
|
||||||
|
|
||||||
@to_dict
|
@to_dict
|
||||||
def shuffling_case(seed: spec.Bytes32, count: int):
|
def shuffling_case(seed, count):
|
||||||
yield 'seed', '0x' + seed.hex()
|
yield 'seed', '0x' + seed.hex()
|
||||||
yield 'count', count
|
yield 'count', count
|
||||||
yield 'shuffled', [spec.get_shuffled_index(i, count, seed) for i in range(count)]
|
yield 'shuffled', [spec.get_shuffled_index(i, count, seed) for i in range(count)]
|
||||||
@ -23,8 +22,7 @@ def shuffling_test_cases():
|
|||||||
|
|
||||||
def mini_shuffling_suite(configs_path: str) -> gen_typing.TestSuiteOutput:
|
def mini_shuffling_suite(configs_path: str) -> gen_typing.TestSuiteOutput:
|
||||||
presets = loader.load_presets(configs_path, 'minimal')
|
presets = loader.load_presets(configs_path, 'minimal')
|
||||||
spec_phase0.apply_constants_preset(presets)
|
spec.apply_constants_preset(presets)
|
||||||
spec_phase1.apply_constants_preset(presets)
|
|
||||||
|
|
||||||
return ("shuffling_minimal", "core", gen_suite.render_suite(
|
return ("shuffling_minimal", "core", gen_suite.render_suite(
|
||||||
title="Swap-or-Not Shuffling tests with minimal config",
|
title="Swap-or-Not Shuffling tests with minimal config",
|
||||||
@ -39,8 +37,7 @@ def mini_shuffling_suite(configs_path: str) -> gen_typing.TestSuiteOutput:
|
|||||||
|
|
||||||
def full_shuffling_suite(configs_path: str) -> gen_typing.TestSuiteOutput:
|
def full_shuffling_suite(configs_path: str) -> gen_typing.TestSuiteOutput:
|
||||||
presets = loader.load_presets(configs_path, 'mainnet')
|
presets = loader.load_presets(configs_path, 'mainnet')
|
||||||
spec_phase0.apply_constants_preset(presets)
|
spec.apply_constants_preset(presets)
|
||||||
spec_phase1.apply_constants_preset(presets)
|
|
||||||
|
|
||||||
return ("shuffling_full", "core", gen_suite.render_suite(
|
return ("shuffling_full", "core", gen_suite.render_suite(
|
||||||
title="Swap-or-Not Shuffling tests with mainnet config",
|
title="Swap-or-Not Shuffling tests with mainnet config",
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
from random import Random
|
from random import Random
|
||||||
|
|
||||||
|
from inspect import getmembers, isclass
|
||||||
|
|
||||||
from eth2spec.debug import random_value, encode
|
from eth2spec.debug import random_value, encode
|
||||||
from eth2spec.phase0 import spec
|
from eth2spec.phase0 import spec
|
||||||
|
from eth2spec.utils.ssz.ssz_typing import Container
|
||||||
from eth2spec.utils.ssz.ssz_impl import (
|
from eth2spec.utils.ssz.ssz_impl import (
|
||||||
hash_tree_root,
|
hash_tree_root,
|
||||||
signing_root,
|
signing_root,
|
||||||
@ -27,17 +30,23 @@ def create_test_case_contents(value, typ):
|
|||||||
|
|
||||||
|
|
||||||
@to_dict
|
@to_dict
|
||||||
def create_test_case(rng: Random, name: str, mode: random_value.RandomizationMode, chaos: bool):
|
def create_test_case(rng: Random, name: str, typ, mode: random_value.RandomizationMode, chaos: bool):
|
||||||
typ = spec.get_ssz_type_by_name(name)
|
|
||||||
value = random_value.get_random_ssz_object(rng, typ, MAX_BYTES_LENGTH, MAX_LIST_LENGTH, mode, chaos)
|
value = random_value.get_random_ssz_object(rng, typ, MAX_BYTES_LENGTH, MAX_LIST_LENGTH, mode, chaos)
|
||||||
yield name, create_test_case_contents(value, typ)
|
yield name, create_test_case_contents(value, typ)
|
||||||
|
|
||||||
|
|
||||||
|
def get_spec_ssz_types():
|
||||||
|
return [
|
||||||
|
(name, value) for (name, value) in getmembers(spec, isclass)
|
||||||
|
if issubclass(value, Container) and value != Container # only the subclasses, not the imported base class
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@to_tuple
|
@to_tuple
|
||||||
def ssz_static_cases(rng: Random, mode: random_value.RandomizationMode, chaos: bool, count: int):
|
def ssz_static_cases(rng: Random, mode: random_value.RandomizationMode, chaos: bool, count: int):
|
||||||
for type_name in spec.ssz_types:
|
for (name, ssz_type) in get_spec_ssz_types():
|
||||||
for i in range(count):
|
for i in range(count):
|
||||||
yield create_test_case(rng, type_name, mode, chaos)
|
yield create_test_case(rng, name, ssz_type, mode, chaos)
|
||||||
|
|
||||||
|
|
||||||
def get_ssz_suite(seed: int, config_name: str, mode: random_value.RandomizationMode, chaos: bool, cases_if_random: int):
|
def get_ssz_suite(seed: int, config_name: str, mode: random_value.RandomizationMode, chaos: bool, cases_if_random: int):
|
||||||
@ -81,8 +90,6 @@ if __name__ == "__main__":
|
|||||||
settings.append((seed, "mainnet", random_value.RandomizationMode.mode_random, False, 5))
|
settings.append((seed, "mainnet", random_value.RandomizationMode.mode_random, False, 5))
|
||||||
seed += 1
|
seed += 1
|
||||||
|
|
||||||
print("Settings: %d, SSZ-types: %d" % (len(settings), len(spec.ssz_types)))
|
|
||||||
|
|
||||||
gen_runner.run_generator("ssz_static", [
|
gen_runner.run_generator("ssz_static", [
|
||||||
get_ssz_suite(seed, config_name, mode, chaos, cases_if_random)
|
get_ssz_suite(seed, config_name, mode, chaos, cases_if_random)
|
||||||
for (seed, config_name, mode, chaos, cases_if_random) in settings
|
for (seed, config_name, mode, chaos, cases_if_random) in settings
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
from inspect import getmembers, isfunction
|
from inspect import getmembers, isfunction
|
||||||
|
|
||||||
def generate_from_tests(src, bls_active=True):
|
def generate_from_tests(src, phase, bls_active=True):
|
||||||
"""
|
"""
|
||||||
Generate a list of test cases by running tests from the given src in generator-mode.
|
Generate a list of test cases by running tests from the given src in generator-mode.
|
||||||
:param src: to retrieve tests from (discovered using inspect.getmembers)
|
:param src: to retrieve tests from (discovered using inspect.getmembers).
|
||||||
|
:param phase: to run tests against particular phase.
|
||||||
:param bls_active: optional, to override BLS switch preference. Defaults to True.
|
:param bls_active: optional, to override BLS switch preference. Defaults to True.
|
||||||
:return: the list of test cases.
|
:return: the list of test cases.
|
||||||
"""
|
"""
|
||||||
@ -16,7 +17,7 @@ def generate_from_tests(src, bls_active=True):
|
|||||||
for name in fn_names:
|
for name in fn_names:
|
||||||
tfn = getattr(src, name)
|
tfn = getattr(src, name)
|
||||||
try:
|
try:
|
||||||
test_case = tfn(generator_mode=True, bls_active=bls_active)
|
test_case = tfn(generator_mode=True, phase=phase, bls_active=bls_active)
|
||||||
# If no test case data is returned, the test is ignored.
|
# If no test case data is returned, the test is ignored.
|
||||||
if test_case is not None:
|
if test_case is not None:
|
||||||
out.append(test_case)
|
out.append(test_case)
|
||||||
|
@ -116,12 +116,22 @@ def with_phases(phases):
|
|||||||
def decorator(fn):
|
def decorator(fn):
|
||||||
def run_with_spec_version(spec, *args, **kw):
|
def run_with_spec_version(spec, *args, **kw):
|
||||||
kw['spec'] = spec
|
kw['spec'] = spec
|
||||||
fn(*args, **kw)
|
return fn(*args, **kw)
|
||||||
|
|
||||||
def wrapper(*args, **kw):
|
def wrapper(*args, **kw):
|
||||||
if 'phase0' in phases:
|
run_phases = phases
|
||||||
run_with_spec_version(spec_phase0, *args, **kw)
|
|
||||||
if 'phase1' in phases:
|
# limit phases if one explicitly specified
|
||||||
run_with_spec_version(spec_phase1, *args, **kw)
|
if 'phase' in kw:
|
||||||
|
phase = kw.pop('phase')
|
||||||
|
if phase not in phases:
|
||||||
|
return
|
||||||
|
run_phases = [phase]
|
||||||
|
|
||||||
|
if 'phase0' in run_phases:
|
||||||
|
ret = run_with_spec_version(spec_phase0, *args, **kw)
|
||||||
|
if 'phase1' in run_phases:
|
||||||
|
ret = run_with_spec_version(spec_phase1, *args, **kw)
|
||||||
|
return ret
|
||||||
return wrapper
|
return wrapper
|
||||||
return decorator
|
return decorator
|
||||||
|
@ -5,7 +5,7 @@ from eth2spec.utils.ssz.ssz_impl import signing_root
|
|||||||
from eth2spec.utils.bls import bls_sign
|
from eth2spec.utils.bls import bls_sign
|
||||||
|
|
||||||
from eth2spec.test.helpers.state import get_balance
|
from eth2spec.test.helpers.state import get_balance
|
||||||
from eth2spec.test.helpers.transfers import get_valid_transfer
|
# from eth2spec.test.helpers.transfers import get_valid_transfer
|
||||||
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, sign_block
|
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, sign_block
|
||||||
from eth2spec.test.helpers.keys import privkeys, pubkeys
|
from eth2spec.test.helpers.keys import privkeys, pubkeys
|
||||||
from eth2spec.test.helpers.attester_slashings import get_valid_attester_slashing
|
from eth2spec.test.helpers.attester_slashings import get_valid_attester_slashing
|
||||||
@ -303,38 +303,38 @@ def test_voluntary_exit(spec, state):
|
|||||||
assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH
|
assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH
|
||||||
|
|
||||||
|
|
||||||
@with_all_phases
|
# @with_all_phases
|
||||||
@spec_state_test
|
# @spec_state_test
|
||||||
def test_transfer(spec, state):
|
# def test_transfer(spec, state):
|
||||||
# overwrite default 0 to test
|
# overwrite default 0 to test
|
||||||
spec.MAX_TRANSFERS = 1
|
# spec.MAX_TRANSFERS = 1
|
||||||
|
|
||||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
# sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||||
amount = get_balance(state, sender_index)
|
# amount = get_balance(state, sender_index)
|
||||||
|
|
||||||
transfer = get_valid_transfer(spec, state, state.slot + 1, sender_index, amount, signed=True)
|
# transfer = get_valid_transfer(spec, state, state.slot + 1, sender_index, amount, signed=True)
|
||||||
recipient_index = transfer.recipient
|
# recipient_index = transfer.recipient
|
||||||
pre_transfer_recipient_balance = get_balance(state, recipient_index)
|
# pre_transfer_recipient_balance = get_balance(state, recipient_index)
|
||||||
|
|
||||||
# un-activate so validator can transfer
|
# un-activate so validator can transfer
|
||||||
state.validator_registry[sender_index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
# state.validator_registry[sender_index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||||
|
|
||||||
yield 'pre', state
|
# yield 'pre', state
|
||||||
|
|
||||||
# Add to state via block transition
|
# Add to state via block transition
|
||||||
block = build_empty_block_for_next_slot(spec, state)
|
# block = build_empty_block_for_next_slot(spec, state)
|
||||||
block.body.transfers.append(transfer)
|
# block.body.transfers.append(transfer)
|
||||||
sign_block(spec, state, block)
|
# sign_block(spec, state, block)
|
||||||
|
|
||||||
yield 'blocks', [block], List[spec.BeaconBlock]
|
# yield 'blocks', [block], List[spec.BeaconBlock]
|
||||||
|
|
||||||
spec.state_transition(state, block)
|
# spec.state_transition(state, block)
|
||||||
yield 'post', state
|
# yield 'post', state
|
||||||
|
|
||||||
sender_balance = get_balance(state, sender_index)
|
# sender_balance = get_balance(state, sender_index)
|
||||||
recipient_balance = get_balance(state, recipient_index)
|
# recipient_balance = get_balance(state, recipient_index)
|
||||||
assert sender_balance == 0
|
# assert sender_balance == 0
|
||||||
assert recipient_balance == pre_transfer_recipient_balance + amount
|
# assert recipient_balance == pre_transfer_recipient_balance + amount
|
||||||
|
|
||||||
|
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from typing import Dict, Any, Callable, Iterable
|
from typing import Dict, Any, Callable, Iterable
|
||||||
from eth2spec.debug.encode import encode
|
from eth2spec.debug.encode import encode
|
||||||
|
from eth2spec.utils.ssz.ssz_typing import Container
|
||||||
|
|
||||||
|
|
||||||
def spectest(description: str = None):
|
def spectest(description: str = None):
|
||||||
@ -30,9 +31,13 @@ def spectest(description: str = None):
|
|||||||
else:
|
else:
|
||||||
# Otherwise, try to infer the type, but keep it as-is if it's not a SSZ container.
|
# Otherwise, try to infer the type, but keep it as-is if it's not a SSZ container.
|
||||||
(key, value) = data
|
(key, value) = data
|
||||||
if hasattr(value.__class__, 'fields'):
|
if isinstance(value, Container):
|
||||||
out[key] = encode(value, value.__class__)
|
out[key] = encode(value, value.__class__)
|
||||||
else:
|
else:
|
||||||
|
# not a ssz value.
|
||||||
|
# It could be vector or bytes still, but it is a rare case,
|
||||||
|
# and lists can't be inferred fully (generics lose element type).
|
||||||
|
# In such cases, explicitly state the type of the yielded value as a third yielded object.
|
||||||
out[key] = value
|
out[key] = value
|
||||||
if has_contents:
|
if has_contents:
|
||||||
return out
|
return out
|
||||||
|
@ -1,5 +1,28 @@
|
|||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
|
|
||||||
|
ZERO_BYTES32 = b'\x00' * 32
|
||||||
|
|
||||||
|
|
||||||
|
def _hash(x):
|
||||||
|
return sha256(x).digest()
|
||||||
|
|
||||||
|
|
||||||
|
# Minimal collection of (key, value) pairs, for fast hash-retrieval, to save on repetitive computation cost.
|
||||||
|
# Key = the hash input
|
||||||
|
# Value = the hash output
|
||||||
|
hash_cache = []
|
||||||
|
|
||||||
|
|
||||||
|
def add_zero_hashes_to_cache():
|
||||||
|
zerohashes = [(None, ZERO_BYTES32)]
|
||||||
|
for layer in range(1, 32):
|
||||||
|
k = zerohashes[layer - 1][1] + zerohashes[layer - 1][1]
|
||||||
|
zerohashes.append((k, _hash(k)))
|
||||||
|
hash_cache.extend(zerohashes[1:])
|
||||||
|
|
||||||
|
|
||||||
def hash(x):
|
def hash(x):
|
||||||
return sha256(x).digest()
|
for (k, h) in hash_cache:
|
||||||
|
if x == k:
|
||||||
|
return h
|
||||||
|
return _hash(x)
|
||||||
|
@ -513,13 +513,11 @@ def read_vector_elem_type(vector_typ: Type[Vector[T, L]]) -> T:
|
|||||||
|
|
||||||
|
|
||||||
def read_elem_type(typ):
|
def read_elem_type(typ):
|
||||||
if typ == bytes:
|
if typ == bytes or (isinstance(typ, type) and issubclass(typ, bytes)): # bytes or bytesN
|
||||||
return byte
|
return byte
|
||||||
elif is_list_type(typ):
|
elif is_list_type(typ):
|
||||||
return read_list_elem_type(typ)
|
return read_list_elem_type(typ)
|
||||||
elif is_vector_type(typ):
|
elif is_vector_type(typ):
|
||||||
return read_vector_elem_type(typ)
|
return read_vector_elem_type(typ)
|
||||||
elif issubclass(typ, bytes): # bytes or bytesN
|
|
||||||
return byte
|
|
||||||
else:
|
else:
|
||||||
raise TypeError("Unexpected type: {}".format(typ))
|
raise TypeError("Unexpected type: {}".format(typ))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user