mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-01-12 03:34:20 +00:00
Work for new pyspec based test generators
This commit is contained in:
parent
fea40da6fe
commit
db91c7fe9e
@ -22,7 +22,7 @@ SHUFFLE_ROUND_COUNT: 90
|
||||
# Deposit contract
|
||||
# ---------------------------------------------------------------
|
||||
# **TBD**
|
||||
DEPOSIT_CONTRACT_ADDRESS: 0x1234567890123567890123456789012357890
|
||||
DEPOSIT_CONTRACT_ADDRESS: 0x12345678901235678901234567890123567890
|
||||
# 2**5 ` (= 32)
|
||||
DEPOSIT_CONTRACT_TREE_DEPTH: 32
|
||||
|
||||
|
@ -22,7 +22,7 @@ SHUFFLE_ROUND_COUNT: 90
|
||||
# Deposit contract
|
||||
# ---------------------------------------------------------------
|
||||
# **TBD**
|
||||
DEPOSIT_CONTRACT_ADDRESS: 0x1234567890123567890123456789012357890
|
||||
DEPOSIT_CONTRACT_ADDRESS: 0x12345678901235678901234567890123567890
|
||||
# 2**5 ` (= 32)
|
||||
DEPOSIT_CONTRACT_TREE_DEPTH: 32
|
||||
|
||||
@ -62,8 +62,8 @@ SLOTS_PER_EPOCH: 8
|
||||
MIN_SEED_LOOKAHEAD: 1
|
||||
# 2**2 ` (= 4) epochs 25.6 minutes
|
||||
ACTIVATION_EXIT_DELAY: 4
|
||||
# 2**4 ` (= 16) epochs ~1.7 hours
|
||||
EPOCHS_PER_ETH1_VOTING_PERIOD: 16
|
||||
# [customized] higher frequency new deposits from eth1 for testing
|
||||
EPOCHS_PER_ETH1_VOTING_PERIOD: 2
|
||||
# [customized] smaller state
|
||||
SLOTS_PER_HISTORICAL_ROOT: 64
|
||||
# 2**8 ` (= 256) epochs ~27 hours
|
||||
|
@ -83,11 +83,14 @@ def hash(x):
|
||||
# Access to overwrite spec constants based on configuration
|
||||
def apply_constants_preset(preset: Dict[str, Any]):
|
||||
global_vars = globals()
|
||||
for k, v in preset:
|
||||
for k, v in preset.items():
|
||||
global_vars[k] = v
|
||||
|
||||
# Deal with derived constants
|
||||
GENESIS_EPOCH = slot_to_epoch(GENESIS_SLOT)
|
||||
global_vars['GENESIS_EPOCH'] = slot_to_epoch(GENESIS_SLOT)
|
||||
|
||||
# Initialize SSZ types again, to account for changed lengths
|
||||
init_SSZ_types()
|
||||
""")
|
||||
|
||||
with open(outfile, 'w') as out:
|
||||
|
@ -6,7 +6,8 @@ def get_spec(file_name) -> List[str]:
|
||||
code_lines = []
|
||||
pulling_from = None
|
||||
current_name = None
|
||||
processing_typedef = False
|
||||
current_typedef = None
|
||||
type_defs = []
|
||||
for linenum, line in enumerate(open(sys.argv[1]).readlines()):
|
||||
line = line.rstrip()
|
||||
if pulling_from is None and len(line) > 0 and line[0] == '#' and line[-1] == '`':
|
||||
@ -18,21 +19,26 @@ def get_spec(file_name) -> List[str]:
|
||||
if pulling_from is None:
|
||||
pulling_from = linenum
|
||||
else:
|
||||
if processing_typedef:
|
||||
if current_typedef is not None:
|
||||
assert code_lines[-1] == '}'
|
||||
code_lines[-1] = '})'
|
||||
current_typedef[-1] = '})'
|
||||
type_defs.append((current_name, current_typedef))
|
||||
pulling_from = None
|
||||
processing_typedef = False
|
||||
current_typedef = None
|
||||
else:
|
||||
if pulling_from == linenum and line == '{':
|
||||
code_lines.append('%s = SSZType({' % current_name)
|
||||
processing_typedef = True
|
||||
current_typedef = ['global_vars["%s"] = SSZType({' % current_name]
|
||||
elif pulling_from is not None:
|
||||
# Add some whitespace between functions
|
||||
if line[:3] == 'def':
|
||||
code_lines.append("")
|
||||
code_lines.append("")
|
||||
code_lines.append('')
|
||||
code_lines.append('')
|
||||
code_lines.append(line)
|
||||
# Remember type def lines
|
||||
if current_typedef is not None:
|
||||
current_typedef.append(line)
|
||||
elif pulling_from is None and len(line) > 0 and line[0] == '|':
|
||||
row = line[1:].split('|')
|
||||
if len(row) >= 2:
|
||||
@ -48,4 +54,12 @@ def get_spec(file_name) -> List[str]:
|
||||
eligible = False
|
||||
if eligible:
|
||||
code_lines.append(row[0] + ' = ' + (row[1].replace('**TBD**', '0x1234567890123567890123456789012357890')))
|
||||
# Build type-def re-initialization
|
||||
code_lines.append('')
|
||||
code_lines.append('def init_SSZ_types():')
|
||||
code_lines.append(' global_vars = globals()')
|
||||
for ssz_type_name, ssz_type in type_defs:
|
||||
code_lines.append('')
|
||||
for type_line in ssz_type:
|
||||
code_lines.append(' ' + type_line)
|
||||
return code_lines
|
||||
|
@ -14,5 +14,12 @@ def load_presets(configs_dir, presets_name) -> Dict[str, Any]:
|
||||
:return: Dictionary, mapping of constant-name -> constant-value
|
||||
"""
|
||||
path = Path(join(configs_dir, 'constant_presets', presets_name+'.yaml'))
|
||||
yaml = YAML(typ='safe')
|
||||
return yaml.load(path)
|
||||
yaml = YAML(typ='base')
|
||||
loaded = yaml.load(path)
|
||||
out = dict()
|
||||
for k, v in loaded.items():
|
||||
if v.startswith("0x"):
|
||||
out[k] = bytes.fromhex(v[2:])
|
||||
else:
|
||||
out[k] = int(v)
|
||||
return out
|
||||
|
@ -90,6 +90,7 @@ def run_generator(generator_name, suite_creators: List[TestSuiteCreator]):
|
||||
file_mode = "w"
|
||||
|
||||
yaml = YAML(pure=True)
|
||||
yaml.default_flow_style = None
|
||||
|
||||
print(f"Generating tests for {generator_name}, creating {len(suite_creators)} test suite files...")
|
||||
print(f"Reading config presets and fork timelines from {args.configs_path}")
|
||||
@ -98,6 +99,7 @@ def run_generator(generator_name, suite_creators: List[TestSuiteCreator]):
|
||||
|
||||
handler_output_dir = Path(output_dir) / Path(handler)
|
||||
try:
|
||||
if not handler_output_dir.exists():
|
||||
handler_output_dir.mkdir()
|
||||
except FileNotFoundError as e:
|
||||
sys.exit(f'Error when creating handler dir {handler} for test "{suite["title"]}" ({e})')
|
||||
|
28
test_libs/pyspec/eth2spec/debug/decode.py
Normal file
28
test_libs/pyspec/eth2spec/debug/decode.py
Normal file
@ -0,0 +1,28 @@
|
||||
from eth2spec.utils.minimal_ssz import hash_tree_root
|
||||
|
||||
|
||||
def decode(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 [decode(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] = decode(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")
|
26
test_libs/pyspec/eth2spec/debug/encode.py
Normal file
26
test_libs/pyspec/eth2spec/debug/encode.py
Normal file
@ -0,0 +1,26 @@
|
||||
from eth2spec.utils.minimal_ssz import hash_tree_root
|
||||
|
||||
|
||||
def encode(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 [encode(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] = encode(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")
|
||||
|
@ -1,52 +0,0 @@
|
||||
from eth2spec.utils.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")
|
@ -99,13 +99,17 @@ def process_epoch_transition(state: BeaconState) -> None:
|
||||
spec.finish_epoch_update(state)
|
||||
|
||||
|
||||
def state_transition(state: BeaconState,
|
||||
block: BeaconBlock,
|
||||
verify_state_root: bool=False) -> BeaconState:
|
||||
while state.slot < block.slot:
|
||||
def state_transition_to(state: BeaconState, up_to: int) -> BeaconState:
|
||||
while state.slot < up_to:
|
||||
spec.cache_state(state)
|
||||
if (state.slot + 1) % spec.SLOTS_PER_EPOCH == 0:
|
||||
process_epoch_transition(state)
|
||||
spec.advance_slot(state)
|
||||
if block.slot == state.slot:
|
||||
|
||||
|
||||
def state_transition(state: BeaconState,
|
||||
block: BeaconBlock,
|
||||
verify_state_root: bool=False) -> BeaconState:
|
||||
state_transition_to(state, block.slot)
|
||||
process_block(state, block, verify_state_root)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user