Skip to content

Commit

Permalink
Merge pull request #471 from anoma/tiago/ethbridge/ledger-secp-keys
Browse files Browse the repository at this point in the history
Add Ethereum secp keys to validators
  • Loading branch information
sug0 authored Oct 13, 2022
2 parents 74eb265 + b608c78 commit 9abe316
Show file tree
Hide file tree
Showing 27 changed files with 1,018 additions and 157 deletions.
22 changes: 21 additions & 1 deletion apps/src/lib/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1482,6 +1482,9 @@ pub mod args {
arg_opt("account-key");
const VALIDATOR_CONSENSUS_KEY: ArgOpt<WalletKeypair> =
arg_opt("consensus-key");
const VALIDATOR_ETH_COLD_KEY: ArgOpt<WalletKeypair> =
arg_opt("eth-cold-key");
const VALIDATOR_ETH_HOT_KEY: ArgOpt<WalletKeypair> = arg_opt("eth-hot-key");
const VALIDATOR_CODE_PATH: ArgOpt<PathBuf> = arg_opt("validator-code-path");
const VALUE: ArgOpt<String> = arg_opt("value");
const WASM_CHECKSUMS_PATH: Arg<PathBuf> = arg("wasm-checksums-path");
Expand Down Expand Up @@ -1700,6 +1703,8 @@ pub mod args {
pub scheme: SchemeType,
pub account_key: Option<WalletPublicKey>,
pub consensus_key: Option<WalletKeypair>,
pub eth_cold_key: Option<WalletKeypair>,
pub eth_hot_key: Option<WalletKeypair>,
pub rewards_account_key: Option<WalletPublicKey>,
pub protocol_key: Option<WalletPublicKey>,
pub validator_vp_code_path: Option<PathBuf>,
Expand All @@ -1714,6 +1719,8 @@ pub mod args {
let scheme = SCHEME.parse(matches);
let account_key = VALIDATOR_ACCOUNT_KEY.parse(matches);
let consensus_key = VALIDATOR_CONSENSUS_KEY.parse(matches);
let eth_cold_key = VALIDATOR_ETH_COLD_KEY.parse(matches);
let eth_hot_key = VALIDATOR_ETH_HOT_KEY.parse(matches);
let rewards_account_key = REWARDS_KEY.parse(matches);
let protocol_key = PROTOCOL_KEY.parse(matches);
let validator_vp_code_path = VALIDATOR_CODE_PATH.parse(matches);
Expand All @@ -1725,6 +1732,8 @@ pub mod args {
scheme,
account_key,
consensus_key,
eth_cold_key,
eth_hot_key,
rewards_account_key,
protocol_key,
validator_vp_code_path,
Expand All @@ -1748,7 +1757,18 @@ pub mod args {
))
.arg(VALIDATOR_CONSENSUS_KEY.def().about(
"A consensus key for the validator account. A new one \
will be generated if none given.",
will be generated if none given. Note that this must be \
ed25519.",
))
.arg(VALIDATOR_ETH_COLD_KEY.def().about(
"An Eth cold key for the validator account. A new one \
will be generated if none given. Note that this must be \
secp256k1.",
))
.arg(VALIDATOR_ETH_HOT_KEY.def().about(
"An Eth hot key for the validator account. A new one will \
be generated if none given. Note that this must be \
secp256k1.",
))
.arg(REWARDS_KEY.def().about(
"A public key for the staking reward account. A new one \
Expand Down
63 changes: 60 additions & 3 deletions apps/src/lib/client/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use namada::types::address::{xan as m1t, Address};
use namada::types::governance::{
OfflineProposal, OfflineVote, Proposal, ProposalVote,
};
use namada::types::key::*;
use namada::types::key::{self, *};
use namada::types::nft::{self, Nft, NftToken};
use namada::types::storage::{Epoch, Key};
use namada::types::token::Amount;
Expand Down Expand Up @@ -159,6 +159,8 @@ pub async fn submit_init_validator(
scheme,
account_key,
consensus_key,
eth_cold_key,
eth_hot_key,
rewards_account_key,
protocol_key,
validator_vp_code_path,
Expand All @@ -175,6 +177,8 @@ pub async fn submit_init_validator(
let validator_key_alias = format!("{}-key", alias);
let consensus_key_alias = format!("{}-consensus-key", alias);
let rewards_key_alias = format!("{}-rewards-key", alias);
let eth_hot_key_alias = format!("{}-eth-hot-key", alias);
let eth_cold_key_alias = format!("{}-eth-cold-key", alias);
let account_key = ctx.get_opt_cached(&account_key).unwrap_or_else(|| {
println!("Generating validator account key...");
ctx.wallet
Expand Down Expand Up @@ -208,6 +212,48 @@ pub async fn submit_init_validator(
.1
});

let eth_cold_key = ctx
.get_opt_cached(&eth_cold_key)
.map(|key| match *key {
common::SecretKey::Secp256k1(_) => key,
common::SecretKey::Ed25519(_) => {
eprintln!("Eth cold key can only be secp256k1");
safe_exit(1)
}
})
.unwrap_or_else(|| {
println!("Generating Eth cold key...");
ctx.wallet
.gen_key(
// Note that ETH only allows secp256k1
SchemeType::Secp256k1,
Some(eth_cold_key_alias.clone()),
unsafe_dont_encrypt,
)
.1
});

let eth_hot_key = ctx
.get_opt_cached(&eth_hot_key)
.map(|key| match *key {
common::SecretKey::Secp256k1(_) => key,
common::SecretKey::Ed25519(_) => {
eprintln!("Eth hot key can only be secp256k1");
safe_exit(1)
}
})
.unwrap_or_else(|| {
println!("Generating Eth hot key...");
ctx.wallet
.gen_key(
// Note that ETH only allows secp256k1
SchemeType::Secp256k1,
Some(eth_hot_key_alias.clone()),
unsafe_dont_encrypt,
)
.1
});

let rewards_account_key =
ctx.get_opt_cached(&rewards_account_key).unwrap_or_else(|| {
println!("Generating staking reward account key...");
Expand All @@ -225,9 +271,12 @@ pub async fn submit_init_validator(
if protocol_key.is_none() {
println!("Generating protocol signing key...");
}
let eth_hot_pk = eth_hot_key.ref_to();
// Generate the validator keys
let validator_keys =
ctx.wallet.gen_validator_keys(protocol_key, scheme).unwrap();
let validator_keys = ctx
.wallet
.gen_validator_keys(Some(eth_hot_pk), protocol_key, scheme)
.unwrap();
let protocol_key = validator_keys.get_protocol_keypair().ref_to();
let dkg_key = validator_keys
.dkg_keypair
Expand Down Expand Up @@ -269,6 +318,14 @@ pub async fn submit_init_validator(
let data = InitValidator {
account_key,
consensus_key: consensus_key.ref_to(),
eth_cold_key: key::secp256k1::PublicKey::try_from_pk(
&eth_cold_key.ref_to(),
)
.unwrap(),
eth_hot_key: key::secp256k1::PublicKey::try_from_pk(
&eth_hot_key.ref_to(),
)
.unwrap(),
rewards_account_key,
protocol_key,
dkg_key,
Expand Down
41 changes: 41 additions & 0 deletions apps/src/lib/client/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,36 @@ pub fn init_network(
keypair.ref_to()
});

let eth_hot_pk = try_parse_public_key(
format!("validator {name} eth hot key"),
&config.eth_hot_key,
)
.unwrap_or_else(|| {
let alias = format!("{}-eth-hot-key", name);
println!("Generating validator {} eth hot key...", name);
let (_alias, keypair) = wallet.gen_key(
SchemeType::Secp256k1,
Some(alias),
unsafe_dont_encrypt,
);
keypair.ref_to()
});

let eth_cold_pk = try_parse_public_key(
format!("validator {name} eth cold key"),
&config.eth_cold_key,
)
.unwrap_or_else(|| {
let alias = format!("{}-eth-cold-key", name);
println!("Generating validator {} eth cold key...", name);
let (_alias, keypair) = wallet.gen_key(
SchemeType::Secp256k1,
Some(alias),
unsafe_dont_encrypt,
);
keypair.ref_to()
});

let dkg_pk = &config
.dkg_public_key
.as_ref()
Expand All @@ -608,6 +638,7 @@ pub fn init_network(

let validator_keys = wallet
.gen_validator_keys(
Some(eth_hot_pk.clone()),
Some(protocol_pk.clone()),
SchemeType::Ed25519,
)
Expand All @@ -624,6 +655,10 @@ pub fn init_network(
Some(genesis_config::HexString(account_pk.to_string()));
config.staking_reward_public_key =
Some(genesis_config::HexString(staking_reward_pk.to_string()));
config.eth_cold_key =
Some(genesis_config::HexString(eth_cold_pk.to_string()));
config.eth_hot_key =
Some(genesis_config::HexString(eth_hot_pk.to_string()));

config.protocol_public_key =
Some(genesis_config::HexString(protocol_pk.to_string()));
Expand Down Expand Up @@ -1089,6 +1124,12 @@ pub fn init_genesis_validator(
consensus_public_key: Some(HexString(
pre_genesis.consensus_key.ref_to().to_string(),
)),
eth_cold_key: Some(HexString(
pre_genesis.eth_cold_key.ref_to().to_string(),
)),
eth_hot_key: Some(HexString(
pre_genesis.eth_hot_key.ref_to().to_string(),
)),
account_public_key: Some(HexString(
pre_genesis.account_key.ref_to().to_string(),
)),
Expand Down
51 changes: 49 additions & 2 deletions apps/src/lib/config/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ pub mod genesis_config {
pub struct ValidatorConfig {
// Public key for consensus. (default: generate)
pub consensus_public_key: Option<HexString>,
// Public key (cold) for eth governance. (default: generate)
pub eth_cold_key: Option<HexString>,
// Public key (hot) for eth bridge. (default: generate)
pub eth_hot_key: Option<HexString>,
// Public key for validator account. (default: generate)
pub account_public_key: Option<HexString>,
// Public key for staking reward account. (default: generate)
Expand Down Expand Up @@ -318,6 +322,18 @@ pub mod genesis_config {
.unwrap()
.to_public_key()
.unwrap(),
eth_cold_key: config
.eth_cold_key
.as_ref()
.unwrap()
.to_public_key()
.unwrap(),
eth_hot_key: config
.eth_hot_key
.as_ref()
.unwrap()
.to_public_key()
.unwrap(),
},
account_key: config
.account_public_key
Expand Down Expand Up @@ -750,18 +766,30 @@ pub fn genesis() -> Genesis {
24, 247, 69, 6, 9, 30, 44, 16, 88, 238, 77, 162, 243, 125, 240, 206,
])
.unwrap();

let secp_eth_cold_keypair = secp256k1::SecretKey::try_from_slice(&[
90, 83, 107, 155, 193, 251, 120, 27, 76, 1, 188, 8, 116, 121, 90, 99,
65, 17, 187, 6, 238, 141, 63, 188, 76, 38, 102, 7, 47, 185, 28, 52,
])
.unwrap();

let staking_reward_keypair =
common::SecretKey::try_from_sk(&ed_staking_reward_keypair).unwrap();
let eth_cold_keypair =
common::SecretKey::try_from_sk(&secp_eth_cold_keypair).unwrap();
let address = wallet::defaults::validator_address();
let staking_reward_address = Address::decode("atest1v4ehgw36xcersvee8qerxd35x9prsw2xg5erxv6pxfpygd2x89z5xsf5xvmnysejgv6rwd2rnj2avt").unwrap();
let (protocol_keypair, dkg_keypair) = wallet::defaults::validator_keys();
let (protocol_keypair, eth_bridge_keypair, dkg_keypair) =
wallet::defaults::validator_keys();
let validator = Validator {
pos_data: GenesisValidator {
address,
staking_reward_address,
tokens: token::Amount::whole(200_000),
consensus_key: consensus_keypair.ref_to(),
staking_reward_key: staking_reward_keypair.ref_to(),
eth_cold_key: eth_cold_keypair.ref_to(),
eth_hot_key: eth_bridge_keypair.ref_to(),
},
account_key: account_keypair.ref_to(),
protocol_key: protocol_keypair.ref_to(),
Expand Down Expand Up @@ -886,13 +914,32 @@ pub mod tests {
let staking_reward_keypair: common::SecretKey =
ed25519::SigScheme::generate(&mut rng).try_to_sk().unwrap();
let srkp_arr = staking_reward_keypair.try_to_vec().unwrap();
let (protocol_keypair, dkg_keypair) =
let (protocol_keypair, _eth_hot_bridge_keypair, dkg_keypair) =
wallet::defaults::validator_keys();

// TODO: derive validator eth address from an eth keypair
let eth_cold_gov_keypair: common::SecretKey =
secp256k1::SigScheme::generate(&mut rng)
.try_to_sk()
.unwrap();
let eth_hot_bridge_keypair: common::SecretKey =
secp256k1::SigScheme::generate(&mut rng)
.try_to_sk()
.unwrap();

println!("address: {}", address);
println!("staking_reward_address: {}", staking_reward_address);
println!("keypair: {:?}", kp_arr);
println!("staking_reward_keypair: {:?}", srkp_arr);
println!("protocol_keypair: {:?}", protocol_keypair);
println!("dkg_keypair: {:?}", dkg_keypair.try_to_vec().unwrap());
println!(
"eth_cold_gov_keypair: {:?}",
eth_cold_gov_keypair.try_to_vec().unwrap()
);
println!(
"eth_hot_bridge_keypair: {:?}",
eth_hot_bridge_keypair.try_to_vec().unwrap()
);
}
}
Loading

0 comments on commit 9abe316

Please sign in to comment.