Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add generate_bls_to_execution_change #313

Merged
merged 33 commits into from
Mar 13, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d3fd1da
Extract `load_mnemonic_arguments_decorator` func
hwwhww Jan 4, 2023
7404b69
[WIP] Add generate_bls_to_execution_change
hwwhww Jan 6, 2023
d68a1c7
Always use `GENESIS_FORK_VERSION` to sign BLSToExecutionChange and fi…
hwwhww Jan 15, 2023
6a4ba11
Add `0x` prefix to the bytes type fields of the output JSON file
hwwhww Jan 15, 2023
47bf1aa
WIP validation
hwwhww Jan 16, 2023
63fdc5e
Add `--devnet_chain_setting` for devnet testing
hwwhww Jan 16, 2023
c5651ea
Improve `validate_bls_to_execution_change`
hwwhww Jan 16, 2023
2b5c218
Add arguments description to README.md
hwwhww Jan 16, 2023
1f8bab5
Echo the folder path
hwwhww Jan 16, 2023
f5e2803
Arrange JSON fields by adding `metadata`
hwwhww Jan 16, 2023
245ee7b
Normalize input `bls_withdrawal_credentials` and add `test_existing_m…
hwwhww Jan 22, 2023
3b7e144
Generate multiple changes
hwwhww Jan 23, 2023
676279e
Add checksum address validation
hwwhww Jan 23, 2023
75e8ea0
Add test case of multiple validator indices
hwwhww Jan 23, 2023
0be70aa
Update README
hwwhww Jan 23, 2023
962ce8c
Add retype confirmation and fix typo
hwwhww Jan 26, 2023
1912868
Remove shutdown testnets and fill Sepolia and Goerli `genesis_validat…
hwwhww Jan 27, 2023
c9b4e01
Merge branch 'dev' into bls-to-execution-change
hwwhww Feb 1, 2023
33f847b
Update README.md
hwwhww Feb 10, 2023
7df39ba
Apply @james-prysm's suggestions
hwwhww Feb 10, 2023
27af99f
Update param description
hwwhww Feb 10, 2023
9b86724
Run test_btec_script.py in CI
hwwhww Feb 10, 2023
ca5062a
Kick the cache
hwwhww Feb 10, 2023
d83c312
Run test_binary_btec_script.py in CI
hwwhww Feb 10, 2023
2c3fb22
Strip brackets and extra spaces
hwwhww Feb 13, 2023
db3e628
fix error message grammar
JohnWestlund Feb 18, 2023
2cd1d99
Merge pull request #332 from JohnWestlund/bls-to-execution-change
hwwhww Mar 10, 2023
aae55a6
Apply PR feedback by catching the exceptions. Improve error handling …
hwwhww Mar 13, 2023
f79bbac
Improve error handling
hwwhww Mar 13, 2023
9aed027
Confirm deposit `eth1_withdrawal_address` input
hwwhww Mar 13, 2023
ee052fa
Add more description of mnemonic language per @infosecual's suggestion
hwwhww Mar 13, 2023
69f778d
Make `--non_interactive` flag visible and add notes in docs
hwwhww Mar 13, 2023
ed092fc
clean folders first
hwwhww Mar 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ jobs:
steps:
- checkout
- restore_cache:
key: venv-deps2-{{ arch }}-{{ .Branch }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements_test.txt" }}-{{ checksum "setup.py" }}-{{ checksum "Makefile" }}-v2
key: venv-deps2-{{ arch }}-{{ .Branch }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements_test.txt" }}-{{ checksum "setup.py" }}-{{ checksum "Makefile" }}-v3
- run:
name: Install requirements in venv
command: make venv_build_test
- save_cache:
key: venv-deps2-{{ arch }}-{{ .Branch }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements_test.txt" }}-{{ checksum "setup.py" }}-{{ checksum "Makefile" }}-v2
key: venv-deps2-{{ arch }}-{{ .Branch }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements_test.txt" }}-{{ checksum "setup.py" }}-{{ checksum "Makefile" }}-v3
paths:
- ./venv
venv_pytest:
Expand All @@ -45,7 +45,7 @@ jobs:
steps:
- checkout
- restore_cache:
key: venv-deps2-{{ arch }}-{{ .Branch }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements_test.txt" }}-{{ checksum "setup.py" }}-{{ checksum "Makefile" }}-v2
key: venv-deps2-{{ arch }}-{{ .Branch }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements_test.txt" }}-{{ checksum "setup.py" }}-{{ checksum "Makefile" }}-v3
- run:
name: Run tests with venv
command: make venv_test
Expand All @@ -61,7 +61,7 @@ jobs:
steps:
- checkout
- restore_cache:
key: venv-deps2-{{ arch }}-{{ .Branch }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements_test.txt" }}-{{ checksum "setup.py" }}-{{ checksum "Makefile" }}-v2
key: venv-deps2-{{ arch }}-{{ .Branch }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements_test.txt" }}-{{ checksum "setup.py" }}-{{ checksum "Makefile" }}-v3
- run:
name: Run linter with venv
command: make venv_lint
Expand Down Expand Up @@ -105,6 +105,9 @@ jobs:
- run:
name: Run deposit script on Windows"
command: python ./test_deposit_script.py
- run:
name: Run btec script on Windows"
command: python ./test_btec_script.py
build-linux-amd64:
machine:
image: ubuntu-2004:202201-02
Expand Down Expand Up @@ -135,9 +138,11 @@ jobs:
export TEST_FOLDER_NAME=TMP_TEST_FOLDER
mkdir ${TEST_FOLDER_NAME}
cp -r ${BUILD_FILE_NAME} ${TEST_FOLDER_NAME}
cp test_binary_script.py ${TEST_FOLDER_NAME}
cp test_binary_deposit_script.py ${TEST_FOLDER_NAME}
cp test_binary_btec_script.py ${TEST_FOLDER_NAME}
cd ${TEST_FOLDER_NAME}
python test_binary_script.py ./${BUILD_FILE_NAME};
python test_binary_deposit_script.py ./${BUILD_FILE_NAME};
python test_binary_btec_script.py ./${BUILD_FILE_NAME};
- run:
name: Compress the file
command: |
Expand Down Expand Up @@ -181,9 +186,11 @@ jobs:
export TEST_FOLDER_NAME=TMP_TEST_FOLDER
mkdir ${TEST_FOLDER_NAME}
cp -r ${BUILD_FILE_NAME} ${TEST_FOLDER_NAME}
cp test_binary_script.py ${TEST_FOLDER_NAME}
cp test_binary_deposit_script.py ${TEST_FOLDER_NAME}
cp test_binary_btec_script.py ${TEST_FOLDER_NAME}
cd ${TEST_FOLDER_NAME}
python test_binary_script.py ./${BUILD_FILE_NAME};
python test_binary_deposit_script.py ./${BUILD_FILE_NAME};
python test_binary_btec_script.py ./${BUILD_FILE_NAME};
- run:
name: Compress the file
command: |
Expand Down Expand Up @@ -225,9 +232,11 @@ jobs:
$TEST_FOLDER_NAME = "TMP_TEST_FOLDER"
mkdir ${TEST_FOLDER_NAME}
Copy-item ${BUILD_FILE_NAME} -destination ${TEST_FOLDER_NAME} -recurse
copy test_binary_script.py ${TEST_FOLDER_NAME}
copy test_binary_deposit_script.py ${TEST_FOLDER_NAME}
copy test_binary_btec_script.py ${TEST_FOLDER_NAME}
cd ${TEST_FOLDER_NAME}
python test_binary_script.py ${BUILD_FILE_NAME}
python test_binary_deposit_script.py ${BUILD_FILE_NAME}
python test_binary_btec_script.py ${BUILD_FILE_NAME}
- run:
name: Compress the file
command: |
Expand Down Expand Up @@ -271,9 +280,11 @@ jobs:
export TEST_FOLDER_NAME=TMP_TEST_FOLDER
mkdir ${TEST_FOLDER_NAME}
cp -r ${BUILD_FILE_NAME} ${TEST_FOLDER_NAME}
cp test_binary_script.py ${TEST_FOLDER_NAME}
cp test_binary_deposit_script.py ${TEST_FOLDER_NAME}
cp test_binary_btec_script.py ${TEST_FOLDER_NAME}
cd ${TEST_FOLDER_NAME}
python3 test_binary_script.py ./${BUILD_FILE_NAME};
python3 test_binary_deposit_script.py ./${BUILD_FILE_NAME};
python3 test_binary_btec_script.py ./${BUILD_FILE_NAME};
- run:
name: Compress the file
command: |
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
validator_keys
bls_to_execution_changes

# Python testing & linting:
build/
Expand Down
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- [`new-mnemonic` Arguments](#new-mnemonic-arguments)
- [`existing-mnemonic` Arguments](#existing-mnemonic-arguments)
- [Successful message](#successful-message)
- [`generate-bls-to-execution-change` Arguments](#generate-bls-to-execution-change-arguments)
- [Option 2. Build `deposit-cli` with native Python](#option-2-build-deposit-cli-with-native-python)
- [Step 0. Python version checking](#step-0-python-version-checking)
- [Step 1. Installation](#step-1-installation-1)
Expand Down Expand Up @@ -139,7 +140,7 @@ You can use `new-mnemonic --help` to see all arguments. Note that if there are m
| `--mnemonic_language` | String. Options: `简体中文`, `繁體中文`, `český jazyk`, `English`, `Italiano`, `한국어`, `Português`, `Español`. Default to `English` | The mnemonic language |
| `--folder` | String. Pointing to `./validator_keys` by default | The folder path for the keystore(s) and deposit(s) |
| `--chain` | String. `mainnet` by default | The chain setting for the signing domain. |
| `--eth1_withdrawal_address` | String. Eth1 address in hexadecimal encoded form | If this field is set and valid, the given Eth1 address will be used to create the withdrawal credentials. Otherwise, it will generate withdrawal credentials with the mnemonic-derived withdrawal public key in [EIP-2334 format](https://eips.ethereum.org/EIPS/eip-2334#eth2-specific-parameters). |
| `--eth1_withdrawal_address` | String. Eth1 address in hexadecimal encoded form | If this field is set and valid, the given Eth1 address will be used to create the withdrawal credentials. Otherwise, it will generate withdrawal credentials with the mnemonic-derived withdrawal public key in [ERC-2334 format](https://eips.ethereum.org/EIPS/eip-2334#eth2-specific-parameters). |

###### `existing-mnemonic` Arguments

Expand All @@ -151,7 +152,7 @@ You can use `existing-mnemonic --help` to see all arguments. Note that if there
| `--num_validators` | Non-negative integer | The number of new signing keys you want to generate. Note that the child key(s) are generated via the same master key. |
| `--folder` | String. Pointing to `./validator_keys` by default | The folder path for the keystore(s) and deposit(s) |
| `--chain` | String. `mainnet` by default | The chain setting for the signing domain. |
| `--eth1_withdrawal_address` | String. Eth1 address in hexadecimal encoded form | If this field is set and valid, the given Eth1 address will be used to create the withdrawal credentials. Otherwise, it will generate withdrawal credentials with the mnemonic-derived withdrawal public key in [EIP-2334 format](https://eips.ethereum.org/EIPS/eip-2334#eth2-specific-parameters). |
| `--eth1_withdrawal_address` | String. Eth1 address in hexadecimal encoded form | If this field is set and valid, the given Eth1 address will be used to create the withdrawal credentials. Otherwise, it will generate withdrawal credentials with the mnemonic-derived withdrawal public key in [ERC-2334 format](https://eips.ethereum.org/EIPS/eip-2334#eth2-specific-parameters). |

###### Successful message

Expand All @@ -168,6 +169,22 @@ Success!
Your keys can be found at: <YOUR_FOLDER_PATH>
```

###### `generate-bls-to-execution-change` Arguments

You can use `bls-to-execution-change --help` to see all arguments. Note that if there are missing arguments that the CLI needs, it will ask you for them.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you try to run the bls-to-execution-change subcommand with --help it will actually skip the help menu and drop right into interactive mode:

user@laptop:~/repos/staking-deposit-cli$ python3 ./staking_deposit/deposit.py generate-bls-to-execution-change --help

***Using the tool on an offline and secure device is highly recommended to keep your mnemonic safe.***

Please choose your language ['1. العربية', '2. ελληνικά', '3. English', '4. Français', '5. Bahasa melayu', '6. Italiano', '7. 日本語', '8. 한국어', '9. Português do Brasil', '10. român', '11. Türkçe', '12. 简体中文']:  [English]: 


| Argument | Type | Description |
| -------- | -------- | -------- |
| `--bls_to_execution_changes_folder` | String. Pointing to `./bls_to_execution_changes` by default | The folder path for the `bls_to_execution_change-*` JSON file(s) |
| `--chain` | String. `mainnet` by default | The chain setting for the signing domain. |
| `--mnemonic` | String. mnemonic split by space. | The mnemonic you used to create withdrawal credentials. |
| `--mnemonic_password` | Optional string. Empty by default. | The mnemonic password you used in your key generation. Note: It's not the keystore password. |
| `--validator_start_index` | Non-negative integer | The index position for the keys to start generating withdrawal credentials in [ERC-2334 format](https://eips.ethereum.org/EIPS/eip-2334#eth2-specific-parameters). |
| `--validator_indices` | String of integer(s) | A list of the chosen validator index number(s) as identified on the beacon chain. Split multiple items with whitespaces or commas. |
| `--bls_withdrawal_credentials_list` | String of hexstring(s). | A list of the old BLS withdrawal credentials of the given validator(s). It is for confirming you are using the correct keys. Split multiple items with whitespaces or commas. |
| `--execution_address` | String. 20-byte Execution (Eth1) address in hexadecimal encoded form | The execution (Eth1) address you want to change to for withdrawals. |
| `--devnet_chain_setting` | String. JSON string `'{"network_name": "<NETWORK_NAME>", "genesis_fork_version": "<GENESIS_FORK_VERSION>", "genesis_validator_root": "<GENESIS_VALIDATOR_ROOT>"}'` | The custom chain setting of a devnet or testnet. Note that it will override your `--chain` choice. |

#### Option 2. Build `deposit-cli` with native Python

##### Step 0. Python version checking
Expand Down Expand Up @@ -228,6 +245,7 @@ See [here](#commands)

See [here](#new-mnemonic-arguments) for `new-mnemonic` arguments
See [here](#existing-mnemonic-arguments) for `existing-mnemonic` arguments
See [here](#generate-bls-to-execution-change-arguments) for `generate-bls-to-execution-change` arguments

###### Successful message
See [here](#successful-message)
Expand Down Expand Up @@ -295,6 +313,7 @@ See [here](#commands)

See [here](#new-mnemonic-arguments) for `new-mnemonic` arguments
See [here](#existing-mnemonic-arguments) for `existing-mnemonic` arguments
See [here](#generate-bls-to-execution-change-arguments) for `generate-bls-to-execution-change` arguments

#### Option 4. Use Docker image

Expand Down Expand Up @@ -378,6 +397,7 @@ See [here](#commands)

See [here](#new-mnemonic-arguments) for `new-mnemonic` arguments
See [here](#existing-mnemonic-arguments) for `existing-mnemonic` arguments
See [here](#generate-bls-to-execution-change-arguments) for `generate-bls-to-execution-change` arguments

#### Option 2. Build `deposit-cli` with native Python

Expand Down Expand Up @@ -440,6 +460,7 @@ See [here](#commands)

See [here](#new-mnemonic-arguments) for `new-mnemonic` arguments
See [here](#existing-mnemonic-arguments) for `existing-mnemonic` arguments
See [here](#generate-bls-to-execution-change-arguments) for `generate-bls-to-execution-change` arguments

#### Option 3. Build `deposit-cli` with `virtualenv`

Expand Down Expand Up @@ -504,6 +525,7 @@ See [here](#commands)

See [here](#new-mnemonic-arguments) for `new-mnemonic` arguments
See [here](#existing-mnemonic-arguments) for `existing-mnemonic` arguments
See [here](#generate-bls-to-execution-change-arguments) for `generate-bls-to-execution-change` arguments

## Development

Expand Down
56 changes: 35 additions & 21 deletions staking_deposit/cli/existing_mnemonic.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import click
from typing import (
Any,
Callable,
)

from staking_deposit.exceptions import ValidationError
Expand All @@ -22,6 +23,39 @@
)


def load_mnemonic_arguments_decorator(function: Callable[..., Any]) -> Callable[..., Any]:
'''
This is a decorator that, when applied to a parent-command, implements the
to obtain the necessary arguments for the generate_keys() subcommand.
'''
decorators = [
jit_option(
callback=validate_mnemonic,
help=lambda: load_text(['arg_mnemonic', 'help'], func='existing_mnemonic'),
param_decls='--mnemonic',
prompt=lambda: load_text(['arg_mnemonic', 'prompt'], func='existing_mnemonic'),
type=str,
),
jit_option(
callback=captive_prompt_callback(
lambda x: x,
lambda: load_text(['arg_mnemonic_password', 'prompt'], func='existing_mnemonic'),
lambda: load_text(['arg_mnemonic_password', 'confirm'], func='existing_mnemonic'),
lambda: load_text(['arg_mnemonic_password', 'mismatch'], func='existing_mnemonic'),
True,
),
default='',
help=lambda: load_text(['arg_mnemonic_password', 'help'], func='existing_mnemonic'),
hidden=True,
param_decls='--mnemonic-password',
prompt=False,
),
]
for decorator in reversed(decorators):
function = decorator(function)
return function


def validate_mnemonic(ctx: click.Context, param: Any, mnemonic: str) -> str:
mnemonic = reconstruct_mnemonic(mnemonic, WORD_LISTS_PATH)
if mnemonic is not None:
Expand All @@ -33,27 +67,7 @@ def validate_mnemonic(ctx: click.Context, param: Any, mnemonic: str) -> str:
@click.command(
help=load_text(['arg_existing_mnemonic', 'help'], func='existing_mnemonic'),
)
@jit_option(
callback=validate_mnemonic,
help=lambda: load_text(['arg_mnemonic', 'help'], func='existing_mnemonic'),
param_decls='--mnemonic',
prompt=lambda: load_text(['arg_mnemonic', 'prompt'], func='existing_mnemonic'),
type=str,
)
@jit_option(
callback=captive_prompt_callback(
lambda x: x,
lambda: load_text(['arg_mnemonic_password', 'prompt'], func='existing_mnemonic'),
lambda: load_text(['arg_mnemonic_password', 'confirm'], func='existing_mnemonic'),
lambda: load_text(['arg_mnemonic_password', 'mismatch'], func='existing_mnemonic'),
True,
),
default='',
help=lambda: load_text(['arg_mnemonic_password', 'help'], func='existing_mnemonic'),
hidden=True,
param_decls='--mnemonic-password',
prompt=False,
)
@load_mnemonic_arguments_decorator
@jit_option(
callback=captive_prompt_callback(
lambda num: validate_int_range(num, 0, 2**32),
Expand Down
Loading