Skip to content

Commit

Permalink
Merge af72d37 into a73362d
Browse files Browse the repository at this point in the history
  • Loading branch information
mzabaluev authored Sep 11, 2023
2 parents a73362d + af72d37 commit fc5f777
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 20 deletions.
1 change: 0 additions & 1 deletion proto/src/prost/v0_34/tendermint.crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ pub struct ProofOps {
pub ops: ::prost::alloc::vec::Vec<ProofOp>,
}
/// PublicKey defines the keys available for use with Validators
#[derive(::serde::Deserialize, ::serde::Serialize)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PublicKey {
Expand Down
3 changes: 2 additions & 1 deletion proto/src/prost/v0_34/tendermint.types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ pub struct ValidatorSet {
#[prost(message, optional, tag = "2")]
pub proposer: ::core::option::Option<Validator>,
#[prost(int64, tag = "3")]
#[serde(skip)]
#[serde(with = "crate::serializers::from_str", default)]
#[serde(skip_serializing)]
pub total_voting_power: i64,
}
#[derive(::serde::Deserialize, ::serde::Serialize)]
Expand Down
1 change: 0 additions & 1 deletion proto/src/prost/v0_37/tendermint.crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ pub struct ProofOps {
pub ops: ::prost::alloc::vec::Vec<ProofOp>,
}
/// PublicKey defines the keys available for use with Validators
#[derive(::serde::Deserialize, ::serde::Serialize)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PublicKey {
Expand Down
3 changes: 2 additions & 1 deletion proto/src/prost/v0_37/tendermint.types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ pub struct ValidatorSet {
#[prost(message, optional, tag = "2")]
pub proposer: ::core::option::Option<Validator>,
#[prost(int64, tag = "3")]
#[serde(skip)]
#[serde(with = "crate::serializers::from_str", default)]
#[serde(skip_serializing)]
pub total_voting_power: i64,
}
#[derive(::serde::Deserialize, ::serde::Serialize)]
Expand Down
1 change: 0 additions & 1 deletion proto/src/prost/v0_38/tendermint.crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ pub struct ProofOps {
pub ops: ::prost::alloc::vec::Vec<ProofOp>,
}
/// PublicKey defines the keys available for use with Validators
#[derive(::serde::Deserialize, ::serde::Serialize)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PublicKey {
Expand Down
3 changes: 2 additions & 1 deletion proto/src/prost/v0_38/tendermint.types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ pub struct ValidatorSet {
#[prost(message, optional, tag = "2")]
pub proposer: ::core::option::Option<Validator>,
#[prost(int64, tag = "3")]
#[serde(skip)]
#[serde(with = "crate::serializers::from_str", default)]
#[serde(skip_serializing)]
pub total_voting_power: i64,
}
#[derive(::serde::Deserialize, ::serde::Serialize)]
Expand Down
2 changes: 2 additions & 0 deletions proto/src/serializers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,5 @@ pub mod part_set_header_total;
pub mod time_duration;
pub mod timestamp;
pub mod txs;

mod public_key;
71 changes: 71 additions & 0 deletions proto/src/serializers/public_key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
mod v0_34 {
use crate::v0_34::crypto::{public_key, PublicKey};
use serde::{Deserialize, Deserializer, Serialize, Serializer};

impl<'de> Deserialize<'de> for PublicKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let sum = Option::<public_key::Sum>::deserialize(deserializer)?;
Ok(Self { sum })
}
}

impl Serialize for PublicKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.sum.serialize(serializer)
}
}
}

mod v0_37 {
use crate::v0_37::crypto::{public_key, PublicKey};
use serde::{Deserialize, Deserializer, Serialize, Serializer};

impl<'de> Deserialize<'de> for PublicKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let sum = Option::<public_key::Sum>::deserialize(deserializer)?;
Ok(Self { sum })
}
}

impl Serialize for PublicKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.sum.serialize(serializer)
}
}
}

mod v0_38 {
use crate::v0_38::crypto::{public_key, PublicKey};
use serde::{Deserialize, Deserializer, Serialize, Serializer};

impl<'de> Deserialize<'de> for PublicKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let sum = Option::<public_key::Sum>::deserialize(deserializer)?;
Ok(Self { sum })
}
}

impl Serialize for PublicKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.sum.serialize(serializer)
}
}
}
8 changes: 7 additions & 1 deletion tendermint/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ define_error! {

InvalidKey
{ detail: String }
|e| { format_args!("invalid key: {e}") },
|e| { format_args!("invalid key: {}", e.detail) },

Length
|_| { format_args!("length error") },
Expand Down Expand Up @@ -229,6 +229,12 @@ define_error! {
NegativeProofIndex
[ DisplayOnly<TryFromIntError> ]
|_| { "negative item index in proof" },

TotalVotingPowerMismatch
|_| { "total voting power in validator set does not match the sum of participants' powers" },

TotalVotingPowerOverflow
|_| { "total voting power in validator set exceeds the allowed maximum" },
}
}

