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 Ethereum secp keys to validators #471

Merged
merged 48 commits into from
Oct 13, 2022
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
0918529
fixup! pos: add validator eth cold and hot keys
tzemanovic Aug 21, 2022
ebbc8fc
shared: add eth keys for validators
tzemanovic Aug 21, 2022
250ee2e
client: add eth keys for validators
tzemanovic Aug 21, 2022
6893c20
TODO: update genesis
tzemanovic Aug 21, 2022
92a0e22
config: add eth keys to genesis
brentstone Aug 21, 2022
fd92541
client: add eth keys to pre_genesis
brentstone Aug 21, 2022
93179b7
wallet: add eth keys to ValidatorWallet
brentstone Aug 21, 2022
87f70e4
proper hard-coded secp keys, remove outdated comments
brentstone Aug 24, 2022
be2a295
shared: add conversion from secp256k1 pk to eth address
tzemanovic Sep 7, 2022
de84663
WIP: add maps for eth address reverse lookup to native address
tzemanovic Sep 7, 2022
f083429
TODO: add eth hot key to validator keys in the wallet store
tzemanovic Sep 7, 2022
6b9de30
WIP: Merge eth hot and cold keys into single storage sub-key space
sug0 Sep 8, 2022
e283819
add eth keys to gen_genesis_validator test
brentstone Sep 9, 2022
231a664
WIP: adding secp key as a ValidatorKeys field
sug0 Sep 9, 2022
8e27bba
WIP: add missing ValidatorKeys field
sug0 Sep 9, 2022
ade2415
WIP: gen eth keys
sug0 Sep 9, 2022
aa7e997
fixup! WIP: gen eth keys
tzemanovic Sep 9, 2022
5ba4781
fixup! WIP: add maps for eth address reverse lookup to native address
tzemanovic Sep 9, 2022
d3143f3
write eth keys and addresses for genesis and on-chain created validators
tzemanovic Sep 9, 2022
dc05733
fixup! WIP: gen eth keys
tzemanovic Sep 12, 2022
dac56f2
fixup! WIP: gen eth keys
tzemanovic Sep 12, 2022
5cbc47c
fix cli
tzemanovic Sep 12, 2022
175da50
Fix wasm tests
sug0 Sep 12, 2022
3950da6
Remove duplicate tiny-keccak dep
sug0 Sep 13, 2022
7ca2f72
Fix prepare and process proposal unit tests
sug0 Sep 13, 2022
e22a4e2
Run make fmt
sug0 Sep 13, 2022
aaad19f
Remove duped EthAddress type from namada shared
sug0 Sep 15, 2022
166e483
Return an Ethereum bridge addr from a Namada validator addr
sug0 Sep 15, 2022
8fffeca
Add voting powers map to valset upd vexts
sug0 Sep 15, 2022
48e1fe9
Add missing read_eth_key_addresses() to PosReadOnly
sug0 Sep 15, 2022
ca8aef4
WIP: Verify voting powers in valset upd vext
sug0 Sep 15, 2022
ab24237
Verify voting powers in valset upd vext
sug0 Sep 15, 2022
f22f19d
Verify valset upd vext with secp key
sug0 Sep 15, 2022
5e5d88f
Remove unused eth key addresses pos methods
sug0 Sep 15, 2022
9308917
Ignore test_secp_key_belongs_to_active_validator() unit test
sug0 Sep 15, 2022
e7c0994
Add get_eth_bridge_keypair()
sug0 Sep 15, 2022
cb0e980
WIP: Fix unit tests
sug0 Sep 15, 2022
0d5c029
Add method to recover secp sig from a byte array
sug0 Sep 15, 2022
66c89db
Add new test utils
sug0 Sep 15, 2022
e0f88e0
Fix clippy checks
sug0 Sep 15, 2022
86a4d5f
Fixed signature of PoS eth key read methods
sug0 Sep 16, 2022
7e08fc0
Add epoched Ethereum keys
sug0 Sep 16, 2022
daab76d
Fix typo in secp key code
sug0 Sep 16, 2022
540eb4c
Merge eth-bridge-integration
sug0 Sep 21, 2022
b2fc5c1
Load the right keys from ValidatorConfig
sug0 Sep 21, 2022
3411176
Merge eth-bridge-integration
sug0 Sep 27, 2022
7374acd
Merge eth-bridge-integration
sug0 Oct 12, 2022
b608c78
[ci] wasm checksums update
github-actions[bot] Oct 13, 2022
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
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