From 00a68e28b50cb0c1067319d31c75d368b352b822 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sat, 15 Jun 2019 16:57:50 -0400 Subject: [PATCH] Define Custom Types via function_puller --- scripts/build_spec.py | 17 ++++---- scripts/function_puller.py | 22 +++++----- specs/core/0_beacon-chain.md | 40 +++++++++---------- .../pyspec/eth2spec/utils/ssz/ssz_typing.py | 2 +- 4 files changed, 43 insertions(+), 38 deletions(-) diff --git a/scripts/build_spec.py b/scripts/build_spec.py index 3fb1dda7e..6bcb04656 100644 --- a/scripts/build_spec.py +++ b/scripts/build_spec.py @@ -128,11 +128,11 @@ def apply_constants_preset(preset: Dict[str, Any]) -> None: def objects_to_spec(functions: Dict[str, str], + custom_types: Dict[str, str], constants: Dict[str, str], ssz_objects: Dict[str, str], inserts: Dict[str, str], imports: Dict[str, str], - new_types: Dict[str, str], byte_types: List[int], ) -> str: """ @@ -144,7 +144,7 @@ def objects_to_spec(functions: Dict[str, str], f"class {key}({value}):\n" f" def __init__(self, _x: uint64) -> None:\n" f" ...\n" - for key, value in new_types.items() + for key, value in custom_types.items() ] ) ) @@ -225,18 +225,19 @@ def combine_spec_objects(spec0: SpecObject, spec1: SpecObject) -> SpecObject: """ Takes in two spec variants (as tuples of their objects) and combines them using the appropriate combiner function. """ - functions0, constants0, ssz_objects0, inserts0 = spec0 - functions1, constants1, ssz_objects1, inserts1 = spec1 + functions0, custom_types0, constants0, ssz_objects0, inserts0 = spec0 + functions1, custom_types1, constants1, ssz_objects1, inserts1 = spec1 functions = combine_functions(functions0, functions1) + custom_types = combine_constants(custom_types0, custom_types1) constants = combine_constants(constants0, constants1) ssz_objects = combine_ssz_objects(ssz_objects0, ssz_objects1) inserts = combine_inserts(inserts0, inserts1) - return functions, constants, ssz_objects, inserts + return functions, custom_types, constants, ssz_objects, inserts def build_phase0_spec(sourcefile: str, outfile: str=None) -> Optional[str]: - functions, constants, ssz_objects, inserts = get_spec(sourcefile) - spec = objects_to_spec(functions, constants, ssz_objects, inserts, PHASE0_IMPORTS, NEW_TYPES, BYTE_TYPES) + functions, custom_types, constants, ssz_objects, inserts = get_spec(sourcefile) + spec = objects_to_spec(functions, custom_types, constants, ssz_objects, inserts, PHASE0_IMPORTS, BYTE_TYPES) if outfile is not None: with open(outfile, 'w') as out: out.write(spec) @@ -253,7 +254,7 @@ def build_phase1_spec(phase0_sourcefile: str, spec_objects = phase0_spec for value in [phase1_custody, phase1_shard_data]: spec_objects = combine_spec_objects(spec_objects, value) - spec = objects_to_spec(*spec_objects, PHASE1_IMPORTS, NEW_TYPES, BYTE_TYPES) + spec = objects_to_spec(*spec_objects, PHASE1_IMPORTS, BYTE_TYPES) if outfile is not None: with open(outfile, 'w') as out: out.write(spec) diff --git a/scripts/function_puller.py b/scripts/function_puller.py index 303d4ec2f..4ad9eef57 100644 --- a/scripts/function_puller.py +++ b/scripts/function_puller.py @@ -29,6 +29,7 @@ def get_spec(file_name: str) -> SpecObject: inserts = {} function_matcher = re.compile(FUNCTION_REGEX) inserts_matcher = re.compile(BEGIN_INSERT_REGEX) + custom_types = {} for linenum, line in enumerate(open(file_name).readlines()): line = line.rstrip() if pulling_from is None and len(line) > 0 and line[0] == '#' and line[-1] == '`': @@ -64,7 +65,7 @@ def get_spec(file_name: str) -> SpecObject: ssz_objects[current_name] = ssz_objects.get(current_name, '') + line + '\n' else: functions[current_name] = functions.get(current_name, '') + line + '\n' - # Handle constant table entries + # Handle constant and custom types table entries elif pulling_from is None and len(line) > 0 and line[0] == '|': row = line[1:].split('|') if len(row) >= 2: @@ -72,12 +73,15 @@ def get_spec(file_name: str) -> SpecObject: row[i] = row[i].strip().strip('`') if '`' in row[i]: row[i] = row[i][:row[i].find('`')] - eligible = True - if row[0][0] not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_': - eligible = False - for c in row[0]: - if c not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789': + if row[1].startswith('uint') or row[1].startswith('bytes'): + custom_types[row[0]] = row[1] + else: + eligible = True + if row[0][0] not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_': eligible = False - if eligible: - constants[row[0]] = row[1].replace('**TBD**', '0x1234567890123456789012345678901234567890') - return functions, constants, ssz_objects, inserts + for c in row[0]: + if c not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789': + eligible = False + if eligible: + constants[row[0]] = row[1].replace('**TBD**', '0x1234567890123456789012345678901234567890') + return functions, custom_types, constants, ssz_objects, inserts diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 86c22c976..8baba6928 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -10,6 +10,7 @@ - [Introduction](#introduction) - [Notation](#notation) - [Terminology](#terminology) + - [Custom types](#custom-types) - [Constants](#constants) - [Misc](#misc) - [Deposit contract](#deposit-contract) @@ -45,7 +46,6 @@ - [`BeaconBlock`](#beaconblock) - [Beacon state](#beacon-state) - [`BeaconState`](#beaconstate) - - [Custom types](#custom-types) - [Helper functions](#helper-functions) - [`xor`](#xor) - [`hash`](#hash) @@ -150,6 +150,20 @@ Code snippets appearing in `this style` are to be interpreted as Python code. * **Withdrawal period**—the number of slots between a [validator](#dfn-validator) exit and the [validator](#dfn-validator) balance being withdrawable. * **Genesis time**—the Unix time of the genesis beacon chain block at slot 0. +## Custom types + +We define the following Python custom types for type hinting and readability: + +| Name | SSZ equivalent | Description | +| - | - | - | +| `Slot` | `uint64` | a slot number | +| `Epoch` | `uint64` | an epoch number | +| `Shard` | `uint64` | a shard number | +| `ValidatorIndex` | `uint64` | a validator registry index | +| `Gwei` | `uint64` | an amount in Gwei | +| `BLSPubkey` | `Bytes48` | a BLS12-381 public key | +| `BLSSignature` | `Bytes96` | a BLS12-381 signature | + ## Constants *Note*: The default mainnet values for the constants are included here for spec-design purposes. @@ -178,12 +192,12 @@ These configurations are updated for releases, but may be out of sync during `de ### Gwei values -| Name | Value | Unit | +| Name | Value | | - | - | :-: | -| `MIN_DEPOSIT_AMOUNT` | `Gwei(2**0 * 10**9)` (= 1,000,000,000) | Gwei | -| `MAX_EFFECTIVE_BALANCE` | `Gwei(2**5 * 10**9)` (= 32,000,000,000) | Gwei | -| `EJECTION_BALANCE` | `Gwei(2**4 * 10**9)` (= 16,000,000,000) | Gwei | -| `EFFECTIVE_BALANCE_INCREMENT` | `Gwei(2**0 * 10**9)` (= 1,000,000,000) | Gwei | +| `MIN_DEPOSIT_AMOUNT` | `Gwei(2**0 * 10**9)` (= 1,000,000,000) | +| `MAX_EFFECTIVE_BALANCE` | `Gwei(2**5 * 10**9)` (= 32,000,000,000) | +| `EJECTION_BALANCE` | `Gwei(2**4 * 10**9)` (= 16,000,000,000) | +| `EFFECTIVE_BALANCE_INCREMENT` | `Gwei(2**0 * 10**9)` (= 1,000,000,000) | ### Initial values @@ -563,20 +577,6 @@ class BeaconState(Container): deposit_index: uint64 ``` -## Custom types - -We define the following Python custom types for type hinting and readability: - -| Name | SSZ equivalent | Description | -| - | - | - | -| `Slot` | `uint64` | a slot number | -| `Epoch` | `uint64` | an epoch number | -| `Shard` | `uint64` | a shard number | -| `ValidatorIndex` | `uint64` | a validator registry index | -| `Gwei` | `uint64` | an amount in Gwei | -| `BLSPubkey` | `Bytes48` | a BLS12-381 public key | -| `BLSSignature` | `Bytes96` | a BLS12-381 signature | - ## Helper functions *Note*: The definitions below are for specification purposes and are not necessarily optimal implementations. diff --git a/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py b/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py index b75a40403..cbd313d85 100644 --- a/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py +++ b/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py @@ -51,7 +51,7 @@ class uint64(uint): def __new__(cls, value, *args, **kwargs): if value.bit_length() > 64: - raise ValueError("value out of bounds for uint128") + raise ValueError("value out of bounds for uint64") return super().__new__(cls, value)