From 056d6b27e643796007d32798f960fc7d054c3349 Mon Sep 17 00:00:00 2001 From: Thomas Maxwell Date: Wed, 4 Nov 2020 02:35:36 +0100 Subject: [PATCH 01/10] fix typo --- eth2deposit/cli/existing_mnemonic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth2deposit/cli/existing_mnemonic.py b/eth2deposit/cli/existing_mnemonic.py index 5fc1316f..2c0970c2 100644 --- a/eth2deposit/cli/existing_mnemonic.py +++ b/eth2deposit/cli/existing_mnemonic.py @@ -30,7 +30,7 @@ def validate_mnemonic(cts: click.Context, param: Any, mnemonic: str) -> str: @click.option( '--mnemonic', callback=validate_mnemonic, - help=('The mnemonic that you used to generate your keys. (It is reccomened not to use this argument, and wait for ' + help=('The mnemonic that you used to generate your keys. (It is recommended not to use this argument, and wait for ' 'the CLI to ask you for your mnemonic as otherwise it will appear in your shell history.)'), prompt='Please enter your mnemonic separated by spaces (" ")', required=True, From 0c1530996606fd2be635279e55519826b14a4c75 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 4 Nov 2020 10:47:30 +0800 Subject: [PATCH 02/10] Fix broken markdown --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 35e109da..7aea4c5e 100644 --- a/README.md +++ b/README.md @@ -433,7 +433,7 @@ pip3 install -r requirements.txt Run one of the following command to enter the interactive CLI: -``cmd +```cmd python .\eth2deposit\deposit.py new-mnemonic ``` From 0bfb657894c550cdfaf8eed0233c18275e67934b Mon Sep 17 00:00:00 2001 From: vbuterin Date: Thu, 5 Nov 2020 14:34:01 +0800 Subject: [PATCH 03/10] Proposed tweak to from_json and from_file This feels to me like it would be more intuitive behavior; the `from_json` behaves the same way for Keystore and KeystoreCrypto, and it exposes a way for people to use the library with json that is not saved in a file anywhere. --- eth2deposit/key_handling/keystore.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/eth2deposit/key_handling/keystore.py b/eth2deposit/key_handling/keystore.py index a11052fc..a977900c 100644 --- a/eth2deposit/key_handling/keystore.py +++ b/eth2deposit/key_handling/keystore.py @@ -98,9 +98,8 @@ def save(self, file: str) -> None: f.write(self.as_json()) @classmethod - def from_json(cls, path: str) -> 'Keystore': - with open(path, 'r') as f: - json_dict = json.load(f) + def from_json(cls, json_dict: Dict[Any, Any]) -> 'Keystore': + crypto = KeystoreCrypto.from_json(json_dict['crypto']) path = json_dict['path'] uuid = json_dict['uuid'] @@ -108,6 +107,11 @@ def from_json(cls, path: str) -> 'Keystore': description = json_dict.get('description', '') pubkey = json_dict.get('pubkey', '') return cls(crypto=crypto, description=description, pubkey=pubkey, path=path, uuid=uuid, version=version) + + @classmethod + def from_file(cls, path: str) -> 'KeyStore': + with open(path, 'r') as f: + return cls.from_json(json.load(f)) @staticmethod def _process_password(password: str) -> bytes: From 59a12e927e14b720f141e838b3305463f74d9ff9 Mon Sep 17 00:00:00 2001 From: vbuterin Date: Thu, 5 Nov 2020 14:35:25 +0800 Subject: [PATCH 04/10] Fixed saving the path --- eth2deposit/key_handling/keystore.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/eth2deposit/key_handling/keystore.py b/eth2deposit/key_handling/keystore.py index a977900c..6699462a 100644 --- a/eth2deposit/key_handling/keystore.py +++ b/eth2deposit/key_handling/keystore.py @@ -98,8 +98,7 @@ def save(self, file: str) -> None: f.write(self.as_json()) @classmethod - def from_json(cls, json_dict: Dict[Any, Any]) -> 'Keystore': - + def from_json(cls, json_dict: Dict[Any, Any], path='': str) -> 'Keystore': crypto = KeystoreCrypto.from_json(json_dict['crypto']) path = json_dict['path'] uuid = json_dict['uuid'] @@ -111,7 +110,7 @@ def from_json(cls, json_dict: Dict[Any, Any]) -> 'Keystore': @classmethod def from_file(cls, path: str) -> 'KeyStore': with open(path, 'r') as f: - return cls.from_json(json.load(f)) + return cls.from_json(json.load(f), path) @staticmethod def _process_password(password: str) -> bytes: From b6f7ca93c3e8439ed5a40f3cb79725b577b1c354 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 5 Nov 2020 17:13:32 +0800 Subject: [PATCH 05/10] Fix --- eth2deposit/credentials.py | 2 +- eth2deposit/key_handling/keystore.py | 8 ++++---- tests/test_cli/helpers.py | 2 +- tests/test_key_handling/test_keystore.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/eth2deposit/credentials.py b/eth2deposit/credentials.py index d9a4a0b1..f8a98a73 100644 --- a/eth2deposit/credentials.py +++ b/eth2deposit/credentials.py @@ -107,7 +107,7 @@ def save_signing_keystore(self, password: str, folder: str) -> str: return filefolder def verify_keystore(self, keystore_filefolder: str, password: str) -> bool: - saved_keystore = Keystore.from_json(keystore_filefolder) + saved_keystore = Keystore.from_file(keystore_filefolder) secret_bytes = saved_keystore.decrypt(password) return self.signing_sk == int.from_bytes(secret_bytes, 'big') diff --git a/eth2deposit/key_handling/keystore.py b/eth2deposit/key_handling/keystore.py index 6699462a..8075bbaf 100644 --- a/eth2deposit/key_handling/keystore.py +++ b/eth2deposit/key_handling/keystore.py @@ -98,7 +98,7 @@ def save(self, file: str) -> None: f.write(self.as_json()) @classmethod - def from_json(cls, json_dict: Dict[Any, Any], path='': str) -> 'Keystore': + def from_json(cls, json_dict: Dict[Any, Any]) -> 'Keystore': crypto = KeystoreCrypto.from_json(json_dict['crypto']) path = json_dict['path'] uuid = json_dict['uuid'] @@ -106,11 +106,11 @@ def from_json(cls, json_dict: Dict[Any, Any], path='': str) -> 'Keystore': description = json_dict.get('description', '') pubkey = json_dict.get('pubkey', '') return cls(crypto=crypto, description=description, pubkey=pubkey, path=path, uuid=uuid, version=version) - + @classmethod - def from_file(cls, path: str) -> 'KeyStore': + def from_file(cls, path: str) -> 'Keystore': with open(path, 'r') as f: - return cls.from_json(json.load(f), path) + return cls.from_json(json.load(f)) @staticmethod def _process_password(password: str) -> bytes: diff --git a/tests/test_cli/helpers.py b/tests/test_cli/helpers.py index c199c752..01f9204a 100644 --- a/tests/test_cli/helpers.py +++ b/tests/test_cli/helpers.py @@ -17,5 +17,5 @@ def clean_key_folder(my_folder_path: str) -> None: def get_uuid(key_file: str) -> str: - keystore = Keystore.from_json(key_file) + keystore = Keystore.from_file(key_file) return keystore.uuid diff --git a/tests/test_key_handling/test_keystore.py b/tests/test_key_handling/test_keystore.py index e15463dd..add35b88 100644 --- a/tests/test_key_handling/test_keystore.py +++ b/tests/test_key_handling/test_keystore.py @@ -13,7 +13,7 @@ test_vector_folder = os.path.join(os.getcwd(), 'tests', 'test_key_handling', 'keystore_test_vectors') _, _, test_vector_files = next(os.walk(test_vector_folder)) # type: ignore -test_vector_keystores = [Keystore.from_json(os.path.join(test_vector_folder, f)) for f in test_vector_files] +test_vector_keystores = [Keystore.from_file(os.path.join(test_vector_folder, f)) for f in test_vector_files] def test_json_serialization() -> None: From 289b674a0531b7c768b8cee0527fc85150e06e9b Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 13 Nov 2020 00:01:48 +0800 Subject: [PATCH 06/10] Add PyrmontSetting --- eth2deposit/settings.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/eth2deposit/settings.py b/eth2deposit/settings.py index 4c7a5ccf..e1c60e2b 100644 --- a/eth2deposit/settings.py +++ b/eth2deposit/settings.py @@ -20,6 +20,8 @@ class BaseChainSetting(NamedTuple): SpadinaSetting = BaseChainSetting(GENESIS_FORK_VERSION=bytes.fromhex('00000002')) # Eth2 "dress rehearsal" testnet (spec v0.12.3) ZinkenSetting = BaseChainSetting(GENESIS_FORK_VERSION=bytes.fromhex('00000003')) +# Eth2 testnet (spec v1.0.0) +PyrmontSetting = BaseChainSetting(GENESIS_FORK_VERSION=bytes.fromhex('00000000')) MAINNET = 'mainnet' @@ -28,6 +30,7 @@ class BaseChainSetting(NamedTuple): MEDALLA = 'medalla' SPADINA = 'spadina' ZINKEN = 'zinken' +Pyrmont = 'pyrmont' ALL_CHAINS: Dict[str, BaseChainSetting] = { MAINNET: MainnetSetting, WITTI: WittiSetting, @@ -35,6 +38,7 @@ class BaseChainSetting(NamedTuple): MEDALLA: MedallaSetting, SPADINA: SpadinaSetting, ZINKEN: ZinkenSetting, + Pyrmont: PyrmontSetting, } From 935588287e6d3a1218a2ea1cdf5b826514daf59e Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 13 Nov 2020 00:15:52 +0800 Subject: [PATCH 07/10] Add `eth2_network_name` field to deposit_data.json --- eth2deposit/cli/generate_keys.py | 6 +++--- eth2deposit/credentials.py | 16 ++++++++------- eth2deposit/settings.py | 35 +++++++++++++++++--------------- tests/test_credentials.py | 3 ++- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/eth2deposit/cli/generate_keys.py b/eth2deposit/cli/generate_keys.py index 19c559e1..8b85b3e1 100644 --- a/eth2deposit/cli/generate_keys.py +++ b/eth2deposit/cli/generate_keys.py @@ -21,7 +21,7 @@ from eth2deposit.settings import ( ALL_CHAINS, MAINNET, - get_setting, + get_chain_setting, ) @@ -105,7 +105,7 @@ def generate_keys(ctx: click.Context, validator_start_index: int, mnemonic_password = ctx.obj['mnemonic_password'] amounts = [MAX_DEPOSIT_AMOUNT] * num_validators folder = os.path.join(folder, DEFAULT_VALIDATOR_KEYS_FOLDER_NAME) - setting = get_setting(chain) + chain_setting = get_chain_setting(chain) if not os.path.exists(folder): os.mkdir(folder) click.clear() @@ -116,7 +116,7 @@ def generate_keys(ctx: click.Context, validator_start_index: int, mnemonic_password=mnemonic_password, num_keys=num_validators, amounts=amounts, - fork_version=setting.GENESIS_FORK_VERSION, + chain_setting=chain_setting, start_index=validator_start_index, ) keystore_filefolders = credentials.export_keystores(password=keystore_password, folder=folder) diff --git a/eth2deposit/credentials.py b/eth2deposit/credentials.py index d9a4a0b1..7bbf5c84 100644 --- a/eth2deposit/credentials.py +++ b/eth2deposit/credentials.py @@ -11,7 +11,7 @@ Keystore, ScryptKeystore, ) -from eth2deposit.settings import DEPOSIT_CLI_VERSION +from eth2deposit.settings import DEPOSIT_CLI_VERSION, BaseChainSetting from eth2deposit.utils.constants import ( BLS_WITHDRAWAL_PREFIX, ETH2GWEI, @@ -32,7 +32,8 @@ class Credential: A Credential object contains all of the information for a single validator and the corresponding functionality. Once created, it is the only object that should be required to perform any processing for a validator. """ - def __init__(self, *, mnemonic: str, mnemonic_password: str, index: int, amount: int, fork_version: bytes): + def __init__(self, *, mnemonic: str, mnemonic_password: str, + index: int, amount: int, chain_setting: BaseChainSetting): # Set path as EIP-2334 format # https://eips.ethereum.org/EIPS/eip-2334 purpose = '12381' @@ -46,7 +47,7 @@ def __init__(self, *, mnemonic: str, mnemonic_password: str, index: int, amount: self.signing_sk = mnemonic_and_path_to_key( mnemonic=mnemonic, path=self.signing_key_path, password=mnemonic_password) self.amount = amount - self.fork_version = fork_version + self.chain_setting = chain_setting @property def signing_pk(self) -> bytes: @@ -74,7 +75,7 @@ def deposit_message(self) -> DepositMessage: @property def signed_deposit(self) -> DepositData: - domain = compute_deposit_domain(fork_version=self.fork_version) + domain = compute_deposit_domain(fork_version=self.chain_setting.GENESIS_FORK_VERSION) signing_root = compute_signing_root(self.deposit_message, domain) signed_deposit = DepositData( **self.deposit_message.as_dict(), @@ -92,7 +93,8 @@ def deposit_datum_dict(self) -> Dict[str, bytes]: datum_dict = signed_deposit_datum.as_dict() datum_dict.update({'deposit_message_root': self.deposit_message.hash_tree_root}) datum_dict.update({'deposit_data_root': signed_deposit_datum.hash_tree_root}) - datum_dict.update({'fork_version': self.fork_version}) + datum_dict.update({'fork_version': self.chain_setting.GENESIS_FORK_VERSION}) + datum_dict.update({'eth2_network_name': self.chain_setting.ETH2_NETWORK_NAME}) datum_dict.update({'deposit_cli_version': DEPOSIT_CLI_VERSION}) return datum_dict @@ -126,7 +128,7 @@ def from_mnemonic(cls, mnemonic_password: str, num_keys: int, amounts: List[int], - fork_version: bytes, + chain_setting: BaseChainSetting, start_index: int) -> 'CredentialList': if len(amounts) != num_keys: raise ValueError( @@ -136,7 +138,7 @@ def from_mnemonic(cls, with click.progressbar(key_indices, label='Creating your keys:\t\t', show_percent=False, show_pos=True) as indices: return cls([Credential(mnemonic=mnemonic, mnemonic_password=mnemonic_password, - index=index, amount=amounts[index - start_index], fork_version=fork_version) + index=index, amount=amounts[index - start_index], chain_setting=chain_setting) for index in indices]) def export_keystores(self, password: str, folder: str) -> List[str]: diff --git a/eth2deposit/settings.py b/eth2deposit/settings.py index e1c60e2b..efe708e2 100644 --- a/eth2deposit/settings.py +++ b/eth2deposit/settings.py @@ -5,32 +5,35 @@ class BaseChainSetting(NamedTuple): + ETH2_NETWORK_NAME: str GENESIS_FORK_VERSION: bytes +MAINNET = 'mainnet' +WITTI = 'witti' +ALTONA = 'altona' +MEDALLA = 'medalla' +SPADINA = 'spadina' +ZINKEN = 'zinken' +PYRMONT = 'pyrmont' + + # Eth2 Mainnet setting -MainnetSetting = BaseChainSetting(GENESIS_FORK_VERSION=bytes.fromhex('00000000')) +MainnetSetting = BaseChainSetting(ETH2_NETWORK_NAME=MAINNET, GENESIS_FORK_VERSION=bytes.fromhex('00000000')) # Eth2 spec v0.11.3 testnet -WittiSetting = BaseChainSetting(GENESIS_FORK_VERSION=bytes.fromhex('00000113')) +WittiSetting = BaseChainSetting(ETH2_NETWORK_NAME=WITTI, GENESIS_FORK_VERSION=bytes.fromhex('00000113')) # Eth2 spec v0.12.1 testnet -AltonaSetting = BaseChainSetting(GENESIS_FORK_VERSION=bytes.fromhex('00000121')) +AltonaSetting = BaseChainSetting(ETH2_NETWORK_NAME=ALTONA, GENESIS_FORK_VERSION=bytes.fromhex('00000121')) # Eth2 "official" public testnet (spec v0.12.2) -MedallaSetting = BaseChainSetting(GENESIS_FORK_VERSION=bytes.fromhex('00000001')) +MedallaSetting = BaseChainSetting(ETH2_NETWORK_NAME=MEDALLA, GENESIS_FORK_VERSION=bytes.fromhex('00000001')) # Eth2 "dress rehearsal" testnet (spec v0.12.3) -SpadinaSetting = BaseChainSetting(GENESIS_FORK_VERSION=bytes.fromhex('00000002')) +SpadinaSetting = BaseChainSetting(ETH2_NETWORK_NAME=SPADINA, GENESIS_FORK_VERSION=bytes.fromhex('00000002')) # Eth2 "dress rehearsal" testnet (spec v0.12.3) -ZinkenSetting = BaseChainSetting(GENESIS_FORK_VERSION=bytes.fromhex('00000003')) +ZinkenSetting = BaseChainSetting(ETH2_NETWORK_NAME=ZINKEN, GENESIS_FORK_VERSION=bytes.fromhex('00000003')) # Eth2 testnet (spec v1.0.0) -PyrmontSetting = BaseChainSetting(GENESIS_FORK_VERSION=bytes.fromhex('00000000')) +PyrmontSetting = BaseChainSetting(ETH2_NETWORK_NAME=PYRMONT, GENESIS_FORK_VERSION=bytes.fromhex('00000000')) -MAINNET = 'mainnet' -WITTI = 'witti' -ALTONA = 'altona' -MEDALLA = 'medalla' -SPADINA = 'spadina' -ZINKEN = 'zinken' -Pyrmont = 'pyrmont' ALL_CHAINS: Dict[str, BaseChainSetting] = { MAINNET: MainnetSetting, WITTI: WittiSetting, @@ -38,9 +41,9 @@ class BaseChainSetting(NamedTuple): MEDALLA: MedallaSetting, SPADINA: SpadinaSetting, ZINKEN: ZinkenSetting, - Pyrmont: PyrmontSetting, + PYRMONT: PyrmontSetting, } -def get_setting(chain_name: str = MAINNET) -> BaseChainSetting: +def get_chain_setting(chain_name: str = MAINNET) -> BaseChainSetting: return ALL_CHAINS[chain_name] diff --git a/tests/test_credentials.py b/tests/test_credentials.py index c6b7042b..219735a4 100644 --- a/tests/test_credentials.py +++ b/tests/test_credentials.py @@ -1,6 +1,7 @@ import pytest from eth2deposit.credentials import CredentialList +from eth2deposit.settings import MedallaSetting def test_from_mnemonic() -> None: @@ -10,6 +11,6 @@ def test_from_mnemonic() -> None: mnemonic_password="", num_keys=1, amounts=[32, 32], - fork_version=bytes.fromhex('00000000'), + chain_setting=MedallaSetting, start_index=1, ) From bbbc81cf2ee66bff2ced0cd6cdcd8f2d058262cf Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 13 Nov 2020 21:17:42 +0800 Subject: [PATCH 08/10] Use the updated `PyrmontSetting.GENESIS_FORK_VERSION` --- eth2deposit/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eth2deposit/settings.py b/eth2deposit/settings.py index efe708e2..a1c484dc 100644 --- a/eth2deposit/settings.py +++ b/eth2deposit/settings.py @@ -30,8 +30,8 @@ class BaseChainSetting(NamedTuple): SpadinaSetting = BaseChainSetting(ETH2_NETWORK_NAME=SPADINA, GENESIS_FORK_VERSION=bytes.fromhex('00000002')) # Eth2 "dress rehearsal" testnet (spec v0.12.3) ZinkenSetting = BaseChainSetting(ETH2_NETWORK_NAME=ZINKEN, GENESIS_FORK_VERSION=bytes.fromhex('00000003')) -# Eth2 testnet (spec v1.0.0) -PyrmontSetting = BaseChainSetting(ETH2_NETWORK_NAME=PYRMONT, GENESIS_FORK_VERSION=bytes.fromhex('00000000')) +# Eth2 pre-launch testnet (spec v1.0.0) +PyrmontSetting = BaseChainSetting(ETH2_NETWORK_NAME=PYRMONT, GENESIS_FORK_VERSION=bytes.fromhex('00002009')) ALL_CHAINS: Dict[str, BaseChainSetting] = { From 57249554527d87ff46b91bacbf9919852f6e4bdd Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Tue, 17 Nov 2020 23:36:35 +0800 Subject: [PATCH 09/10] bump to py_ecc==5.1.0 --- requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 3fb95028..b47f495a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ -py-ecc==5.0.0 \ - --hash=sha256:67a6b944722408c75bb630617dfbd8062c45b72d154ed3a6891c833717c87638 \ - --hash=sha256:9d3c7ba607ef36d7f8af9944d702799014b27fc77b385d14024f96f9f610ad0a +py_ecc==5.1.0 \ + --hash=sha256:1ba0453d39887cdb63e0855ba317b67f8bd571371bb3cafefae3e2e5206e45c5 \ + --hash=sha256:934d6506f8b9487cc669562eb11beaf9b0a9ca408ffd94d0961c9cdde71336f2 pycryptodome==3.9.8 \ --hash=sha256:02e51e1d5828d58f154896ddfd003e2e7584869c275e5acbe290443575370fba \ --hash=sha256:03d5cca8618620f45fd40f827423f82b86b3a202c8d44108601b0f5f56b04299 \ From c681f93331410b3905a2d6dfe19eb8e71c9f1e50 Mon Sep 17 00:00:00 2001 From: Carl Beekhuizen Date: Tue, 17 Nov 2020 17:14:34 +0100 Subject: [PATCH 10/10] version bump -> v1.1.0 --- eth2deposit/settings.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eth2deposit/settings.py b/eth2deposit/settings.py index a1c484dc..35bde8aa 100644 --- a/eth2deposit/settings.py +++ b/eth2deposit/settings.py @@ -1,7 +1,7 @@ from typing import Dict, NamedTuple -DEPOSIT_CLI_VERSION = '1.0.0' +DEPOSIT_CLI_VERSION = '1.1.0' class BaseChainSetting(NamedTuple): diff --git a/setup.py b/setup.py index 5c9c89e0..efe66cc1 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup( name="eth2deposit", - version='1.0.0', + version='1.1.0', py_modules=["eth2deposit"], packages=find_packages(exclude=('tests', 'docs')), python_requires=">=3.7,<4",