Skip to content

Commit

Permalink
Merge branch 'tomas/fix-validator-raw-hash' (#326)
Browse files Browse the repository at this point in the history
- Updated tx_bond, tx_unbond and tx_withdraw and their tests to the new
  tx API

* tomas/fix-validator-raw-hash:
  update wasm checksums
  pos: update validator raw hash validation
  changelog: add #326
  client/utils: switch off validator's p2p addr strict mode in localhost
  test/e2e: add test for double signing slashing
  shell: fix slashing log msg
  ledger/shell: fix validator look-up from tm raw hash
  tests/PoS: fix the validator's raw hash to correspond to consensus key
  PoS: fix the validator's raw hash to correspond to consensus key
  tendermint: fix address written to TM to correspond to consensus key
  • Loading branch information
tzemanovic committed Aug 24, 2022
2 parents b6e235d + 4b8d423 commit 98eac22
Show file tree
Hide file tree
Showing 25 changed files with 443 additions and 232 deletions.
2 changes: 2 additions & 0 deletions .changelog/unreleased/bug-fixes/326-fix-validator-raw-hash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Fixed validator raw hash corresponding to validator address in Tendermint
([#326](https://github.com/anoma/namada/pull/326))
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.

8 changes: 2 additions & 6 deletions apps/src/lib/client/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,15 +331,11 @@ pub async fn submit_init_validator(
};
// add validator address and keys to the wallet
ctx.wallet
.add_validator_data(validator_address.clone(), validator_keys);
.add_validator_data(validator_address, validator_keys);
ctx.wallet.save().unwrap_or_else(|err| eprintln!("{}", err));

let tendermint_home = ctx.config.ledger.tendermint_dir();
tendermint_node::write_validator_key(
&tendermint_home,
&validator_address,
&consensus_key,
);
tendermint_node::write_validator_key(&tendermint_home, &consensus_key);
tendermint_node::write_validator_state(tendermint_home);

println!();
Expand Down
11 changes: 4 additions & 7 deletions apps/src/lib/client/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,6 @@ pub async fn join_network(
// Write consensus key to tendermint home
tendermint_node::write_validator_key(
&tm_home_dir,
&address,
&*pre_genesis_wallet.consensus_key,
);

Expand Down Expand Up @@ -516,11 +515,7 @@ pub fn init_network(
wallet.gen_key(Some(alias), unsafe_dont_encrypt);

// Write consensus key for Tendermint
tendermint_node::write_validator_key(
&tm_home_dir,
&address,
&keypair,
);
tendermint_node::write_validator_key(&tm_home_dir, &keypair);

keypair.ref_to()
});
Expand Down Expand Up @@ -861,6 +856,7 @@ pub fn init_network(
consensus_timeout_commit;
config.ledger.tendermint.p2p_allow_duplicate_ip =
allow_duplicate_ip;
config.ledger.tendermint.p2p_addr_book_strict = !localhost;
// Clear the net address from the config and use it to set ports
let net_address = validator_config.net_address.take().unwrap();
let first_port = SocketAddr::from_str(&net_address).unwrap().port();
Expand Down Expand Up @@ -1134,7 +1130,8 @@ fn network_configs_url_prefix(chain_id: &ChainId) -> String {
})
}

fn write_tendermint_node_key(
/// Write the node key into tendermint config dir.
pub fn write_tendermint_node_key(
tm_home_dir: &Path,
node_sk: ed25519::SecretKey,
) -> ed25519::PublicKey {
Expand Down
19 changes: 4 additions & 15 deletions apps/src/lib/node/ledger/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ where
let pos_params = self.storage.read_pos_params();
let current_epoch = self.storage.block.epoch;
for evidence in byzantine_validators {
tracing::info!("Processing evidence {evidence:?}.");
let evidence_height = match u64::try_from(evidence.height) {
Ok(height) => height,
Err(err) => {
Expand Down Expand Up @@ -442,19 +443,7 @@ where
}
};
let validator_raw_hash = match evidence.validator {
Some(validator) => {
match String::from_utf8(validator.address) {
Ok(raw_hash) => raw_hash,
Err(err) => {
tracing::error!(
"Evidence failed to decode validator \
address from utf-8 with {}",
err
);
continue;
}
}
}
Some(validator) => tm_raw_hash_to_string(validator.address),
None => {
tracing::error!(
"Evidence without a validator {:#?}",
Expand All @@ -478,9 +467,9 @@ where
};
tracing::info!(
"Slashing {} for {} in epoch {}, block height {}",
evidence_epoch,
slash_type,
validator,
slash_type,
evidence_epoch,
evidence_height
);
if let Err(err) = self.storage.slash(
Expand Down
29 changes: 7 additions & 22 deletions apps/src/lib/node/ledger/tendermint_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::process::Stdio;
use std::str::FromStr;

use borsh::BorshSerialize;
use namada::types::address::Address;
use namada::types::chain::ChainId;
use namada::types::key::*;
use namada::types::time::DateTimeUtc;
Expand Down Expand Up @@ -95,23 +94,10 @@ pub async fn run(

#[cfg(feature = "dev")]
{
let genesis = &crate::config::genesis::genesis();
let consensus_key = crate::wallet::defaults::validator_keypair();
// write the validator key file if it didn't already exist
if !has_validator_key {
write_validator_key_async(
&home_dir,
&genesis
.validators
.first()
.expect(
"There should be one genesis validator in \"dev\" mode",
)
.pos_data
.address,
&consensus_key,
)
.await;
write_validator_key_async(&home_dir, &consensus_key).await;
}
}
write_tm_genesis(&home_dir, chain_id, genesis_time, &config).await;
Expand Down Expand Up @@ -199,16 +185,17 @@ pub fn reset(tendermint_dir: impl AsRef<Path>) -> Result<()> {
/// Convert a common signing scheme validator key into JSON for
/// Tendermint
fn validator_key_to_json<SK: SecretKey>(
address: &Address,
sk: &SK,
) -> std::result::Result<serde_json::Value, ParseSecretKeyError> {
let address = address.raw_hash().unwrap();
ed25519::SecretKey::try_from_sk(sk).map(|sk| {
let pk: ed25519::PublicKey = sk.ref_to();
let pk_common = common::PublicKey::try_from_pk(&pk)
.expect("must be able to convert ed25519 to common");
let raw_hash = tm_consensus_key_raw_hash(&pk_common);
let ck_arr =
[sk.try_to_vec().unwrap(), pk.try_to_vec().unwrap()].concat();
json!({
"address": address,
"address": raw_hash,
"pub_key": {
"type": "tendermint/PubKeyEd25519",
"value": base64::encode(pk.try_to_vec().unwrap()),
Expand All @@ -224,7 +211,6 @@ fn validator_key_to_json<SK: SecretKey>(
/// Initialize validator private key for Tendermint
pub async fn write_validator_key_async(
home_dir: impl AsRef<Path>,
address: &Address,
consensus_key: &common::SecretKey,
) {
let home_dir = home_dir.as_ref();
Expand All @@ -241,7 +227,7 @@ pub async fn write_validator_key_async(
.open(&path)
.await
.expect("Couldn't create private validator key file");
let key = validator_key_to_json(address, consensus_key).unwrap();
let key = validator_key_to_json(consensus_key).unwrap();
let data = serde_json::to_vec_pretty(&key)
.expect("Couldn't encode private validator key file");
file.write_all(&data[..])
Expand All @@ -252,7 +238,6 @@ pub async fn write_validator_key_async(
/// Initialize validator private key for Tendermint
pub fn write_validator_key(
home_dir: impl AsRef<Path>,
address: &Address,
consensus_key: &common::SecretKey,
) {
let home_dir = home_dir.as_ref();
Expand All @@ -267,7 +252,7 @@ pub fn write_validator_key(
.truncate(true)
.open(&path)
.expect("Couldn't create private validator key file");
let key = validator_key_to_json(address, consensus_key).unwrap();
let key = validator_key_to_json(consensus_key).unwrap();
serde_json::to_writer_pretty(file, &key)
.expect("Couldn't write private validator key file");
}
Expand Down
1 change: 1 addition & 0 deletions proof_of_stake/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ borsh = "0.9.1"
thiserror = "1.0.30"
# A fork with state machine testing
proptest = {git = "https://github.com/heliaxdev/proptest", branch = "tomas/sm", optional = true}
derivative = "2.2.0"

[dev-dependencies]
23 changes: 17 additions & 6 deletions proof_of_stake/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,11 @@ pub trait PosActions: PosReadOnly {
&mut self,
params: &PosParams,
) -> Result<(), Self::Error>;
/// Write PoS validator's raw hash its address.
/// Write PoS validator's raw hash of its consensus key.
fn write_validator_address_raw_hash(
&mut self,
address: &Self::Address,
consensus_key: &Self::PublicKey,
) -> Result<(), Self::Error>;
/// Write PoS validator's staking reward address, into which staking rewards
/// will be credited.
Expand Down Expand Up @@ -283,6 +284,7 @@ pub trait PosActions: PosReadOnly {
),
)?;
}
let consensus_key_clone = consensus_key.clone();
let BecomeValidatorData {
consensus_key,
state,
Expand All @@ -302,7 +304,7 @@ pub trait PosActions: PosReadOnly {
self.write_validator_consensus_key(address, consensus_key)?;
self.write_validator_state(address, state)?;
self.write_validator_set(validator_set)?;
self.write_validator_address_raw_hash(address)?;
self.write_validator_address_raw_hash(address, &consensus_key_clone)?;
self.write_validator_total_deltas(address, total_deltas)?;
self.write_validator_voting_power(address, voting_power)?;
Ok(())
Expand Down Expand Up @@ -583,7 +585,7 @@ pub trait PosBase {

/// Read PoS parameters.
fn read_pos_params(&self) -> PosParams;
/// Read PoS raw hash of validator's address.
/// Read PoS raw hash of validator's consensus key.
fn read_validator_address_raw_hash(
&self,
raw_hash: impl AsRef<str>,
Expand Down Expand Up @@ -618,8 +620,12 @@ pub trait PosBase {

/// Write PoS parameters.
fn write_pos_params(&mut self, params: &PosParams);
/// Write PoS validator's raw hash its address.
fn write_validator_address_raw_hash(&mut self, address: &Self::Address);
/// Write PoS validator's raw hash of its consensus key.
fn write_validator_address_raw_hash(
&mut self,
address: &Self::Address,
consensus_key: &Self::PublicKey,
);
/// Write PoS validator's staking reward address, into which staking rewards
/// will be credited.
fn write_validator_staking_reward_address(
Expand Down Expand Up @@ -729,7 +735,12 @@ pub trait PosBase {
voting_power,
bond: (bond_id, bond),
} = res?;
self.write_validator_address_raw_hash(address);
self.write_validator_address_raw_hash(
address,
consensus_key
.get(current_epoch)
.expect("Consensus key must be set"),
);
self.write_validator_staking_reward_address(
address,
&staking_reward_address,
Expand Down
6 changes: 6 additions & 0 deletions proof_of_stake/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,12 @@ pub enum SlashType {
)]
pub struct BasisPoints(u64);

/// Derive Tendermint raw hash from the public key
pub trait PublicKeyTmRawHash {
/// Derive Tendermint raw hash from the public key
fn tm_raw_hash(&self) -> String;
}

impl VotingPower {
/// Convert token amount into a voting power.
pub fn from_tokens(tokens: impl Into<u64>, params: &PosParams) -> Self {
Expand Down
Loading

0 comments on commit 98eac22

Please sign in to comment.