Expand Down
46 changes: 36 additions & 10 deletions tendermint/src/validator.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! Tendermint validators
use serde::{Deserialize, Serialize};
use tendermint_proto::v0_37::types::SimpleValidator as RawSimpleValidator;
use tendermint_proto::v0_38::types::{
SimpleValidator as RawSimpleValidator, ValidatorSet as RawValidatorSet,
};
use tendermint_proto::Protobuf;

use crate::{
Expand All @@ -17,30 +19,55 @@ use crate::{

/// Validator set contains a vector of validators
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(try_from = "RawValidatorSet")]
pub struct Set {
validators: Vec<Info>,
proposer: Option<Info>,
total_voting_power: vote::Power,
}

impl Set {
pub const MAX_TOTAL_VOTING_POWER: u64 = (i64::MAX / 8) as u64;

/// Constructor
pub fn new(mut validators: Vec<Info>, proposer: Option<Info>) -> Set {
Self::sort_validators(&mut validators);
pub fn new(validators: Vec<Info>, proposer: Option<Info>) -> Set {
Self::try_from_parts(validators, proposer, 0).unwrap()
}

fn try_from_parts(
mut validators: Vec<Info>,
proposer: Option<Info>,
unvalidated_total_voting_power: i64,
) -> Result<Set, Error> {
// Compute the total voting power
let total_voting_power = validators
.iter()
.map(|v| v.power.value())
.sum::<u64>()
.try_into()
.unwrap();
.fold(0u64, |acc, v| acc.saturating_add(v));

if total_voting_power > Self::MAX_TOTAL_VOTING_POWER {
return Err(Error::total_voting_power_overflow());
}

// The conversion cannot fail as we have validated against a smaller limit.
let total_voting_power: vote::Power = total_voting_power.try_into().unwrap();

Set {
// If the given total voting power is not the default value,
// validate it against the sum of voting powers of the participants.
if unvalidated_total_voting_power != 0 {
let given_val: vote::Power = unvalidated_total_voting_power.try_into()?;
if given_val != total_voting_power {
return Err(Error::total_voting_power_mismatch());
}
}

Self::sort_validators(&mut validators);

Ok(Set {
validators,
proposer,
total_voting_power,
}
})
}

/// Convenience constructor for cases where there is no proposer
Expand Down Expand Up @@ -266,9 +293,8 @@ tendermint_pb_modules! {
.collect::<Result<Vec<_>, _>>()?;

let proposer = value.proposer.map(TryInto::try_into).transpose()?;
let validator_set = Self::new(validators, proposer);

Ok(validator_set)
Self::try_from_parts(validators, proposer, value.total_voting_power)
}
}

Expand Down
13 changes: 10 additions & 3 deletions tools/proto-compiler/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const BASE64STRING: &str = r#"#[serde(with = "crate::serializers::bytes::base64s
const VEC_BASE64STRING: &str = r#"#[serde(with = "crate::serializers::bytes::vec_base64string")]"#;
const OPTIONAL: &str = r#"#[serde(with = "crate::serializers::optional")]"#;
const BYTES_SKIP_IF_EMPTY: &str = r#"#[serde(skip_serializing_if = "bytes::Bytes::is_empty")]"#;
const SKIP: &str = "#[serde(skip)]";
const SKIP_SERIALIZING: &str = "#[serde(skip_serializing)]";
const RENAME_ALL_PASCALCASE: &str = r#"#[serde(rename_all = "PascalCase")]"#;
const NULLABLEVECARRAY: &str = r#"#[serde(with = "crate::serializers::txs")]"#;
const NULLABLE: &str = r#"#[serde(with = "crate::serializers::nullable")]"#;
Expand Down Expand Up @@ -98,7 +98,7 @@ pub static CUSTOM_TYPE_ATTRIBUTES: &[(&str, &str)] = &[
(".tendermint.types.Commit", SERIALIZED),
(".tendermint.types.CommitSig", SERIALIZED),
(".tendermint.types.ValidatorSet", SERIALIZED),
(".tendermint.crypto.PublicKey", SERIALIZED),
(".tendermint.crypto.PublicKey.sum", SERIALIZED),
(".tendermint.crypto.PublicKey.sum", TYPE_TAG),
(".tendermint.abci.ResponseInfo", SERIALIZED),
(".tendermint.types.CanonicalBlockID", SERIALIZED),
Expand Down Expand Up @@ -199,7 +199,14 @@ pub static CUSTOM_FIELD_ATTRIBUTES: &[(&str, &str)] = &[
".tendermint.types.Validator.proposer_priority",
QUOTED_WITH_DEFAULT,
), // Default is for /genesis deserialization
(".tendermint.types.ValidatorSet.total_voting_power", SKIP),
(
".tendermint.types.ValidatorSet.total_voting_power",
QUOTED_WITH_DEFAULT,
),
(
".tendermint.types.ValidatorSet.total_voting_power",
SKIP_SERIALIZING,
),
(".tendermint.types.BlockMeta.block_size", QUOTED),
(".tendermint.types.BlockMeta.num_txs", QUOTED),
(".tendermint.crypto.PublicKey.sum.ed25519", RENAME_EDPUBKEY),
Expand Down

0 comments on commit fc5f777

Please sign in to comment.