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

draft: Validator eth secp keys #371

Closed
wants to merge 57 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
5763877
shared/key: add arb_common_keypair testing strategy
tzemanovic May 6, 2022
275a636
shared/token: add arb_amount testing strategy
tzemanovic May 6, 2022
07a6821
wasm: add tx_bond tests
tzemanovic May 6, 2022
9ccbece
shared/token: add arb_amount_ceiled testing strategy
tzemanovic May 6, 2022
d1887fd
tests: expose native_vp test helpers
tzemanovic May 11, 2022
0b278a6
PoS: add PartialOrd, Ord, PartialEq and Eq for Epoched an EpochedDelta
tzemanovic May 11, 2022
ba9983e
tests: add re-usable PoS initialization helper
tzemanovic May 11, 2022
cfe2971
tests: make native pos vp module public
junkicide May 13, 2022
72aaf3a
tests: reuse init_pos for native pos vp test
junkicide May 13, 2022
5baeda5
PoS: fix type s/OffsetUnboundingLen/OffsetUnbondingLen
tzemanovic Jun 2, 2022
f9fd2d0
PoS: fix Bonds data type and application of unbonding on it
tzemanovic Jun 2, 2022
80f9191
wasm: tx_unbond tests
junkicide May 30, 2022
ef97a46
wasm: test tx_withdraw
tzemanovic Jun 8, 2022
553fc54
Changelog: add #462
tzemanovic Jun 8, 2022
65bdbfd
tests/pos: add proptest-regressions file
tzemanovic Jul 15, 2022
36e9c58
clean up documentation
brentstone Jul 14, 2022
4bc4b59
removed a deprecated function, spelling fixes
brentstone Jul 15, 2022
4fa9eff
quick doc fix
brentstone Jul 21, 2022
117959d
Update comments
brentstone Jul 21, 2022
4b43766
doc fixed in proof_of_stake/
brentstone Jul 21, 2022
c4a61c4
pos/vp: remove redundant validity predicate storage key check
tzemanovic Jul 29, 2022
74cce90
[ci skip] wasm checksums update
github-actions[bot] Aug 2, 2022
d5ccb62
test: add seed for failed PoS VP test
tzemanovic Aug 12, 2022
08ae9ca
pos/validation: refactor accumulation of changes
tzemanovic Jul 6, 2022
f716311
pos: fix bond zero amount error msg
tzemanovic Jul 6, 2022
2a53746
changelog: add #318
tzemanovic Aug 21, 2022
46cc2dc
Merge branch 'junkicide+tomas/pos-tx-tests' (#254)
tzemanovic Aug 21, 2022
f439b39
Merge branch 'tomas/refactor-pos-vp' (#318)
tzemanovic Aug 21, 2022
3978dff
pos: add validator eth cold and hot keys
tzemanovic Aug 21, 2022
de292a2
fixup! pos: add validator eth cold and hot keys
tzemanovic Aug 21, 2022
d76917b
shared: add eth keys for validators
tzemanovic Aug 21, 2022
a3dde58
client: add eth keys for validators
tzemanovic Aug 21, 2022
d681d7e
TODO: update genesis
tzemanovic Aug 21, 2022
b731b0e
config: add eth keys to genesis
brentstone Aug 21, 2022
5a8c895
client: add eth keys to pre_genesis
brentstone Aug 21, 2022
e179748
wallet: add eth keys to ValidatorWallet
brentstone Aug 21, 2022
4073a6f
proper hard-coded secp keys, remove outdated comments
brentstone Aug 24, 2022
75de2b2
shared: add conversion from secp256k1 pk to eth address
tzemanovic Sep 7, 2022
7fbeb28
WIP: add maps for eth address reverse lookup to native address
tzemanovic Sep 7, 2022
cd1f091
TODO: add eth hot key to validator keys in the wallet store
tzemanovic Sep 7, 2022
09b1aee
WIP: Merge eth hot and cold keys into single storage sub-key space
sug0 Sep 8, 2022
9a18ba1
add eth keys to gen_genesis_validator test
brentstone Sep 9, 2022
061cfc8
WIP: adding secp key as a ValidatorKeys field
sug0 Sep 9, 2022
cf92b69
WIP: add missing ValidatorKeys field
sug0 Sep 9, 2022
318e586
WIP: gen eth keys
sug0 Sep 9, 2022
72d5204
fixup! WIP: gen eth keys
tzemanovic Sep 9, 2022
9ef74bf
fixup! WIP: add maps for eth address reverse lookup to native address
tzemanovic Sep 9, 2022
e636402
write eth keys and addresses for genesis and on-chain created validators
tzemanovic Sep 9, 2022
75489df
fixup! WIP: gen eth keys
tzemanovic Sep 12, 2022
40311d0
fixup! WIP: gen eth keys
tzemanovic Sep 12, 2022
fdbcdc0
fix cli
tzemanovic Sep 12, 2022
e62a1c7
Fix wasm tests
sug0 Sep 12, 2022
86ef7a6
Add missing read_eth_key_addresses() to PosReadOnly
sug0 Sep 15, 2022
f263839
Remove unused eth key addresses pos methods
sug0 Sep 15, 2022
0ef4072
Fixed signature of PoS eth key read methods
sug0 Sep 16, 2022
7cd4852
Fix typo in secp key code
sug0 Sep 16, 2022
19bf28b
Load the right keys from ValidatorConfig
sug0 Sep 21, 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
1 change: 1 addition & 0 deletions .changelog/unreleased/improvements/318-refactor-pos-vp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Refactored PoS VP logic ([#318](https://github.com/anoma/namada/pull/318))
2 changes: 2 additions & 0 deletions .changelog/unreleased/testing/462-pos-tx-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Test PoS transaction for bonding, unbonding and withdrawal. Fixed an issue
found on unbonding. ([#462](https://github.com/anoma/anoma/issues/462))
10 changes: 10 additions & 0 deletions Cargo.lock

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

22 changes: 21 additions & 1 deletion apps/src/lib/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1481,6 +1481,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 @@ -1694,6 +1697,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 @@ -1708,6 +1713,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 @@ -1719,6 +1726,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 @@ -1742,7 +1751,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
75 changes: 60 additions & 15 deletions apps/src/lib/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1194,7 +1194,7 @@ fn process_bonds_query(
let mut total_active = total_active.unwrap_or_else(|| 0.into());
let mut current_total: token::Amount = 0.into();
for bond in bonds.iter() {
for (epoch_start, &(mut delta)) in bond.deltas.iter().sorted() {
for (epoch_start, &(mut delta)) in bond.pos_deltas.iter().sorted() {
writeln!(w, " Active from epoch {}: Δ {}", epoch_start, delta)
.unwrap();
delta = apply_slashes(slashes, delta, *epoch_start, None, Some(w));
Expand Down Expand Up @@ -1653,25 +1653,56 @@ pub async fn get_proposal_offline_votes(
let bonds_iter =
query_storage_prefix::<pos::Bonds>(client.clone(), key).await;
if let Some(bonds) = bonds_iter {
for (key, epoched_amount) in bonds {
let bond = epoched_amount
.get(proposal.tally_epoch)
.expect("Delegation bond should be definied.");
for (key, epoched_bonds) in bonds {
// Look-up slashes for the validator in this key and
// apply them if any
let validator = pos::get_validator_address_from_bond(&key)
.expect(
"Delegation key should contain validator address.",
);
let slashes_key = pos::validator_slashes_key(&validator);
let slashes = query_storage_value::<pos::Slashes>(
client,
&slashes_key,
)
.await
.unwrap_or_default();
let mut delegated_amount: token::Amount = 0.into();
let epoch = namada::ledger::pos::types::Epoch::from(
proposal.tally_epoch.0,
);
let amount = *bond
.deltas
.get(&epoch)
.expect("Delegation amount should be definied.");
let validator_address =
pos::get_validator_address_from_bond(&key).expect(
"Delegation key should contain validator address.",
let bond = epoched_bonds
.get(epoch)
.expect("Delegation bond should be defined.");
let mut to_deduct = bond.neg_deltas;
for (start_epoch, &(mut delta)) in
bond.pos_deltas.iter().sorted()
{
// deduct bond's neg_deltas
if to_deduct > delta {
to_deduct -= delta;
// If the whole bond was deducted, continue to
// the next one
continue;
} else {
delta -= to_deduct;
to_deduct = token::Amount::default();
}

delta = apply_slashes(
&slashes,
delta,
*start_epoch,
None,
None,
);
delegated_amount += delta;
}

if proposal_vote.vote.is_yay() {
yay_delegators.insert(validator_address, amount);
yay_delegators.insert(validator, delegated_amount);
} else {
nay_delegators.insert(validator_address, amount);
nay_delegators.insert(validator, delegated_amount);
}
}
}
Expand Down Expand Up @@ -1746,7 +1777,21 @@ pub async fn get_bond_amount_at(
Some(epoched_bonds) => {
let mut delegated_amount: token::Amount = 0.into();
for bond in epoched_bonds.iter() {
for (epoch_start, &(mut delta)) in bond.deltas.iter().sorted() {
let mut to_deduct = bond.neg_deltas;
for (epoch_start, &(mut delta)) in
bond.pos_deltas.iter().sorted()
{
// deduct bond's neg_deltas
if to_deduct > delta {
to_deduct -= delta;
// If the whole bond was deducted, continue to
// the next one
continue;
} else {
delta -= to_deduct;
to_deduct = token::Amount::default();
}

delta = apply_slashes(
&slashes,
delta,
Expand Down
65 changes: 61 additions & 4 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;
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 Expand Up @@ -890,7 +947,7 @@ pub async fn submit_unbond(ctx: Context, args: args::Unbond) {
Some(bonds) => {
let mut bond_amount: token::Amount = 0.into();
for bond in bonds.iter() {
for delta in bond.deltas.values() {
for delta in bond.pos_deltas.values() {
bond_amount += *delta;
}
}
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
Loading