Define Custom Types via function_puller
This commit is contained in:
parent
8577cff72e
commit
00a68e28b5
|
@ -128,11 +128,11 @@ def apply_constants_preset(preset: Dict[str, Any]) -> None:
|
||||||
|
|
||||||
|
|
||||||
def objects_to_spec(functions: Dict[str, str],
|
def objects_to_spec(functions: Dict[str, str],
|
||||||
|
custom_types: Dict[str, str],
|
||||||
constants: Dict[str, str],
|
constants: Dict[str, str],
|
||||||
ssz_objects: Dict[str, str],
|
ssz_objects: Dict[str, str],
|
||||||
inserts: Dict[str, str],
|
inserts: Dict[str, str],
|
||||||
imports: Dict[str, str],
|
imports: Dict[str, str],
|
||||||
new_types: Dict[str, str],
|
|
||||||
byte_types: List[int],
|
byte_types: List[int],
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
|
@ -144,7 +144,7 @@ def objects_to_spec(functions: Dict[str, str],
|
||||||
f"class {key}({value}):\n"
|
f"class {key}({value}):\n"
|
||||||
f" def __init__(self, _x: uint64) -> None:\n"
|
f" def __init__(self, _x: uint64) -> None:\n"
|
||||||
f" ...\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.
|
Takes in two spec variants (as tuples of their objects) and combines them using the appropriate combiner function.
|
||||||
"""
|
"""
|
||||||
functions0, constants0, ssz_objects0, inserts0 = spec0
|
functions0, custom_types0, constants0, ssz_objects0, inserts0 = spec0
|
||||||
functions1, constants1, ssz_objects1, inserts1 = spec1
|
functions1, custom_types1, constants1, ssz_objects1, inserts1 = spec1
|
||||||
functions = combine_functions(functions0, functions1)
|
functions = combine_functions(functions0, functions1)
|
||||||
|
custom_types = combine_constants(custom_types0, custom_types1)
|
||||||
constants = combine_constants(constants0, constants1)
|
constants = combine_constants(constants0, constants1)
|
||||||
ssz_objects = combine_ssz_objects(ssz_objects0, ssz_objects1)
|
ssz_objects = combine_ssz_objects(ssz_objects0, ssz_objects1)
|
||||||
inserts = combine_inserts(inserts0, inserts1)
|
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]:
|
def build_phase0_spec(sourcefile: str, outfile: str=None) -> Optional[str]:
|
||||||
functions, constants, ssz_objects, inserts = get_spec(sourcefile)
|
functions, custom_types, constants, ssz_objects, inserts = get_spec(sourcefile)
|
||||||
spec = objects_to_spec(functions, constants, ssz_objects, inserts, PHASE0_IMPORTS, NEW_TYPES, BYTE_TYPES)
|
spec = objects_to_spec(functions, custom_types, constants, ssz_objects, inserts, PHASE0_IMPORTS, BYTE_TYPES)
|
||||||
if outfile is not None:
|
if outfile is not None:
|
||||||
with open(outfile, 'w') as out:
|
with open(outfile, 'w') as out:
|
||||||
out.write(spec)
|
out.write(spec)
|
||||||
|
@ -253,7 +254,7 @@ def build_phase1_spec(phase0_sourcefile: str,
|
||||||
spec_objects = phase0_spec
|
spec_objects = phase0_spec
|
||||||
for value in [phase1_custody, phase1_shard_data]:
|
for value in [phase1_custody, phase1_shard_data]:
|
||||||
spec_objects = combine_spec_objects(spec_objects, value)
|
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:
|
if outfile is not None:
|
||||||
with open(outfile, 'w') as out:
|
with open(outfile, 'w') as out:
|
||||||
out.write(spec)
|
out.write(spec)
|
||||||
|
|
|
@ -29,6 +29,7 @@ def get_spec(file_name: str) -> SpecObject:
|
||||||
inserts = {}
|
inserts = {}
|
||||||
function_matcher = re.compile(FUNCTION_REGEX)
|
function_matcher = re.compile(FUNCTION_REGEX)
|
||||||
inserts_matcher = re.compile(BEGIN_INSERT_REGEX)
|
inserts_matcher = re.compile(BEGIN_INSERT_REGEX)
|
||||||
|
custom_types = {}
|
||||||
for linenum, line in enumerate(open(file_name).readlines()):
|
for linenum, line in enumerate(open(file_name).readlines()):
|
||||||
line = line.rstrip()
|
line = line.rstrip()
|
||||||
if pulling_from is None and len(line) > 0 and line[0] == '#' and line[-1] == '`':
|
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'
|
ssz_objects[current_name] = ssz_objects.get(current_name, '') + line + '\n'
|
||||||
else:
|
else:
|
||||||
functions[current_name] = functions.get(current_name, '') + line + '\n'
|
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] == '|':
|
elif pulling_from is None and len(line) > 0 and line[0] == '|':
|
||||||
row = line[1:].split('|')
|
row = line[1:].split('|')
|
||||||
if len(row) >= 2:
|
if len(row) >= 2:
|
||||||
|
@ -72,12 +73,15 @@ def get_spec(file_name: str) -> SpecObject:
|
||||||
row[i] = row[i].strip().strip('`')
|
row[i] = row[i].strip().strip('`')
|
||||||
if '`' in row[i]:
|
if '`' in row[i]:
|
||||||
row[i] = row[i][:row[i].find('`')]
|
row[i] = row[i][:row[i].find('`')]
|
||||||
eligible = True
|
if row[1].startswith('uint') or row[1].startswith('bytes'):
|
||||||
if row[0][0] not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_':
|
custom_types[row[0]] = row[1]
|
||||||
eligible = False
|
else:
|
||||||
for c in row[0]:
|
eligible = True
|
||||||
if c not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789':
|
if row[0][0] not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_':
|
||||||
eligible = False
|
eligible = False
|
||||||
if eligible:
|
for c in row[0]:
|
||||||
constants[row[0]] = row[1].replace('**TBD**', '0x1234567890123456789012345678901234567890')
|
if c not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789':
|
||||||
return functions, constants, ssz_objects, inserts
|
eligible = False
|
||||||
|
if eligible:
|
||||||
|
constants[row[0]] = row[1].replace('**TBD**', '0x1234567890123456789012345678901234567890')
|
||||||
|
return functions, custom_types, constants, ssz_objects, inserts
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
- [Introduction](#introduction)
|
- [Introduction](#introduction)
|
||||||
- [Notation](#notation)
|
- [Notation](#notation)
|
||||||
- [Terminology](#terminology)
|
- [Terminology](#terminology)
|
||||||
|
- [Custom types](#custom-types)
|
||||||
- [Constants](#constants)
|
- [Constants](#constants)
|
||||||
- [Misc](#misc)
|
- [Misc](#misc)
|
||||||
- [Deposit contract](#deposit-contract)
|
- [Deposit contract](#deposit-contract)
|
||||||
|
@ -45,7 +46,6 @@
|
||||||
- [`BeaconBlock`](#beaconblock)
|
- [`BeaconBlock`](#beaconblock)
|
||||||
- [Beacon state](#beacon-state)
|
- [Beacon state](#beacon-state)
|
||||||
- [`BeaconState`](#beaconstate)
|
- [`BeaconState`](#beaconstate)
|
||||||
- [Custom types](#custom-types)
|
|
||||||
- [Helper functions](#helper-functions)
|
- [Helper functions](#helper-functions)
|
||||||
- [`xor`](#xor)
|
- [`xor`](#xor)
|
||||||
- [`hash`](#hash)
|
- [`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.
|
* **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.
|
* **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
|
## Constants
|
||||||
|
|
||||||
*Note*: The default mainnet values for the constants are included here for spec-design purposes.
|
*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
|
### Gwei values
|
||||||
|
|
||||||
| Name | Value | Unit |
|
| Name | Value |
|
||||||
| - | - | :-: |
|
| - | - | :-: |
|
||||||
| `MIN_DEPOSIT_AMOUNT` | `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) | Gwei |
|
| `MAX_EFFECTIVE_BALANCE` | `Gwei(2**5 * 10**9)` (= 32,000,000,000) |
|
||||||
| `EJECTION_BALANCE` | `Gwei(2**4 * 10**9)` (= 16,000,000,000) | Gwei |
|
| `EJECTION_BALANCE` | `Gwei(2**4 * 10**9)` (= 16,000,000,000) |
|
||||||
| `EFFECTIVE_BALANCE_INCREMENT` | `Gwei(2**0 * 10**9)` (= 1,000,000,000) | Gwei |
|
| `EFFECTIVE_BALANCE_INCREMENT` | `Gwei(2**0 * 10**9)` (= 1,000,000,000) |
|
||||||
|
|
||||||
### Initial values
|
### Initial values
|
||||||
|
|
||||||
|
@ -563,20 +577,6 @@ class BeaconState(Container):
|
||||||
deposit_index: uint64
|
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
|
## Helper functions
|
||||||
|
|
||||||
*Note*: The definitions below are for specification purposes and are not necessarily optimal implementations.
|
*Note*: The definitions below are for specification purposes and are not necessarily optimal implementations.
|
||||||
|
|
|
@ -51,7 +51,7 @@ class uint64(uint):
|
||||||
|
|
||||||
def __new__(cls, value, *args, **kwargs):
|
def __new__(cls, value, *args, **kwargs):
|
||||||
if value.bit_length() > 64:
|
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)
|
return super().__new__(cls, value)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue