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

Feature add --amount option #286

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 11 additions & 1 deletion staking_deposit/cli/existing_mnemonic.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
reconstruct_mnemonic,
)
from staking_deposit.utils.constants import (
WORD_LISTS_PATH,
WORD_LISTS_PATH, MAX_DEPOSIT_ETH, MIN_DEPOSIT_ETH,
)
from staking_deposit.utils.click import (
captive_prompt_callback,
Expand Down Expand Up @@ -65,6 +65,16 @@ def validate_mnemonic(ctx: click.Context, param: Any, mnemonic: str) -> str:
param_decls="--validator_start_index",
prompt=lambda: load_text(['arg_validator_start_index', 'prompt'], func='existing_mnemonic'),
)
@jit_option(
callback=captive_prompt_callback(
lambda num: validate_int_range(num, MIN_DEPOSIT_ETH, MAX_DEPOSIT_ETH + 1),
lambda: load_text(['arg_amount', 'prompt'], func='existing_mnemonic'),
),
default=32,
help=lambda: load_text(['arg_amount', 'help'], func='existing_mnemonic'),
param_decls="--amount",
prompt=lambda: load_text(['arg_amount', 'prompt'], func='existing_mnemonic'),
)
@generate_keys_arguments_decorator
@click.pass_context
def existing_mnemonic(ctx: click.Context, mnemonic: str, mnemonic_password: str, **kwargs: Any) -> None:
Expand Down
6 changes: 3 additions & 3 deletions staking_deposit/cli/generate_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
validate_password_strength,
)
from staking_deposit.utils.constants import (
MAX_DEPOSIT_AMOUNT,
ETH2GWEI,
DEFAULT_VALIDATOR_KEYS_FOLDER_NAME,
)
from staking_deposit.utils.ascii_art import RHINO_0
Expand Down Expand Up @@ -121,10 +121,10 @@ def generate_keys_arguments_decorator(function: Callable[..., Any]) -> Callable[
@click.pass_context
def generate_keys(ctx: click.Context, validator_start_index: int,
num_validators: int, folder: str, chain: str, keystore_password: str,
eth1_withdrawal_address: HexAddress, **kwargs: Any) -> None:
eth1_withdrawal_address: HexAddress, amount: int, **kwargs: Any) -> None:
mnemonic = ctx.obj['mnemonic']
mnemonic_password = ctx.obj['mnemonic_password']
amounts = [MAX_DEPOSIT_AMOUNT] * num_validators
amounts = [amount * ETH2GWEI] * num_validators
folder = os.path.join(folder, DEFAULT_VALIDATOR_KEYS_FOLDER_NAME)
chain_setting = get_chain_setting(chain)
if not os.path.exists(folder):
Expand Down
3 changes: 2 additions & 1 deletion staking_deposit/cli/new_mnemonic.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
)
from staking_deposit.utils.constants import (
MNEMONIC_LANG_OPTIONS,
WORD_LISTS_PATH,
WORD_LISTS_PATH, MAX_DEPOSIT_ETH,
)
from staking_deposit.utils.intl import (
fuzzy_reverse_dict_lookup,
Expand Down Expand Up @@ -60,4 +60,5 @@ def new_mnemonic(ctx: click.Context, mnemonic_language: str, **kwargs: Any) -> N
# Do NOT use mnemonic_password.
ctx.obj = {'mnemonic': mnemonic, 'mnemonic_password': ''}
ctx.params['validator_start_index'] = 0
ctx.params['amount'] = MAX_DEPOSIT_ETH
ctx.forward(generate_keys)
4 changes: 4 additions & 0 deletions staking_deposit/intl/en/cli/existing_mnemonic.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
"help": "Enter the index (key number) you wish to start generating more keys from. For example, if you've generated 4 keys in the past, you'd enter 4 here.",
"prompt": "Enter the index (key number) you wish to start generating more keys from. For example, if you've generated 4 keys in the past, you'd enter 4 here.",
"confirm": "Please repeat the index to confirm"
},
"arg_amount": {
"help": "Enter the deposit amount in ETH. From 1 to 32 ETH.",
"prompt": "Enter the deposit amount in ETH. From 1 to 32 ETH."
}
}
}
7 changes: 4 additions & 3 deletions staking_deposit/utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
ETH1_ADDRESS_WITHDRAWAL_PREFIX = bytes.fromhex('01')

ETH2GWEI = 10 ** 9
MIN_DEPOSIT_AMOUNT = 2 ** 0 * ETH2GWEI
MAX_DEPOSIT_AMOUNT = 2 ** 5 * ETH2GWEI

MAX_DEPOSIT_ETH = 2 ** 5
MIN_DEPOSIT_ETH = 2 ** 0
MIN_DEPOSIT_AMOUNT = MIN_DEPOSIT_ETH * ETH2GWEI
MAX_DEPOSIT_AMOUNT = MAX_DEPOSIT_ETH * ETH2GWEI

# File/folder constants
WORD_LISTS_PATH = os.path.join('staking_deposit', 'key_handling', 'key_derivation', 'word_lists')
Expand Down
2 changes: 1 addition & 1 deletion staking_deposit/utils/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def validate_deposit(deposit_data_dict: Dict[str, Any], credential: Credential)
return False

# Verify deposit amount
if not MIN_DEPOSIT_AMOUNT < amount <= MAX_DEPOSIT_AMOUNT:
if not MIN_DEPOSIT_AMOUNT <= amount <= MAX_DEPOSIT_AMOUNT:
return False

# Verify deposit signature && pubkey
Expand Down
55 changes: 55 additions & 0 deletions tests/test_cli/test_existing_menmonic.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def test_existing_mnemonic_bls_withdrawal() -> None:
'existing-mnemonic',
'--folder', my_folder_path,
'--mnemonic-password', 'TREZOR',
'--amount', 32,
]
result = runner.invoke(cli, arguments, input=data)

Expand Down Expand Up @@ -74,6 +75,7 @@ def test_existing_mnemonic_eth1_address_withdrawal() -> None:
'--folder', my_folder_path,
'--mnemonic-password', 'TREZOR',
'--eth1_withdrawal_address', eth1_withdrawal_address,
'--amount', 32,
]
result = runner.invoke(cli, arguments, input=data)

Expand Down Expand Up @@ -136,6 +138,7 @@ async def test_script() -> None:
'--chain', 'mainnet',
'--keystore_password', 'MyPassword',
'--folder', my_folder_path,
'--amount', '32',
]
proc = await asyncio.create_subprocess_shell(
' '.join(cmd_args),
Expand Down Expand Up @@ -183,6 +186,7 @@ async def test_script_abbreviated_mnemonic() -> None:
'--chain', 'mainnet',
'--keystore_password', 'MyPassword',
'--folder', my_folder_path,
'--amount', '32',
]
proc = await asyncio.create_subprocess_shell(
' '.join(cmd_args),
Expand All @@ -199,3 +203,54 @@ async def test_script_abbreviated_mnemonic() -> None:

# Clean up
clean_key_folder(my_folder_path)


@pytest.mark.asyncio
def test_existing_mnemonic_amount() -> None:
# Prepare folder
my_folder_path = os.path.join(os.getcwd(), 'TESTING_TEMP_FOLDER')
clean_key_folder(my_folder_path)
if not os.path.exists(my_folder_path):
os.mkdir(my_folder_path)

runner = CliRunner()
inputs = [
'TREZOR',
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
'2', '2', '5', 'mainnet', 'MyPassword', 'MyPassword']
data = '\n'.join(inputs)
arguments = [
'--language', 'english',
'existing-mnemonic',
'--folder', my_folder_path,
'--mnemonic-password', 'TREZOR',
'--amount', 1
]
result = runner.invoke(cli, arguments, input=data)

assert result.exit_code == 0

# Check files
validator_keys_folder_path = os.path.join(my_folder_path, DEFAULT_VALIDATOR_KEYS_FOLDER_NAME)
_, _, key_files = next(os.walk(validator_keys_folder_path))

deposit_file = [key_file for key_file in key_files if key_file.startswith('deposit_data')][0]
with open(validator_keys_folder_path + '/' + deposit_file, 'r') as f:
deposits_dict = json.load(f)
for deposit in deposits_dict:
amount = deposit['amount']
assert amount == (10 ** 9)

all_uuid = [
get_uuid(validator_keys_folder_path + '/' + key_file)
for key_file in key_files
if key_file.startswith('keystore')
]
assert len(set(all_uuid)) == 5

# Verify file permissions
if os.name == 'posix':
for file_name in key_files:
assert get_permissions(validator_keys_folder_path, file_name) == '0o440'
# Clean up
clean_key_folder(my_folder_path)
2 changes: 1 addition & 1 deletion tests/test_cli/test_regeneration.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def mock_get_mnemonic(language, words_path, entropy=None) -> str:
mock_mnemonic,
'1', '1', '2', 'mainnet', 'MyPassword', 'MyPassword']
data = '\n'.join(inputs)
arguments = ['existing-mnemonic', '--folder', folder_path_2]
arguments = ['existing-mnemonic', '--folder', folder_path_2, '--amount', 32]
result = runner.invoke(cli, arguments, input=data)

assert result.exit_code == 0
Expand Down