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

feat: presign for validator account #6747

Open
wants to merge 1 commit into
base: unstable
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions account_manager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ eth2_wallet_manager = { path = "../common/eth2_wallet_manager" }
filesystem = { workspace = true }
safe_arith = { workspace = true }
sensitive_url = { workspace = true }
serde_json = { workspace = true }
slashing_protection = { workspace = true }
slot_clock = { workspace = true }
tokio = { workspace = true }
Expand Down
35 changes: 32 additions & 3 deletions account_manager/src/validator/exit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use eth2_keystore::Keystore;
use eth2_network_config::Eth2NetworkConfig;
use safe_arith::SafeArith;
use sensitive_url::SensitiveUrl;
use serde_json;
use slot_clock::{SlotClock, SystemTimeSlotClock};
use std::path::{Path, PathBuf};
use std::time::Duration;
Expand All @@ -24,6 +25,7 @@ pub const BEACON_SERVER_FLAG: &str = "beacon-node";
pub const NO_WAIT: &str = "no-wait";
pub const NO_CONFIRMATION: &str = "no-confirmation";
pub const PASSWORD_PROMPT: &str = "Enter the keystore password";
pub const PRESIGN: &str = "presign";

pub const DEFAULT_BEACON_NODE: &str = "http://localhost:5052/";
pub const CONFIRMATION_PHRASE: &str = "Exit my validator";
Expand Down Expand Up @@ -74,6 +76,15 @@ pub fn cli_app() -> Command {
.action(ArgAction::SetTrue)
.help_heading(FLAG_HEADER)
)
.arg(
Arg::new(PRESIGN)
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps we want to standardise the flag name to be the same with #6612 , depends on which is preferred. I am happy to change the flag name in #6612 if presign is adopted.

Copy link
Member

@chong-he chong-he Jan 22, 2025

Choose a reason for hiding this comment

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

I have changed the flag name in #6612 to --presign as per the comment: #6612 (comment)

So please ignore the above

.long(PRESIGN)
.help("Only presign the voluntary exit message without publishing it")
.default_value("false")
.action(ArgAction::SetTrue)
.help_heading(FLAG_HEADER)
.display_order(0)
)
}

pub fn cli_run<E: EthSpec>(matches: &ArgMatches, env: Environment<E>) -> Result<(), String> {
Expand All @@ -84,6 +95,7 @@ pub fn cli_run<E: EthSpec>(matches: &ArgMatches, env: Environment<E>) -> Result<
let stdin_inputs = cfg!(windows) || matches.get_flag(STDIN_INPUTS_FLAG);
let no_wait = matches.get_flag(NO_WAIT);
let no_confirmation = matches.get_flag(NO_CONFIRMATION);
let presign = matches.get_flag(PRESIGN);

let spec = env.eth2_config().spec.clone();
let server_url: String = clap_utils::parse_required(matches, BEACON_SERVER_FLAG)?;
Expand All @@ -107,6 +119,7 @@ pub fn cli_run<E: EthSpec>(matches: &ArgMatches, env: Environment<E>) -> Result<
&eth2_network_config,
no_wait,
no_confirmation,
presign,
))?;

Ok(())
Expand All @@ -123,6 +136,7 @@ async fn publish_voluntary_exit<E: EthSpec>(
eth2_network_config: &Eth2NetworkConfig,
no_wait: bool,
no_confirmation: bool,
presign: bool,
) -> Result<(), String> {
let genesis_data = get_geneisis_data(client).await?;
let testnet_genesis_root = eth2_network_config
Expand Down Expand Up @@ -154,9 +168,26 @@ async fn publish_voluntary_exit<E: EthSpec>(
validator_index,
};

// Sign the voluntary exit. We sign ahead of the prompt as that step is only important for the broadcast
let signed_voluntary_exit = voluntary_exit.sign(&keypair.sk, genesis_data.genesis_validators_root, spec);
if presign {
eprintln!(
"Successfully pre-signed voluntary exit for validator {}. Not publishing.",
keypair.pk
);

// Convert to JSON and print
let string_output = serde_json::to_string_pretty(&signed_voluntary_exit)
.map_err(|e| format!("Unable to convert to JSON: {}", e))?;

println!("{}", string_output);
Copy link
Member

Choose a reason for hiding this comment

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

While working on #6612 , initially I also printed out the signature. But then I realise it probably isn't much useful in practice - if users want to pre-sign an exit, they probably want the signature saved to a file. So I modified in this commit in that PR:
5a4f928

We can hear from others about this and edit accordingly.

return Ok(());
}

eprintln!(
"Publishing a voluntary exit for validator: {} \n",
keypair.pk

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change

);
if !no_confirmation {
eprintln!("WARNING: THIS IS AN IRREVERSIBLE OPERATION\n");
Expand All @@ -174,9 +205,7 @@ async fn publish_voluntary_exit<E: EthSpec>(
};

if confirmation == CONFIRMATION_PHRASE {
// Sign and publish the voluntary exit to network
let signed_voluntary_exit =
voluntary_exit.sign(&keypair.sk, genesis_data.genesis_validators_root, spec);
// Publish the voluntary exit to network
client
.post_beacon_pool_voluntary_exits(&signed_voluntary_exit)
.await
Expand Down
Loading