Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
commit 020cad8
Author: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
Date:   Fri Sep 24 15:49:21 2021 +0100

    Feature/rust rewarding (#750)

    * Calculating gas fees

    * Ability to set custom fees

    * Added extra test

    * Removed commented code

    * Moved all msg types to common contract crate

    * Temporarily disabling get_tx method

    * Finishing up nymd client API

    * Comment fix

    * Remaining fee values

    * Some cleanup

    * Removed needless borrow

    * Fixed imports in contract tests

    * Moved error types around

    * New ValidatorClient

    * Experiment with new type of defaults

    * Removed dead module

    * Dealt with unwrap

    * Migrated mixnode to use new validator client

    * Migrated gateway to use new validator client

    * Mixnode and gateway adjustments

    * More exported defaults

    * Clients using new validator client

    * Fixed mixnode upgrade

    * Moved default values to a new crate

    * Changed behaviour of validator client features

    * Migrated basic functions of validator api

    * Updated config + fixed startup

    * Fixed wasm client build

    * Integration with the explorer api

    * Removed tokio dev dependency

    * Needless borrow

    * Fixex wasm client build

    * Fixed tauri client build

    * Needless borrows

    * New tables for rewarding

    * Updated cosmos-sdk version

    * Removed reward-specific node status routes

    * New rewarding-specific config entries

    * Additional network defaults

    * Initial periodic rewards from validator api

    * Replaced print with log

    * Filtering nodes with uptime > 0

    * Additional failure logging statements

    * Fixed operation ordering

    * Adjusted next rewarding epoch determination

    * Modified rewarding behaviour to keep track of rewarding in progress

    * Improved error message on config load failure

    * Additional log statement

    * Adjusted rewarding gas limit calculation

    * Made naming slightly more consistent

    * Fixed incorrect parentheses placement

    * Fixed fee calculation

    * Cargo fmt

    * Removed failed merge artifacts

    * Introduced comment for any future reward modification

    * typos

    * Helper functions for the future

    * Making @mfahampshire 's life easier

    * Redesigned epoch + rewarding skipped epochs (if possible)

    * Removed old merge artifacts

    * Naming consistency

    * Constraining arguments

    * Removed unnecessary if branch

    * Ignore monitor check for current epoch

    * Additional checks for current epoch data

    * Monitor threshold check

    * cargo fmt

    * Fixed post-merge issues in transactions.rs

commit 5dfaff6
Author: Drazen Urch <drazen@urch.eu>
Date:   Tue Sep 21 10:59:17 2021 +0200

    Update hmac and blake3 (#673)

    * Update hmac and blake3

    * Remain paranoid for `0.*` crates

    * Most paranoid versions :)

    * Updated aes and using published version of blake3

    Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>

commit 5b03982
Author: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
Date:   Mon Sep 20 10:40:03 2021 +0100

    Replaced unwrap_or_else with unwrap_or_default (#780)

commit 8f6856d
Author: Drazen Urch <drazen@urch.eu>
Date:   Mon Sep 20 11:15:06 2021 +0200

    Make fee helpers public (#777)

    Co-authored-by: Drazen Urch <durch@users.noreply.guthub.com>
  • Loading branch information
Drazen Urch committed Sep 27, 2021
1 parent 80664b9 commit bf502f6
Show file tree
Hide file tree
Showing 45 changed files with 2,695 additions and 551 deletions.
218 changes: 59 additions & 159 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion clients/client-core/src/client/reply_key_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub enum ReplyKeyStorageError {
/// Permanent storage for keys in all sent [`ReplySURB`]
///
/// Each sent out [`ReplySURB`] has a new key associated with it that is going to be used for
/// payload encryption. In order to decrypt whatever reply we receive, we need to know which
/// payload encryption. In order to -decrypt whatever reply we receive, we need to know which
/// key to use for that purpose. We do it based on received `H(t)` which has to be included
/// with each reply.
/// Moreover, there is no restriction when the [`ReplySURB`] might get used so we need to
Expand Down
4 changes: 4 additions & 0 deletions common/client-libs/validator-client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ impl<C> Client<C> {
self.mixnet_contract_address = Some(mixnet_contract_address)
}

pub fn get_mixnet_contract_address(&self) -> Option<cosmrs::AccountId> {
self.mixnet_contract_address.clone()
}

pub async fn get_cached_mixnodes(&self) -> Result<Vec<MixNodeBond>, ValidatorClientError> {
Ok(self.validator_api.get_mixnodes().await?)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use cosmrs::rpc::{Error as TendermintRpcError, HttpClient, HttpClientUrl, Simple
use cosmrs::staking::{MsgDelegate, MsgUndelegate};
use cosmrs::tx::{Fee, Msg, MsgType, SignDoc, SignerInfo};
use cosmrs::{cosmwasm, rpc, tx, AccountId, Coin};
use log::debug;
use serde::Serialize;
use sha2::Digest;
use sha2::Sha256;
Expand Down Expand Up @@ -256,6 +257,48 @@ pub trait SigningCosmWasmClient: CosmWasmClient {
})
}

async fn execute_multiple<I, M>(
&self,
sender_address: &AccountId,
contract_address: &AccountId,
msgs: I,
fee: Fee,
memo: impl Into<String> + Send + 'static,
) -> Result<ExecuteResult, NymdError>
where
I: IntoIterator<Item = (M, Vec<Coin>)> + Send,
M: Serialize,
{
let messages = msgs
.into_iter()
.map(|(msg, funds)| {
cosmwasm::MsgExecuteContract {
sender: sender_address.clone(),
contract: contract_address.clone(),
msg: serde_json::to_vec(&msg)?,
funds,
}
.to_msg()
.map_err(|_| NymdError::SerializationError("MsgExecuteContract".to_owned()))
})
.collect::<Result<_, _>>()?;

let tx_res = self
.sign_and_broadcast_commit(sender_address, messages, fee, memo)
.await?
.check_response()?;

debug!(
"gas wanted: {:?}, gas used: {:?}",
tx_res.deliver_tx.gas_wanted, tx_res.deliver_tx.gas_used
);

Ok(ExecuteResult {
logs: parse_raw_logs(tx_res.deliver_tx.log)?,
transaction_hash: tx_res.hash,
})
}

async fn send_tokens(
&self,
sender_address: &AccountId,
Expand Down
17 changes: 7 additions & 10 deletions common/client-libs/validator-client/src/nymd/fee_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
use crate::nymd::GasPrice;
use cosmrs::tx::{Fee, Gas};
use cosmrs::Coin;
use cosmwasm_std::Uint128;
use serde::{Deserialize, Serialize};
use std::fmt;
use ts_rs::TS;
Expand All @@ -31,13 +30,7 @@ pub enum Operation {
}

pub(crate) fn calculate_fee(gas_price: &GasPrice, gas_limit: Gas) -> Coin {
let limit_uint128 = Uint128::from(gas_limit.value());
let amount = gas_price.amount * limit_uint128;
assert!(amount.u128() <= u64::MAX as u128);
Coin {
denom: gas_price.denom.clone(),
amount: (amount.u128() as u64).into(),
}
gas_price * gas_limit
}

impl fmt::Display for Operation {
Expand Down Expand Up @@ -85,16 +78,20 @@ impl Operation {
}
}

pub(crate) fn determine_fee(&self, gas_price: &GasPrice, gas_limit: Option<Gas>) -> Fee {
pub(crate) fn determine_custom_fee(gas_price: &GasPrice, gas_limit: Gas) -> Fee {
// we need to know 2 of the following 3 parameters (the third one is being implicit) in order to construct Fee:
// (source: https://docs.cosmos.network/v0.42/basics/gas-fees.html)
// - gas price
// - gas limit
// - fees
let gas_limit = gas_limit.unwrap_or_else(|| self.default_gas_limit());
let fee = calculate_fee(gas_price, gas_limit);
Fee::from_amount_and_gas(fee, gas_limit)
}

pub(crate) fn determine_fee(&self, gas_price: &GasPrice, gas_limit: Option<Gas>) -> Fee {
let gas_limit = gas_limit.unwrap_or_else(|| self.default_gas_limit());
Self::determine_custom_fee(gas_price, gas_limit)
}
}

#[cfg(test)]
Expand Down
47 changes: 45 additions & 2 deletions common/client-libs/validator-client/src/nymd/gas_price.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

use crate::nymd::error::NymdError;
use config::defaults;
use cosmrs::Denom;
use cosmwasm_std::Decimal;
use cosmrs::tx::Gas;
use cosmrs::{Coin, Denom};
use cosmwasm_std::{Decimal, Fraction, Uint128};
use std::ops::Mul;
use std::str::FromStr;

/// A gas price, i.e. the price of a single unit of gas. This is typically a fraction of
Expand All @@ -18,6 +20,36 @@ pub struct GasPrice {
pub denom: Denom,
}

impl<'a> Mul<Gas> for &'a GasPrice {
type Output = Coin;

fn mul(self, gas_limit: Gas) -> Self::Output {
let limit_uint128 = Uint128::from(gas_limit.value());
let mut amount = self.amount * limit_uint128;

let gas_price_numerator = self.amount.numerator();
let gas_price_denominator = self.amount.denominator();

// gas price is a fraction of the smallest fee token unit, so we must ensure that
// for any multiplication, we have rounded up
//
// I don't really like the this solution as it has a theoretical chance of
// overflowing (internally cosmwasm uses U256 to avoid that)
// however, realistically that is impossible to happen as the resultant value
// would have to be way higher than our token limit of 10^15 (1 billion of tokens * 1 million for denomination)
// and max value of u128 is approximately 10^38
if limit_uint128.u128() * gas_price_numerator > amount.u128() * gas_price_denominator {
amount += Uint128::new(1);
}

assert!(amount.u128() <= u64::MAX as u128);
Coin {
denom: self.denom.clone(),
amount: (amount.u128() as u64).into(),
}
}
}

impl FromStr for GasPrice {
type Err = NymdError;

Expand Down Expand Up @@ -78,4 +110,15 @@ mod tests {
assert!("0.025 upunk".parse::<GasPrice>().is_err());
assert!("0.025UPUNK".parse::<GasPrice>().is_err());
}

#[test]
fn gas_limit_multiplication() {
// real world example that caused an issue when the result was rounded down
let gas_price: GasPrice = "0.025upunk".parse().unwrap();
let gas_limit: Gas = 157500u64.into();

let fee = &gas_price * gas_limit;
// the failing behaviour was result value of 3937
assert_eq!(fee.amount, 3938u64.into());
}
}
31 changes: 30 additions & 1 deletion common/client-libs/validator-client/src/nymd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use crate::nymd::fee_helpers::Operation;
use crate::nymd::wallet::DirectSecp256k1HdWallet;
use cosmrs::rpc::endpoint::broadcast;
use cosmrs::rpc::{Error as TendermintRpcError, HttpClientUrl};
use cosmrs::tx::{Fee, Gas};

use cosmwasm_std::Coin;
use mixnet_contract::{
Expand All @@ -29,6 +28,8 @@ pub use crate::nymd::cosmwasm_client::client::CosmWasmClient;
pub use crate::nymd::cosmwasm_client::signing_client::SigningCosmWasmClient;
pub use crate::nymd::gas_price::GasPrice;
pub use cosmrs::rpc::HttpClient as QueryNymdClient;
pub use cosmrs::tendermint::Time as TendermintTime;
pub use cosmrs::tx::{Fee, Gas};
pub use cosmrs::Coin as CosmosCoin;
pub use cosmrs::{AccountId, Denom};
pub use signing_client::Client as SigningNymdClient;
Expand Down Expand Up @@ -159,6 +160,17 @@ impl<C> NymdClient<C> {
operation.determine_fee(&self.gas_price, gas_limit)
}

pub fn calculate_custom_fee(&self, gas_limit: impl Into<Gas>) -> Fee {
Operation::determine_custom_fee(&self.gas_price, gas_limit.into())
}

pub async fn get_current_block_timestamp(&self) -> Result<TendermintTime, NymdError>
where
C: CosmWasmClient + Sync,
{
Ok(self.client.get_block(None).await?.block.header.time)
}

pub async fn get_balance(&self, address: &AccountId) -> Result<Option<CosmosCoin>, NymdError>
where
C: CosmWasmClient + Sync,
Expand Down Expand Up @@ -400,6 +412,23 @@ impl<C> NymdClient<C> {
.await
}

pub async fn execute_multiple<I, M>(
&self,
contract_address: &AccountId,
msgs: I,
fee: Fee,
memo: impl Into<String> + Send + 'static,
) -> Result<ExecuteResult, NymdError>
where
C: SigningCosmWasmClient + Sync,
I: IntoIterator<Item = (M, Vec<CosmosCoin>)> + Send,
M: Serialize,
{
self.client
.execute_multiple(self.address(), contract_address, msgs, fee, memo)
.await
}

pub async fn upload(
&self,
wasm_code: Vec<u8>,
Expand Down
15 changes: 7 additions & 8 deletions common/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
aes-ctr = "0.6.0"
bs58 = "0.4"
blake3 = "0.3"
#blake3 = { version = "0.3", features = ["traits-preview"]}
digest = "0.9"
aes = { version = "0.7.4", features = ["ctr"] }
bs58 = "0.4.0"
blake3 = { version = "1.0.0", features = ["traits-preview"] }
digest = "0.9.0"
generic-array = "0.14"
hkdf = "0.10"
hmac = "0.8"
cipher = "0.2"
hkdf = "0.11.0"
hmac = "0.11.0"
cipher = "0.3.0"
x25519-dalek = "1.1"
ed25519-dalek = "1.0"
log = "0.4"
Expand Down
4 changes: 2 additions & 2 deletions common/crypto/src/hmac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ where
D::OutputSize: ArrayLength<u8>,
{
let mut hmac =
Hmac::<D>::new_varkey(key).expect("HMAC should be able to take key of any size!");
Hmac::<D>::new_from_slice(key).expect("HMAC should be able to take key of any size!");
hmac.update(data);
hmac.finalize()
}
Expand All @@ -31,7 +31,7 @@ where
D::OutputSize: ArrayLength<u8>,
{
let mut hmac =
Hmac::<D>::new_varkey(key).expect("HMAC should be able to take key of any size!");
Hmac::<D>::new_from_slice(key).expect("HMAC should be able to take key of any size!");
hmac.update(data);
// note, under the hood ct_eq is called
hmac.verify(tag).is_ok()
Expand Down
2 changes: 1 addition & 1 deletion common/crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub use generic_array;

// with the below my idea was to try to introduce having a single place of importing all hashing, encryption,
// etc. algorithms and import them elsewhere as needed via common/crypto
pub use aes_ctr;
pub use aes;
pub use blake3;

// TODO: this function uses all three modules: asymmetric crypto, symmetric crypto and derives key...,
Expand Down
14 changes: 7 additions & 7 deletions common/crypto/src/shared_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use crate::asymmetric::encryption;
use crate::hkdf;
use cipher::stream::{Key, NewStreamCipher, SyncStreamCipher};
use cipher::{CipherKey, NewCipher, StreamCipher};
use digest::{BlockInput, FixedOutput, Reset, Update};
use generic_array::{typenum::Unsigned, ArrayLength};
use rand::{CryptoRng, RngCore};
Expand All @@ -13,9 +13,9 @@ use rand::{CryptoRng, RngCore};
pub fn new_ephemeral_shared_key<C, D, R>(
rng: &mut R,
remote_key: &encryption::PublicKey,
) -> (encryption::KeyPair, Key<C>)
) -> (encryption::KeyPair, CipherKey<C>)
where
C: SyncStreamCipher + NewStreamCipher,
C: StreamCipher + NewCipher,
D: Update + BlockInput + FixedOutput + Reset + Default + Clone,
D::BlockSize: ArrayLength<u8>,
D::OutputSize: ArrayLength<u8>,
Expand All @@ -31,7 +31,7 @@ where
.expect("somehow too long okm was provided");

let derived_shared_key =
Key::<C>::from_exact_iter(okm).expect("okm was expanded to incorrect length!");
CipherKey::<C>::from_exact_iter(okm).expect("okm was expanded to incorrect length!");

(ephemeral_keypair, derived_shared_key)
}
Expand All @@ -40,9 +40,9 @@ where
pub fn recompute_shared_key<C, D>(
remote_key: &encryption::PublicKey,
local_key: &encryption::PrivateKey,
) -> Key<C>
) -> CipherKey<C>
where
C: SyncStreamCipher + NewStreamCipher,
C: StreamCipher + NewCipher,
D: Update + BlockInput + FixedOutput + Reset + Default + Clone,
D::BlockSize: ArrayLength<u8>,
D::OutputSize: ArrayLength<u8>,
Expand All @@ -53,5 +53,5 @@ where
let okm = hkdf::extract_then_expand::<D>(None, &dh_result, None, C::KeySize::to_usize())
.expect("somehow too long okm was provided");

Key::<C>::from_exact_iter(okm).expect("okm was expanded to incorrect length!")
CipherKey::<C>::from_exact_iter(okm).expect("okm was expanded to incorrect length!")
}
Loading

0 comments on commit bf502f6

Please sign in to comment.