def valid_deposit(): new_dep, state = build_deposit_for_index(10, 10) yield 'description', 'valid deposit to add new validator' yield 'pre', encode(state, spec.BeaconState) yield 'deposit', encode(new_dep, spec.Deposit) spec.process_deposit(state, new_dep) yield 'post', encode(state, spec.BeaconState)
def valid_topup(): new_dep, state = build_deposit_for_index(10, 3) yield 'description', 'valid deposit to top-up existing validator' yield 'pre', encode(state, spec.BeaconState) yield 'deposit', encode(new_dep, spec.Deposit) spec.process_deposit(state, new_dep) yield 'post', encode(state, spec.BeaconState)
def invalid_deposit_proof(): new_dep, state = build_deposit_for_index(10, 10) # Make deposit proof invalid (at bottom of proof) new_dep.proof[-1] = spec.ZERO_HASH yield 'description', 'invalid deposit proof' yield 'pre', encode(state, spec.BeaconState) yield 'deposit', encode(new_dep, spec.Deposit) try: spec.process_deposit(state, new_dep) except AssertionError: # expected yield 'post', None return raise Exception('invalid_deposit_index has unexpectedly allowed deposit')
def invalid_deposit_index(): new_dep, state = build_deposit_for_index(10, 10) # Mess up deposit index, 1 too small state.deposit_index = 9 yield 'description', 'invalid deposit index' yield 'pre', encode(state, spec.BeaconState) yield 'deposit', encode(new_dep, spec.Deposit) try: spec.process_deposit(state, new_dep) except AssertionError: # expected yield 'post', None return raise Exception('invalid_deposit_index has unexpectedly allowed deposit')
def case_fn(): value = value_fn() yield "value", "data", encode(value) yield "serialized", "ssz", serialize(value) yield "root", "meta", '0x' + hash_tree_root(value).hex() if isinstance(value, Container): yield "signing_root", "meta", '0x' + signing_root(value).hex()
def entry(*args, **kw): # check generator mode, may be None/else. # "pop" removes it, so it is not passed to the inner function. if kw.pop('generator_mode', False) is True: out = {} if description is None: # fall back on function name for test description name = fn.__name__ if name.startswith('test_'): name = name[5:] out['description'] = name else: # description can be explicit out['description'] = description has_contents = False # put all generated data into a dict. for data in fn(*args, **kw): has_contents = True # If there is a type argument, encode it as that type. if len(data) == 3: (key, value, typ) = data out[key] = encode(value, typ) else: # Otherwise, try to infer the type, but keep it as-is if it's not a SSZ type or bytes. (key, value) = data if isinstance(value, (SSZValue, bytes)): out[key] = encode(value) elif isinstance(value, list) and all([ isinstance(el, (SSZValue, bytes)) for el in value ]): out[key] = [encode(el) for el in value] 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 if has_contents: return out else: return None else: # just complete the function, ignore all yielded data, we are not using it for _ in fn(*args, **kw): continue return None
def create_test_case(rng: Random, typ, mode: random_value.RandomizationMode, chaos: bool) -> Iterable[gen_typing.TestCasePart]: value = random_value.get_random_ssz_object(rng, typ, MAX_BYTES_LENGTH, MAX_LIST_LENGTH, mode, chaos) yield "value", "data", encode.encode(value) yield "serialized", "ssz", serialize(value) roots_data = { "root": '0x' + hash_tree_root(value).hex() } yield "roots", "data", roots_data
def create_test_case(rng: Random, name: str, 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) yield "type_name", name yield "value", encode.encode(value, typ) yield "serialized", '0x' + serialize(value).hex() yield "root", '0x' + hash_tree_root(value).hex() if hasattr(value, "signature"): yield "signing_root", '0x' + signing_root(value).hex()
def create_test_case(rng: Random, typ, mode: random_value.RandomizationMode, chaos: bool) -> Iterable[gen_typing.TestCasePart]: value = random_value.get_random_ssz_object(rng, typ, MAX_BYTES_LENGTH, MAX_LIST_LENGTH, mode, chaos) yield "value", "data", encode.encode(value) yield "serialized", "ssz", serialize(value) roots_data = {"root": '0x' + hash_tree_root(value).hex()} if isinstance(value, Container) and hasattr(value, "signature"): roots_data["signing_root"] = '0x' + signing_root(value).hex() yield "roots", "data", roots_data
def entry(*args, **kw): # check generator mode, may be None/else. # "pop" removes it, so it is not passed to the inner function. if kw.pop('generator_mode', False) is True: out = {} if description is None: # fall back on function name for test description name = fn.__name__ if name.startswith('test_'): name = name[5:] out['description'] = name else: # description can be explicit out['description'] = description has_contents = False # put all generated data into a dict. for data in fn(*args, **kw): has_contents = True # If there is a type argument, encode it as that type. if len(data) == 3: (key, value, typ) = data out[key] = encode(value, typ) else: # Otherwise, try to infer the type, but keep it as-is if it's not a SSZ container. (key, value) = data if hasattr(value.__class__, 'fields'): out[key] = encode(value, value.__class__) else: out[key] = value if has_contents: return out else: return None else: # just complete the function, ignore all yielded data, we are not using it for _ in fn(*args, **kw): continue return None
def generator_mode(): if description is not None: # description can be explicit yield 'description', 'meta', description # transform the yielded data, and add type annotations for data in fn(*args, **kw): # if not 2 items, then it is assumed to be already formatted with a type: # e.g. ("bls_setting", "meta", 1) if len(data) != 2: yield data continue # Try to infer the type, but keep it as-is if it's not a SSZ type or bytes. (key, value) = data if value is None: continue if isinstance(value, SSZValue): yield key, 'data', encode(value) yield key, 'ssz', serialize(value) elif isinstance(value, bytes): yield key, 'data', encode(value) yield key, 'ssz', value elif isinstance(value, list) and all( [isinstance(el, (SSZValue, bytes)) for el in value]): for i, el in enumerate(value): if isinstance(el, SSZValue): yield f'{key}_{i}', 'data', encode(el) yield f'{key}_{i}', 'ssz', serialize(el) elif isinstance(el, bytes): yield f'{key}_{i}', 'data', encode(el) yield f'{key}_{i}', 'ssz', el yield f'{key}_count', 'meta', len(value) else: # Not a ssz value. # The data will now just be yielded as any python data, # something that should be encodeable by the generator runner. yield key, 'data', value
def create_test_case_contents(value, typ): yield "value", encode.encode(value, typ) yield "serialized", '0x' + serialize(value).hex() yield "root", '0x' + hash_tree_root(value).hex() if hasattr(value, "signature"): yield "signing_root", '0x' + signing_root(value).hex()
def case_fn(): value = value_fn() yield "value", "data", encode(value) yield "serialized", "ssz", serialize(value) yield "root", "meta", '0x' + hash_tree_root(value).hex()