Compare commits

...

6 Commits

Author SHA1 Message Date
Jędrzej Stuczyński f4492b4b13 Manual merge of #810 2021-10-11 10:55:03 +01:00
Jędrzej Stuczyński 5585a83e3e Unused import 2021-10-11 10:46:28 +01:00
Jędrzej Stuczyński 308af24881 Using default rocket build (that uses Rocket.toml) 2021-10-04 10:54:09 +01:00
Jędrzej Stuczyński 50d7fc73cb Loosened some argument restrictions for the sake of easier deployments 2021-09-30 15:13:08 +01:00
Jędrzej Stuczyński 01043d7940 Removed invalid field from validator-api config field 2021-09-30 15:00:45 +01:00
Jędrzej Stuczyński 2d1961b8be Removed use of coconut in validator-api and gateway 2021-09-28 10:55:14 +01:00
28 changed files with 794 additions and 629 deletions
Generated
-8
View File
@@ -3281,9 +3281,7 @@ version = "0.11.0"
dependencies = [ dependencies = [
"clap", "clap",
"client-core", "client-core",
"coconut-interface",
"config", "config",
"credentials",
"crypto", "crypto",
"dirs", "dirs",
"dotenv", "dotenv",
@@ -3336,9 +3334,7 @@ name = "nym-gateway"
version = "0.11.0" version = "0.11.0"
dependencies = [ dependencies = [
"clap", "clap",
"coconut-interface",
"config", "config",
"credentials",
"crypto", "crypto",
"dashmap", "dashmap",
"dirs", "dirs",
@@ -3424,9 +3420,7 @@ version = "0.11.0"
dependencies = [ dependencies = [
"clap", "clap",
"client-core", "client-core",
"coconut-interface",
"config", "config",
"credentials",
"crypto", "crypto",
"dirs", "dirs",
"dotenv", "dotenv",
@@ -3457,9 +3451,7 @@ version = "0.11.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
"coconut-interface",
"config", "config",
"credentials",
"crypto", "crypto",
"dirs", "dirs",
"dotenv", "dotenv",
-2
View File
@@ -31,8 +31,6 @@ tokio-tungstenite = "0.14" # websocket
## internal ## internal
client-core = { path = "../client-core" } client-core = { path = "../client-core" }
coconut-interface = { path = "../../common/coconut-interface" }
credentials = { path = "../../common/credentials" }
config = { path = "../../common/config" } config = { path = "../../common/config" }
crypto = { path = "../../common/crypto" } crypto = { path = "../../common/crypto" }
gateway-client = { path = "../../common/client-libs/gateway-client" } gateway-client = { path = "../../common/client-libs/gateway-client" }
-30
View File
@@ -22,9 +22,6 @@ use client_core::client::topology_control::{
TopologyAccessor, TopologyRefresher, TopologyRefresherConfig, TopologyAccessor, TopologyRefresher, TopologyRefresherConfig,
}; };
use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder; use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder;
use coconut_interface::Credential;
use credentials::bandwidth::prepare_for_spending;
use credentials::obtain_aggregate_verification_key;
use crypto::asymmetric::identity; use crypto::asymmetric::identity;
use futures::channel::mpsc; use futures::channel::mpsc;
use gateway_client::{ use gateway_client::{
@@ -166,30 +163,6 @@ impl NymClient {
.start(self.runtime.handle()) .start(self.runtime.handle())
} }
async fn prepare_credential(&self) -> Credential {
let verification_key = obtain_aggregate_verification_key(
&self.config.get_base().get_validator_api_endpoints(),
)
.await
.expect("could not obtain aggregate verification key of validators");
let bandwidth_credential = credentials::bandwidth::obtain_signature(
&self.key_manager.identity_keypair().public_key().to_bytes(),
&self.config.get_base().get_validator_api_endpoints(),
)
.await
.expect("could not obtain bandwidth credential");
// the above would presumably be loaded from a file
// the below would only be executed once we know where we want to spend it (i.e. which gateway and stuff)
prepare_for_spending(
&self.key_manager.identity_keypair().public_key().to_bytes(),
&bandwidth_credential,
&verification_key,
)
.expect("could not prepare out bandwidth credential for spending")
}
fn start_gateway_client( fn start_gateway_client(
&mut self, &mut self,
mixnet_message_sender: MixnetMessageSender, mixnet_message_sender: MixnetMessageSender,
@@ -208,8 +181,6 @@ impl NymClient {
.expect("provided gateway id is invalid!"); .expect("provided gateway id is invalid!");
self.runtime.block_on(async { self.runtime.block_on(async {
let coconut_credential = self.prepare_credential().await;
let mut gateway_client = GatewayClient::new( let mut gateway_client = GatewayClient::new(
gateway_address, gateway_address,
self.key_manager.identity_keypair(), self.key_manager.identity_keypair(),
@@ -218,7 +189,6 @@ impl NymClient {
mixnet_message_sender, mixnet_message_sender,
ack_sender, ack_sender,
self.config.get_base().get_gateway_response_timeout(), self.config.get_base().get_gateway_response_timeout(),
coconut_credential,
); );
gateway_client gateway_client
+2 -29
View File
@@ -6,10 +6,7 @@ use crate::commands::override_config;
use clap::{App, Arg, ArgMatches}; use clap::{App, Arg, ArgMatches};
use client_core::client::key_manager::KeyManager; use client_core::client::key_manager::KeyManager;
use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder; use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder;
use coconut_interface::Credential;
use config::NymConfig; use config::NymConfig;
use credentials::bandwidth::prepare_for_spending;
use credentials::obtain_aggregate_verification_key;
use crypto::asymmetric::{encryption, identity}; use crypto::asymmetric::{encryption, identity};
use gateway_client::GatewayClient; use gateway_client::GatewayClient;
use gateway_requests::registration::handshake::SharedKeys; use gateway_requests::registration::handshake::SharedKeys;
@@ -60,34 +57,15 @@ pub fn command_args<'a, 'b>() -> clap::App<'a, 'b> {
) )
} }
// this behaviour should definitely be changed, we shouldn't
// need to get bandwidth credential for registration
async fn prepare_temporary_credential(validators: &[Url], raw_identity: &[u8]) -> Credential {
let verification_key = obtain_aggregate_verification_key(validators)
.await
.expect("could not obtain aggregate verification key of validators");
let bandwidth_credential = credentials::bandwidth::obtain_signature(raw_identity, validators)
.await
.expect("could not obtain bandwidth credential");
prepare_for_spending(raw_identity, &bandwidth_credential, &verification_key)
.expect("could not prepare out bandwidth credential for spending")
}
async fn register_with_gateway( async fn register_with_gateway(
gateway: &gateway::Node, gateway: &gateway::Node,
our_identity: Arc<identity::KeyPair>, our_identity: Arc<identity::KeyPair>,
validator_urls: Vec<Url>,
) -> Arc<SharedKeys> { ) -> Arc<SharedKeys> {
let timeout = Duration::from_millis(1500); let timeout = Duration::from_millis(1500);
let coconut_credential =
prepare_temporary_credential(&validator_urls, &our_identity.public_key().to_bytes()).await;
let mut gateway_client = GatewayClient::new_init( let mut gateway_client = GatewayClient::new_init(
gateway.clients_address(), gateway.clients_address(),
gateway.identity_key, gateway.identity_key,
our_identity.clone(), our_identity.clone(),
coconut_credential,
timeout, timeout,
); );
gateway_client gateway_client
@@ -210,13 +188,8 @@ pub fn execute(matches: &ArgMatches) {
config config
.get_base_mut() .get_base_mut()
.with_gateway_id(gate_details.identity_key.to_base58_string()); .with_gateway_id(gate_details.identity_key.to_base58_string());
let validator_urls = config.get_base().get_validator_api_endpoints(); let shared_keys =
let shared_keys = register_with_gateway( register_with_gateway(&gate_details, key_manager.identity_keypair()).await;
&gate_details,
key_manager.identity_keypair(),
validator_urls,
)
.await;
(shared_keys, gate_details.clients_address()) (shared_keys, gate_details.clients_address())
}; };
-2
View File
@@ -24,8 +24,6 @@ url = "2.2"
# internal # internal
client-core = { path = "../client-core" } client-core = { path = "../client-core" }
coconut-interface = { path = "../../common/coconut-interface" }
credentials = { path = "../../common/credentials" }
config = { path = "../../common/config" } config = { path = "../../common/config" }
crypto = { path = "../../common/crypto" } crypto = { path = "../../common/crypto" }
gateway-client = { path = "../../common/client-libs/gateway-client" } gateway-client = { path = "../../common/client-libs/gateway-client" }
-30
View File
@@ -23,9 +23,6 @@ use client_core::client::topology_control::{
TopologyAccessor, TopologyRefresher, TopologyRefresherConfig, TopologyAccessor, TopologyRefresher, TopologyRefresherConfig,
}; };
use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder; use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder;
use coconut_interface::Credential;
use credentials::bandwidth::prepare_for_spending;
use credentials::obtain_aggregate_verification_key;
use crypto::asymmetric::identity; use crypto::asymmetric::identity;
use futures::channel::mpsc; use futures::channel::mpsc;
use gateway_client::{ use gateway_client::{
@@ -154,30 +151,6 @@ impl NymClient {
.start(self.runtime.handle()) .start(self.runtime.handle())
} }
async fn prepare_credential(&self) -> Credential {
let verification_key = obtain_aggregate_verification_key(
&self.config.get_base().get_validator_api_endpoints(),
)
.await
.expect("could not obtain aggregate verification key of validators");
let bandwidth_credential = credentials::bandwidth::obtain_signature(
&self.key_manager.identity_keypair().public_key().to_bytes(),
&self.config.get_base().get_validator_api_endpoints(),
)
.await
.expect("could not obtain bandwidth credential");
// the above would presumably be loaded from a file
// the below would only be executed once we know where we want to spend it (i.e. which gateway and stuff)
prepare_for_spending(
&self.key_manager.identity_keypair().public_key().to_bytes(),
&bandwidth_credential,
&verification_key,
)
.expect("could not prepare out bandwidth credential for spending")
}
fn start_gateway_client( fn start_gateway_client(
&mut self, &mut self,
mixnet_message_sender: MixnetMessageSender, mixnet_message_sender: MixnetMessageSender,
@@ -196,8 +169,6 @@ impl NymClient {
.expect("provided gateway id is invalid!"); .expect("provided gateway id is invalid!");
self.runtime.block_on(async { self.runtime.block_on(async {
let coconut_credential = self.prepare_credential().await;
let mut gateway_client = GatewayClient::new( let mut gateway_client = GatewayClient::new(
gateway_address, gateway_address,
self.key_manager.identity_keypair(), self.key_manager.identity_keypair(),
@@ -206,7 +177,6 @@ impl NymClient {
mixnet_message_sender, mixnet_message_sender,
ack_sender, ack_sender,
self.config.get_base().get_gateway_response_timeout(), self.config.get_base().get_gateway_response_timeout(),
coconut_credential,
); );
gateway_client gateway_client
+2 -29
View File
@@ -6,10 +6,7 @@ use crate::commands::override_config;
use clap::{App, Arg, ArgMatches}; use clap::{App, Arg, ArgMatches};
use client_core::client::key_manager::KeyManager; use client_core::client::key_manager::KeyManager;
use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder; use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder;
use coconut_interface::Credential;
use config::NymConfig; use config::NymConfig;
use credentials::bandwidth::prepare_for_spending;
use credentials::obtain_aggregate_verification_key;
use crypto::asymmetric::{encryption, identity}; use crypto::asymmetric::{encryption, identity};
use gateway_client::GatewayClient; use gateway_client::GatewayClient;
use gateway_requests::registration::handshake::SharedKeys; use gateway_requests::registration::handshake::SharedKeys;
@@ -60,34 +57,15 @@ pub fn command_args<'a, 'b>() -> clap::App<'a, 'b> {
) )
} }
// this behaviour should definitely be changed, we shouldn't
// need to get bandwidth credential for registration
async fn prepare_temporary_credential(validators: &[Url], raw_identity: &[u8]) -> Credential {
let verification_key = obtain_aggregate_verification_key(validators)
.await
.expect("could not obtain aggregate verification key of validators");
let bandwidth_credential = credentials::bandwidth::obtain_signature(raw_identity, validators)
.await
.expect("could not obtain bandwidth credential");
prepare_for_spending(raw_identity, &bandwidth_credential, &verification_key)
.expect("could not prepare out bandwidth credential for spending")
}
async fn register_with_gateway( async fn register_with_gateway(
gateway: &gateway::Node, gateway: &gateway::Node,
our_identity: Arc<identity::KeyPair>, our_identity: Arc<identity::KeyPair>,
validator_urls: Vec<Url>,
) -> Arc<SharedKeys> { ) -> Arc<SharedKeys> {
let timeout = Duration::from_millis(1500); let timeout = Duration::from_millis(1500);
let coconut_credential =
prepare_temporary_credential(&validator_urls, &our_identity.public_key().to_bytes()).await;
let mut gateway_client = GatewayClient::new_init( let mut gateway_client = GatewayClient::new_init(
gateway.clients_address(), gateway.clients_address(),
gateway.identity_key, gateway.identity_key,
our_identity.clone(), our_identity.clone(),
coconut_credential,
timeout, timeout,
); );
gateway_client gateway_client
@@ -211,13 +189,8 @@ pub fn execute(matches: &ArgMatches) {
config config
.get_base_mut() .get_base_mut()
.with_gateway_id(gate_details.identity_key.to_base58_string()); .with_gateway_id(gate_details.identity_key.to_base58_string());
let validator_urls = config.get_base().get_validator_api_endpoints(); let shared_keys =
let shared_keys = register_with_gateway( register_with_gateway(&gate_details, key_manager.identity_keypair()).await;
&gate_details,
key_manager.identity_keypair(),
validator_urls,
)
.await;
(shared_keys, gate_details.clients_address()) (shared_keys, gate_details.clients_address())
}; };
@@ -8,7 +8,6 @@ pub use crate::packet_router::{
AcknowledgementReceiver, AcknowledgementSender, MixnetMessageReceiver, MixnetMessageSender, AcknowledgementReceiver, AcknowledgementSender, MixnetMessageReceiver, MixnetMessageSender,
}; };
use crate::socket_state::{PartiallyDelegated, SocketState}; use crate::socket_state::{PartiallyDelegated, SocketState};
use coconut_interface::Credential;
use crypto::asymmetric::identity; use crypto::asymmetric::identity;
use futures::{FutureExt, SinkExt, StreamExt}; use futures::{FutureExt, SinkExt, StreamExt};
use gateway_requests::authentication::encrypted_address::EncryptedAddressBytes; use gateway_requests::authentication::encrypted_address::EncryptedAddressBytes;
@@ -36,8 +35,6 @@ const DEFAULT_RECONNECTION_BACKOFF: Duration = Duration::from_secs(5);
pub struct GatewayClient { pub struct GatewayClient {
authenticated: bool, authenticated: bool,
// TODO: This should be replaced by an actual bandwidth value, with 0 meaning no bandwidth
has_bandwidth: bool,
gateway_address: String, gateway_address: String,
gateway_identity: identity::PublicKey, gateway_identity: identity::PublicKey,
local_identity: Arc<identity::KeyPair>, local_identity: Arc<identity::KeyPair>,
@@ -54,7 +51,6 @@ pub struct GatewayClient {
reconnection_attempts: usize, reconnection_attempts: usize,
/// Delay between each subsequent reconnection attempt. /// Delay between each subsequent reconnection attempt.
reconnection_backoff: Duration, reconnection_backoff: Duration,
coconut_credential: Credential,
} }
impl GatewayClient { impl GatewayClient {
@@ -68,11 +64,9 @@ impl GatewayClient {
mixnet_message_sender: MixnetMessageSender, mixnet_message_sender: MixnetMessageSender,
ack_sender: AcknowledgementSender, ack_sender: AcknowledgementSender,
response_timeout_duration: Duration, response_timeout_duration: Duration,
coconut_credential: Credential,
) -> Self { ) -> Self {
GatewayClient { GatewayClient {
authenticated: false, authenticated: false,
has_bandwidth: false,
gateway_address, gateway_address,
gateway_identity, gateway_identity,
local_identity, local_identity,
@@ -83,7 +77,6 @@ impl GatewayClient {
should_reconnect_on_failure: true, should_reconnect_on_failure: true,
reconnection_attempts: DEFAULT_RECONNECTION_ATTEMPTS, reconnection_attempts: DEFAULT_RECONNECTION_ATTEMPTS,
reconnection_backoff: DEFAULT_RECONNECTION_BACKOFF, reconnection_backoff: DEFAULT_RECONNECTION_BACKOFF,
coconut_credential,
} }
} }
@@ -104,7 +97,6 @@ impl GatewayClient {
gateway_address: String, gateway_address: String,
gateway_identity: identity::PublicKey, gateway_identity: identity::PublicKey,
local_identity: Arc<identity::KeyPair>, local_identity: Arc<identity::KeyPair>,
coconut_credential: Credential,
response_timeout_duration: Duration, response_timeout_duration: Duration,
) -> Self { ) -> Self {
use futures::channel::mpsc; use futures::channel::mpsc;
@@ -117,7 +109,6 @@ impl GatewayClient {
GatewayClient { GatewayClient {
authenticated: false, authenticated: false,
has_bandwidth: false,
gateway_address, gateway_address,
gateway_identity, gateway_identity,
local_identity, local_identity,
@@ -128,7 +119,6 @@ impl GatewayClient {
should_reconnect_on_failure: false, should_reconnect_on_failure: false,
reconnection_attempts: DEFAULT_RECONNECTION_ATTEMPTS, reconnection_attempts: DEFAULT_RECONNECTION_ATTEMPTS,
reconnection_backoff: DEFAULT_RECONNECTION_BACKOFF, reconnection_backoff: DEFAULT_RECONNECTION_BACKOFF,
coconut_credential,
} }
} }
@@ -456,32 +446,6 @@ impl GatewayClient {
} }
} }
pub async fn claim_bandwidth(&mut self) -> Result<(), GatewayClientError> {
if !self.authenticated {
return Err(GatewayClientError::NotAuthenticated);
}
if self.shared_key.is_none() {
return Err(GatewayClientError::NoSharedKeyAvailable);
}
let mut rng = OsRng;
let iv = IV::new_random(&mut rng);
let msg = ClientControlRequest::new_enc_bandwidth_credential(
&self.coconut_credential,
self.shared_key.as_ref().unwrap(),
iv,
)
.ok_or(GatewayClientError::SerializeCredential)?
.into();
self.has_bandwidth = match self.send_websocket_message(msg).await? {
ServerResponse::Bandwidth { status } => Ok(status),
ServerResponse::Error { message } => Err(GatewayClientError::GatewayError(message)),
_ => Err(GatewayClientError::UnexpectedResponse),
}?;
Ok(())
}
pub async fn batch_send_mix_packets( pub async fn batch_send_mix_packets(
&mut self, &mut self,
packets: Vec<MixPacket>, packets: Vec<MixPacket>,
@@ -489,9 +453,6 @@ impl GatewayClient {
if !self.authenticated { if !self.authenticated {
return Err(GatewayClientError::NotAuthenticated); return Err(GatewayClientError::NotAuthenticated);
} }
if !self.has_bandwidth {
return Err(GatewayClientError::NotEnoughBandwidth);
}
if !self.connection.is_established() { if !self.connection.is_established() {
return Err(GatewayClientError::ConnectionNotEstablished); return Err(GatewayClientError::ConnectionNotEstablished);
} }
@@ -550,9 +511,6 @@ impl GatewayClient {
if !self.authenticated { if !self.authenticated {
return Err(GatewayClientError::NotAuthenticated); return Err(GatewayClientError::NotAuthenticated);
} }
if !self.has_bandwidth {
return Err(GatewayClientError::NotEnoughBandwidth);
}
if !self.connection.is_established() { if !self.connection.is_established() {
return Err(GatewayClientError::ConnectionNotEstablished); return Err(GatewayClientError::ConnectionNotEstablished);
} }
@@ -598,9 +556,6 @@ impl GatewayClient {
if !self.authenticated { if !self.authenticated {
return Err(GatewayClientError::NotAuthenticated); return Err(GatewayClientError::NotAuthenticated);
} }
if !self.has_bandwidth {
return Err(GatewayClientError::NotEnoughBandwidth);
}
if self.connection.is_partially_delegated() { if self.connection.is_partially_delegated() {
return Ok(()); return Ok(());
} }
@@ -633,7 +588,6 @@ impl GatewayClient {
self.establish_connection().await?; self.establish_connection().await?;
} }
let shared_key = self.perform_initial_authentication().await?; let shared_key = self.perform_initial_authentication().await?;
self.claim_bandwidth().await?;
// this call is NON-blocking // this call is NON-blocking
self.start_listening_for_mixnet_messages()?; self.start_listening_for_mixnet_messages()?;
@@ -3,10 +3,12 @@
use crate::nymd::cosmwasm_client::types::ContractCodeId; use crate::nymd::cosmwasm_client::types::ContractCodeId;
use cosmrs::tendermint::block; use cosmrs::tendermint::block;
use cosmrs::{bip32, rpc, tx, AccountId}; use cosmrs::{bip32, tx, AccountId};
use std::io; use std::io;
use thiserror::Error; use thiserror::Error;
pub use cosmrs::rpc::error::{Code, Error as TendermintRpcError};
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum NymdError { pub enum NymdError {
#[error("No contract address is available to perform the call")] #[error("No contract address is available to perform the call")]
@@ -31,7 +33,7 @@ pub enum NymdError {
InvalidTxHash(String), InvalidTxHash(String),
#[error("There was an issue with a tendermint RPC request - {0}")] #[error("There was an issue with a tendermint RPC request - {0}")]
TendermintError(#[from] rpc::Error), TendermintError(#[from] TendermintRpcError),
#[error("There was an issue when attempting to serialize data")] #[error("There was an issue when attempting to serialize data")]
SerializationError(String), SerializationError(String),
@@ -98,3 +100,48 @@ pub enum NymdError {
#[error("The provided gas price is malformed")] #[error("The provided gas price is malformed")]
MalformedGasPrice, MalformedGasPrice,
} }
impl NymdError {
pub fn is_tendermint_timeout(&self) -> bool {
match &self {
NymdError::TendermintError(tm_err) => {
if tm_err.code() == Code::InternalError {
// 0.34 (and earlier) versions of tendermint seemed to be using phrase "timed out waiting ..."
// (https://github.com/tendermint/tendermint/blob/v0.34.13/rpc/core/mempool.go#L124)
// while 0.35+ has "timeout waiting for ..."
// https://github.com/tendermint/tendermint/blob/v0.35.0-rc3/internal/rpc/core/mempool.go#L99
// note that as of the time of writing this comment (08.10.2021), the most recent version
// of cosmos-sdk (v0.44.1) uses tendermint 0.34.13
if let Some(data) = tm_err.data() {
data.contains("timed out") || data.contains("timeout")
} else {
false
}
} else {
false
}
}
_ => false,
}
}
pub fn is_tendermint_duplicate(&self) -> bool {
match &self {
NymdError::TendermintError(tm_err) => {
if tm_err.code() == Code::InternalError {
// this particular error message seems to be unchanged between 0.34 and newer versions
// https://github.com/tendermint/tendermint/blob/v0.34.13/mempool/errors.go#L10
// https://github.com/tendermint/tendermint/blob/v0.35.0-rc3/types/mempool.go#L10
if let Some(data) = tm_err.data() {
data.contains("tx already exists in cache")
} else {
false
}
} else {
false
}
}
_ => false,
}
}
}
@@ -4,7 +4,7 @@
use crate::nymd::cosmwasm_client::signing_client; use crate::nymd::cosmwasm_client::signing_client;
use crate::nymd::cosmwasm_client::types::{ use crate::nymd::cosmwasm_client::types::{
ChangeAdminResult, ContractCodeId, ExecuteResult, InstantiateOptions, InstantiateResult, ChangeAdminResult, ContractCodeId, ExecuteResult, InstantiateOptions, InstantiateResult,
MigrateResult, UploadMeta, UploadResult, MigrateResult, SequenceResponse, UploadMeta, UploadResult,
}; };
use crate::nymd::error::NymdError; use crate::nymd::error::NymdError;
use crate::nymd::fee_helpers::Operation; use crate::nymd::fee_helpers::Operation;
@@ -28,6 +28,7 @@ pub use crate::nymd::cosmwasm_client::client::CosmWasmClient;
pub use crate::nymd::cosmwasm_client::signing_client::SigningCosmWasmClient; pub use crate::nymd::cosmwasm_client::signing_client::SigningCosmWasmClient;
pub use crate::nymd::gas_price::GasPrice; pub use crate::nymd::gas_price::GasPrice;
pub use cosmrs::rpc::HttpClient as QueryNymdClient; pub use cosmrs::rpc::HttpClient as QueryNymdClient;
use cosmrs::tendermint::block::Height;
pub use cosmrs::tendermint::Time as TendermintTime; pub use cosmrs::tendermint::Time as TendermintTime;
pub use cosmrs::tx::{Fee, Gas}; pub use cosmrs::tx::{Fee, Gas};
pub use cosmrs::Coin as CosmosCoin; pub use cosmrs::Coin as CosmosCoin;
@@ -155,11 +156,25 @@ impl<C> NymdClient<C> {
&self.client_address.as_ref().unwrap()[0] &self.client_address.as_ref().unwrap()[0]
} }
pub async fn account_sequence(&self) -> Result<SequenceResponse, NymdError>
where
C: SigningCosmWasmClient + Sync,
{
self.client.get_sequence(self.address()).await
}
pub fn get_fee(&self, operation: Operation) -> Fee { pub fn get_fee(&self, operation: Operation) -> Fee {
let gas_limit = self.custom_gas_limits.get(&operation).cloned(); let gas_limit = self.custom_gas_limits.get(&operation).cloned();
operation.determine_fee(&self.gas_price, gas_limit) operation.determine_fee(&self.gas_price, gas_limit)
} }
pub async fn get_current_block_height(&self) -> Result<Height, NymdError>
where
C: CosmWasmClient + Sync,
{
self.client.get_height().await
}
pub fn calculate_custom_fee(&self, gas_limit: impl Into<Gas>) -> Fee { pub fn calculate_custom_fee(&self, gas_limit: impl Into<Gas>) -> Fee {
Operation::determine_custom_fee(&self.gas_price, gas_limit.into()) Operation::determine_custom_fee(&self.gas_price, gas_limit.into())
} }
+595 -5
View File
@@ -2,6 +2,45 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "Inflector"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
dependencies = [
"lazy_static",
"regex",
]
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "ast_node"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93f52ce8fac3d0e6720a92b0576d737c01b1b5db4dd786e962e5925f00bf755"
dependencies = [
"darling",
"pmutil",
"proc-macro2",
"quote",
"swc_macros_common",
"syn",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.13.0" version = "0.13.0"
@@ -38,6 +77,12 @@ dependencies = [
"byte-tools", "byte-tools",
] ]
[[package]]
name = "bumpalo"
version = "3.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538"
[[package]] [[package]]
name = "byte-tools" name = "byte-tools"
version = "0.3.1" version = "0.3.1"
@@ -50,6 +95,12 @@ version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.0"
@@ -178,6 +229,41 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "darling"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
dependencies = [
"darling_core",
"quote",
"syn",
]
[[package]] [[package]]
name = "der" name = "der"
version = "0.4.0" version = "0.4.0"
@@ -205,6 +291,45 @@ dependencies = [
"generic-array 0.14.4", "generic-array 0.14.4",
] ]
[[package]]
name = "dprint-core"
version = "0.35.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93bd44f40b1881477837edc7112695d4b174f058c36c1cbc4c50f8d0482e2ac8"
dependencies = [
"bumpalo",
"fnv",
"serde",
]
[[package]]
name = "dprint-plugin-typescript"
version = "0.43.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67ba0077bd2ab9235848e793fbbfb563e6a04b4c8e4149827802a84063c15805"
dependencies = [
"dprint-core",
"dprint-swc-ecma-ast-view",
"fnv",
"serde",
"swc_common",
"swc_ecmascript",
]
[[package]]
name = "dprint-swc-ecma-ast-view"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecf692a2ee5c5f699ed0e95f21686cf6367f3a591e5d8e7bd3041bbf184651f9"
dependencies = [
"bumpalo",
"fnv",
"num-bigint",
"swc_atoms",
"swc_common",
"swc_ecmascript",
]
[[package]] [[package]]
name = "dyn-clone" name = "dyn-clone"
version = "1.0.4" version = "1.0.4"
@@ -237,6 +362,12 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]] [[package]]
name = "elliptic-curve" name = "elliptic-curve"
version = "0.10.4" version = "0.10.4"
@@ -253,6 +384,18 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "enum_kind"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b940da354ae81ef0926c5eaa428207b8f4f091d3956c891dfbd124162bed99"
dependencies = [
"pmutil",
"proc-macro2",
"swc_macros_common",
"syn",
]
[[package]] [[package]]
name = "fake-simd" name = "fake-simd"
version = "0.1.2" version = "0.1.2"
@@ -269,6 +412,12 @@ dependencies = [
"subtle", "subtle",
] ]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]] [[package]]
name = "form_urlencoded" name = "form_urlencoded"
version = "1.0.1" version = "1.0.1"
@@ -279,6 +428,27 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "from_variant"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0951635027ca477be98f8774abd6f0345233439d63f307e47101acb40c7cc63d"
dependencies = [
"pmutil",
"proc-macro2",
"swc_macros_common",
"syn",
]
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
"byteorder",
]
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.12.4" version = "0.12.4"
@@ -304,7 +474,7 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [ dependencies = [
"cfg-if", "cfg-if 1.0.0",
"libc", "libc",
"wasi 0.9.0+wasi-snapshot-preview1", "wasi 0.9.0+wasi-snapshot-preview1",
] ]
@@ -315,7 +485,7 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [ dependencies = [
"cfg-if", "cfg-if 1.0.0",
"libc", "libc",
"wasi 0.10.2+wasi-snapshot-preview1", "wasi 0.10.2+wasi-snapshot-preview1",
] ]
@@ -377,6 +547,12 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]] [[package]]
name = "idna" name = "idna"
version = "0.2.3" version = "0.2.3"
@@ -388,6 +564,19 @@ dependencies = [
"unicode-normalization", "unicode-normalization",
] ]
[[package]]
name = "is-macro"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a322dd16d960e322c3d92f541b4c1a4f0a2e81e1fdeee430d8cecc8b72e8015f"
dependencies = [
"Inflector",
"pmutil",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "0.4.7" version = "0.4.7"
@@ -400,12 +589,18 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "008b0281ca8032567c9711cd48631781c15228301860a39b32deb28d63125e46" checksum = "008b0281ca8032567c9711cd48631781c15228301860a39b32deb28d63125e46"
dependencies = [ dependencies = [
"cfg-if", "cfg-if 1.0.0",
"ecdsa", "ecdsa",
"elliptic-curve", "elliptic-curve",
"sha2", "sha2",
] ]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.100" version = "0.2.100"
@@ -418,7 +613,7 @@ version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [ dependencies = [
"cfg-if", "cfg-if 1.0.0",
] ]
[[package]] [[package]]
@@ -433,6 +628,12 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
[[package]]
name = "memchr"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]] [[package]]
name = "mixnet-contract" name = "mixnet-contract"
version = "0.1.0" version = "0.1.0"
@@ -441,6 +642,7 @@ dependencies = [
"schemars", "schemars",
"serde", "serde",
"serde_repr", "serde_repr",
"ts-rs",
] ]
[[package]] [[package]]
@@ -461,10 +663,54 @@ dependencies = [
name = "network-defaults" name = "network-defaults"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"serde",
"time", "time",
"url", "url",
] ]
[[package]]
name = "new_debug_unreachable"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]]
name = "num-bigint"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
"serde",
]
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
version = "0.2.3" version = "0.2.3"
@@ -477,6 +723,15 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "owning_ref"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce"
dependencies = [
"stable_deref_trait",
]
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.1.0" version = "2.1.0"
@@ -526,6 +781,25 @@ dependencies = [
"sha-1", "sha-1",
] ]
[[package]]
name = "phf_generator"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
dependencies = [
"phf_shared",
"rand",
]
[[package]]
name = "phf_shared"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
dependencies = [
"siphasher",
]
[[package]] [[package]]
name = "pkcs8" name = "pkcs8"
version = "0.7.5" version = "0.7.5"
@@ -536,6 +810,29 @@ dependencies = [
"spki", "spki",
] ]
[[package]]
name = "pmutil"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3894e5d549cccbe44afecf72922f277f603cd4bb0219c8342631ef18fffbe004"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "precomputed-hash"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.24" version = "1.0.24"
@@ -560,6 +857,30 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.16",
"libc",
"rand_chacha",
"rand_core 0.5.1",
"rand_hc",
"rand_pcg",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core 0.5.1",
]
[[package]] [[package]]
name = "rand_core" name = "rand_core"
version = "0.5.1" version = "0.5.1"
@@ -578,6 +899,41 @@ dependencies = [
"getrandom 0.2.3", "getrandom 0.2.3",
] ]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core 0.5.1",
]
[[package]]
name = "rand_pcg"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
dependencies = [
"rand_core 0.5.1",
]
[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.5" version = "1.0.5"
@@ -608,6 +964,12 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "scoped-tls"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.122" version = "1.0.122"
@@ -689,7 +1051,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12"
dependencies = [ dependencies = [
"block-buffer 0.9.0", "block-buffer 0.9.0",
"cfg-if", "cfg-if 1.0.0",
"cpufeatures", "cpufeatures",
"digest 0.9.0", "digest 0.9.0",
"opaque-debug 0.3.0", "opaque-debug 0.3.0",
@@ -705,6 +1067,18 @@ dependencies = [
"rand_core 0.6.3", "rand_core 0.6.3",
] ]
[[package]]
name = "siphasher"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b"
[[package]]
name = "smallvec"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
[[package]] [[package]]
name = "spki" name = "spki"
version = "0.4.0" version = "0.4.0"
@@ -714,18 +1088,206 @@ dependencies = [
"der", "der",
] ]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]] [[package]]
name = "static_assertions" name = "static_assertions"
version = "1.1.0" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "string_cache"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ddb1139b5353f96e429e1a5e19fbaf663bddedaa06d1dbd49f82e352601209a"
dependencies = [
"lazy_static",
"new_debug_unreachable",
"phf_shared",
"precomputed-hash",
"serde",
]
[[package]]
name = "string_cache_codegen"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97"
dependencies = [
"phf_generator",
"phf_shared",
"proc-macro2",
"quote",
]
[[package]]
name = "string_enum"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f584cc881e9e5f1fd6bf827b0444aa94c30d8fe6378cf241071b5f5700b2871f"
dependencies = [
"pmutil",
"proc-macro2",
"quote",
"swc_macros_common",
"syn",
]
[[package]]
name = "strsim"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "2.4.0" version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
[[package]]
name = "swc_atoms"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "837a3ef86c2817228e733b6f173c821fd76f9eb21a0bc9001a826be48b00b4e7"
dependencies = [
"string_cache",
"string_cache_codegen",
]
[[package]]
name = "swc_common"
version = "0.10.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c93df65683ec1a001e15ce1de438c7c2c226c0c2462d1cb93fa1bd2a7664170b"
dependencies = [
"ast_node",
"cfg-if 0.1.10",
"either",
"from_variant",
"fxhash",
"log",
"num-bigint",
"once_cell",
"owning_ref",
"scoped-tls",
"serde",
"string_cache",
"swc_eq_ignore_macros",
"swc_visit",
"unicode-width",
]
[[package]]
name = "swc_ecma_ast"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83eb6a73820660a5af3c24ae1d436e84e4d4c13822021140011361e678df247b"
dependencies = [
"is-macro",
"num-bigint",
"serde",
"string_enum",
"swc_atoms",
"swc_common",
]
[[package]]
name = "swc_ecma_parser"
version = "0.52.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c03250697857164f16fa98f8e1726f566652d13e52ea3f0c3ecea9deb63ee327"
dependencies = [
"either",
"enum_kind",
"fxhash",
"log",
"num-bigint",
"serde",
"smallvec",
"swc_atoms",
"swc_common",
"swc_ecma_ast",
"swc_ecma_visit",
"unicode-xid",
]
[[package]]
name = "swc_ecma_visit"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd3d60b9dc97ae4f181d4d60f43142d8ac9669953db410bcedefb29a14627e19"
dependencies = [
"num-bigint",
"swc_atoms",
"swc_common",
"swc_ecma_ast",
"swc_visit",
]
[[package]]
name = "swc_ecmascript"
version = "0.29.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ffb53afe008c15d4dc4957e80148c4b457659f93e4d4e8736eaeae352e48ec8"
dependencies = [
"swc_ecma_ast",
"swc_ecma_parser",
]
[[package]]
name = "swc_eq_ignore_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c8f200a2eaed938e7c1a685faaa66e6d42fa9e17da5f62572d3cbc335898f5e"
dependencies = [
"pmutil",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "swc_macros_common"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08ed2e930f5a1a4071fe62c90fd3a296f6030e5d94bfe13993244423caf59a78"
dependencies = [
"pmutil",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "swc_visit"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a423caa0b4585118164dbad8f1ad52b592a9a9370b25decc4d84c6b4309132c0"
dependencies = [
"either",
"swc_visit_macros",
]
[[package]]
name = "swc_visit_macros"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3b2825fee79f10d0166e8e650e79c7a862fb991db275743083f07555d7641f0"
dependencies = [
"Inflector",
"pmutil",
"proc-macro2",
"quote",
"swc_macros_common",
"syn",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.65" version = "1.0.65"
@@ -797,6 +1359,28 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "ts-rs"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "369e48de67506679b3a576b0faf666fa9f9acf2fd00b4c61e28bdb6c8e08ec06"
dependencies = [
"dprint-plugin-typescript",
"ts-rs-macros",
]
[[package]]
name = "ts-rs-macros"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f269e8fd28e26b4cdbd01f81f345aaf666131511e54a735a76a614b5062d0a5a"
dependencies = [
"Inflector",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.13.0" version = "1.13.0"
@@ -839,6 +1423,12 @@ dependencies = [
"tinyvec", "tinyvec",
] ]
[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.1" version = "0.2.1"
-2
View File
@@ -28,8 +28,6 @@ tokio-tungstenite = "0.14"
url = { version = "2.2", features = [ "serde" ] } url = { version = "2.2", features = [ "serde" ] }
# internal # internal
coconut-interface = { path = "../common/coconut-interface" }
credentials = { path = "../common/credentials" }
config = { path = "../common/config" } config = { path = "../common/config" }
crypto = { path = "../common/crypto" } crypto = { path = "../common/crypto" }
gateway-requests = { path = "gateway-requests" } gateway-requests = { path = "gateway-requests" }
-33
View File
@@ -5,7 +5,6 @@ use crate::authentication::encrypted_address::EncryptedAddressBytes;
use crate::iv::IV; use crate::iv::IV;
use crate::registration::handshake::SharedKeys; use crate::registration::handshake::SharedKeys;
use crate::GatewayMacSize; use crate::GatewayMacSize;
use coconut_interface::Credential;
use crypto::generic_array::typenum::Unsigned; use crypto::generic_array::typenum::Unsigned;
use crypto::hmac::recompute_keyed_hmac_and_verify_tag; use crypto::hmac::recompute_keyed_hmac_and_verify_tag;
use crypto::symmetric::stream_cipher; use crypto::symmetric::stream_cipher;
@@ -113,10 +112,6 @@ pub enum ClientControlRequest {
}, },
#[serde(alias = "handshakePayload")] #[serde(alias = "handshakePayload")]
RegisterHandshakeInitRequest { data: Vec<u8> }, RegisterHandshakeInitRequest { data: Vec<u8> },
BandwidthCredential {
enc_credential: Vec<u8>,
iv: Vec<u8>,
},
} }
impl ClientControlRequest { impl ClientControlRequest {
@@ -131,34 +126,6 @@ impl ClientControlRequest {
iv: iv.to_base58_string(), iv: iv.to_base58_string(),
} }
} }
pub fn new_enc_bandwidth_credential(
credential: &Credential,
shared_key: &SharedKeys,
iv: IV,
) -> Option<Self> {
match bincode::serialize(credential) {
Ok(serialized_credential) => {
let enc_credential =
shared_key.encrypt_and_tag(&serialized_credential, Some(iv.inner()));
Some(ClientControlRequest::BandwidthCredential {
enc_credential,
iv: iv.to_bytes(),
})
}
_ => None,
}
}
pub fn try_from_enc_bandwidth_credential(
enc_credential: Vec<u8>,
shared_key: &SharedKeys,
iv: IV,
) -> Result<Credential, GatewayRequestsError> {
let credential = shared_key.decrypt_tagged(&enc_credential, Some(iv.inner()))?;
bincode::deserialize(&credential).map_err(|_| GatewayRequestsError::MalformedEncryption)
}
} }
impl From<ClientControlRequest> for Message { impl From<ClientControlRequest> for Message {
@@ -1,85 +0,0 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::collections::HashMap;
use std::convert::TryFrom;
use std::sync::Arc;
use tokio::sync::RwLock;
use coconut_interface::Credential;
use credentials::error::Error;
use nymsphinx::DestinationAddressBytes;
const BANDWIDTH_INDEX: usize = 0;
pub type BandwidthDatabase = Arc<RwLock<HashMap<DestinationAddressBytes, u64>>>;
pub fn empty_bandwidth_database() -> BandwidthDatabase {
Arc::new(RwLock::new(HashMap::new()))
}
pub struct Bandwidth {
value: u64,
}
impl Bandwidth {
pub fn value(&self) -> u64 {
self.value
}
pub async fn consume_bandwidth(
bandwidths: &BandwidthDatabase,
remote_address: &DestinationAddressBytes,
consumed: u64,
) -> Result<(), Error> {
if let Some(bandwidth) = bandwidths.write().await.get_mut(remote_address) {
if let Some(res) = bandwidth.checked_sub(consumed) {
*bandwidth = res;
Ok(())
} else {
Err(Error::BandwidthOverflow(String::from(
"Allocate more bandwidth for consumption",
)))
}
} else {
Err(Error::MissingBandwidth)
}
}
pub async fn increase_bandwidth(
bandwidths: &BandwidthDatabase,
remote_address: &DestinationAddressBytes,
increase: u64,
) -> Result<(), Error> {
let mut db = bandwidths.write().await;
if let Some(bandwidth) = db.get_mut(remote_address) {
if let Some(new_bandwidth) = bandwidth.checked_add(increase) {
*bandwidth = new_bandwidth;
} else {
return Err(Error::BandwidthOverflow(String::from(
"Use some of the already allocated bandwidth",
)));
}
} else {
db.insert(*remote_address, increase);
}
Ok(())
}
}
impl TryFrom<Credential> for Bandwidth {
type Error = Error;
fn try_from(credential: Credential) -> Result<Self, Self::Error> {
match credential.public_attributes().get(BANDWIDTH_INDEX) {
None => Err(Error::NotEnoughPublicAttributes),
Some(attr) => match <[u8; 8]>::try_from(attr.as_slice()) {
Ok(bandwidth_bytes) => {
let value = u64::from_be_bytes(bandwidth_bytes);
Ok(Self { value })
}
Err(_) => Err(Error::InvalidBandwidthSize),
},
}
}
}
-1
View File
@@ -1,6 +1,5 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net> // Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
mod bandwidth;
pub(crate) mod clients_handler; pub(crate) mod clients_handler;
pub(crate) mod websocket; pub(crate) mod websocket;
@@ -1,14 +1,12 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net> // Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::node::client_handling::bandwidth::{Bandwidth, BandwidthDatabase};
use crate::node::client_handling::clients_handler::{ use crate::node::client_handling::clients_handler::{
ClientsHandlerRequest, ClientsHandlerRequestSender, ClientsHandlerResponse, ClientsHandlerRequest, ClientsHandlerRequestSender, ClientsHandlerResponse,
}; };
use crate::node::client_handling::websocket::message_receiver::{ use crate::node::client_handling::websocket::message_receiver::{
MixMessageReceiver, MixMessageSender, MixMessageReceiver, MixMessageSender,
}; };
use coconut_interface::VerificationKey;
use crypto::asymmetric::identity; use crypto::asymmetric::identity;
use futures::{ use futures::{
channel::{mpsc, oneshot}, channel::{mpsc, oneshot},
@@ -25,7 +23,6 @@ use mixnet_client::forwarder::MixForwardingSender;
use nymsphinx::DestinationAddressBytes; use nymsphinx::DestinationAddressBytes;
use rand::{CryptoRng, Rng}; use rand::{CryptoRng, Rng};
use std::convert::TryFrom; use std::convert::TryFrom;
use std::mem;
use std::sync::Arc; use std::sync::Arc;
use tokio::io::{AsyncRead, AsyncWrite}; use tokio::io::{AsyncRead, AsyncWrite};
use tokio_tungstenite::{ use tokio_tungstenite::{
@@ -58,10 +55,8 @@ pub(crate) struct Handle<R, S> {
clients_handler_sender: ClientsHandlerRequestSender, clients_handler_sender: ClientsHandlerRequestSender,
outbound_mix_sender: MixForwardingSender, outbound_mix_sender: MixForwardingSender,
socket_connection: SocketStream<S>, socket_connection: SocketStream<S>,
local_identity: Arc<identity::KeyPair>,
aggregated_verification_key: VerificationKey, local_identity: Arc<identity::KeyPair>,
bandwidths: BandwidthDatabase,
} }
impl<R, S> Handle<R, S> impl<R, S> Handle<R, S>
@@ -76,8 +71,6 @@ where
clients_handler_sender: ClientsHandlerRequestSender, clients_handler_sender: ClientsHandlerRequestSender,
outbound_mix_sender: MixForwardingSender, outbound_mix_sender: MixForwardingSender,
local_identity: Arc<identity::KeyPair>, local_identity: Arc<identity::KeyPair>,
aggregated_verification_key: VerificationKey,
bandwidths: BandwidthDatabase,
) -> Self { ) -> Self {
Handle { Handle {
rng, rng,
@@ -87,8 +80,6 @@ where
outbound_mix_sender, outbound_mix_sender,
socket_connection: SocketStream::RawTcp(conn), socket_connection: SocketStream::RawTcp(conn),
local_identity, local_identity,
aggregated_verification_key,
bandwidths,
} }
} }
@@ -209,19 +200,8 @@ where
Ok(request) => match request { Ok(request) => match request {
// currently only a single type exists // currently only a single type exists
BinaryRequest::ForwardSphinx(mix_packet) => { BinaryRequest::ForwardSphinx(mix_packet) => {
let consumed_bandwidth = mem::size_of_val(&mix_packet) as u64; self.outbound_mix_sender.unbounded_send(mix_packet).unwrap();
if let Err(e) = Bandwidth::consume_bandwidth( ServerResponse::Send { status: true }
&self.bandwidths,
&self.remote_address.unwrap(),
consumed_bandwidth,
)
.await
{
ServerResponse::new_error(format!("{:?}", e))
} else {
self.outbound_mix_sender.unbounded_send(mix_packet).unwrap();
ServerResponse::Send { status: true }
}
} }
}, },
} }
@@ -357,68 +337,12 @@ where
} }
} }
async fn handle_bandwidth(&mut self, enc_credential: Vec<u8>, iv: Vec<u8>) -> ServerResponse { // currently there are no valid control messages you can send after authentication
if self.shared_key.is_none() { async fn handle_text(&mut self, _: String) -> Message {
return ServerResponse::new_error("No shared key has been exchanged with the gateway"); trace!("Handling text message (presumably control message)");
}
if self.remote_address.is_none() {
return ServerResponse::new_error("No remote address has been set");
}
let iv = match IV::try_from_bytes(&iv) {
Ok(iv) => iv,
Err(e) => {
trace!("failed to parse received IV {:?}", e);
return ServerResponse::new_error("malformed iv");
}
};
let credential = match ClientControlRequest::try_from_enc_bandwidth_credential(
enc_credential,
self.shared_key.as_ref().unwrap(),
iv,
) {
Ok(c) => c,
Err(e) => {
return ServerResponse::new_error(e.to_string());
}
};
if credential.verify(&self.aggregated_verification_key) {
match Bandwidth::try_from(credential) {
Ok(bandwidth) => {
if let Err(e) = Bandwidth::increase_bandwidth(
&self.bandwidths,
&self.remote_address.unwrap(),
bandwidth.value(),
)
.await
{
return ServerResponse::Error {
message: format!("{:?}", e),
};
}
ServerResponse::Bandwidth { status: true }
}
Err(e) => ServerResponse::Error {
message: format!("{:?}", e),
},
}
} else {
ServerResponse::Bandwidth { status: false }
}
}
// currently the bandwidth credential request is the only one we can receive after error!("Currently there are no text messages besides 'Authenticate' and 'Register' and they were already dealt with!");
// authentication ServerResponse::new_error("invalid request").into()
async fn handle_text(&mut self, raw_request: String) -> Message {
if let Ok(request) = ClientControlRequest::try_from(raw_request) {
match request {
ClientControlRequest::BandwidthCredential { enc_credential, iv } => {
self.handle_bandwidth(enc_credential, iv).await.into()
}
_ => ServerResponse::new_error("invalid request").into(),
}
} else {
ServerResponse::new_error("malformed request").into()
}
} }
async fn handle_request(&mut self, raw_request: Message) -> Option<Message> { async fn handle_request(&mut self, raw_request: Message) -> Option<Message> {
@@ -455,7 +379,6 @@ where
ClientControlRequest::RegisterHandshakeInitRequest { data } => { ClientControlRequest::RegisterHandshakeInitRequest { data } => {
self.handle_register(data, mix_sender).await self.handle_register(data, mix_sender).await
} }
_ => ServerResponse::new_error("invalid request"),
} }
} else { } else {
// TODO: is this a malformed request or rather a network error and // TODO: is this a malformed request or rather a network error and
@@ -1,10 +1,8 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net> // Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::node::client_handling::bandwidth::empty_bandwidth_database;
use crate::node::client_handling::clients_handler::ClientsHandlerRequestSender; use crate::node::client_handling::clients_handler::ClientsHandlerRequestSender;
use crate::node::client_handling::websocket::connection_handler::Handle; use crate::node::client_handling::websocket::connection_handler::Handle;
use coconut_interface::VerificationKey;
use crypto::asymmetric::identity; use crypto::asymmetric::identity;
use log::*; use log::*;
use mixnet_client::forwarder::MixForwardingSender; use mixnet_client::forwarder::MixForwardingSender;
@@ -17,19 +15,13 @@ use tokio::task::JoinHandle;
pub(crate) struct Listener { pub(crate) struct Listener {
address: SocketAddr, address: SocketAddr,
local_identity: Arc<identity::KeyPair>, local_identity: Arc<identity::KeyPair>,
aggregated_verification_key: VerificationKey,
} }
impl Listener { impl Listener {
pub(crate) fn new( pub(crate) fn new(address: SocketAddr, local_identity: Arc<identity::KeyPair>) -> Self {
address: SocketAddr,
local_identity: Arc<identity::KeyPair>,
aggregated_verification_key: VerificationKey,
) -> Self {
Listener { Listener {
address, address,
local_identity, local_identity,
aggregated_verification_key,
} }
} }
@@ -47,8 +39,6 @@ impl Listener {
} }
}; };
let bandwidths = empty_bandwidth_database();
loop { loop {
match tcp_listener.accept().await { match tcp_listener.accept().await {
Ok((socket, remote_addr)) => { Ok((socket, remote_addr)) => {
@@ -61,8 +51,6 @@ impl Listener {
clients_handler_sender.clone(), clients_handler_sender.clone(),
outbound_mix_sender.clone(), outbound_mix_sender.clone(),
Arc::clone(&self.local_identity), Arc::clone(&self.local_identity),
self.aggregated_verification_key.clone(),
Arc::clone(&bandwidths),
); );
tokio::spawn(async move { handle.start_handling().await }); tokio::spawn(async move { handle.start_handling().await });
} }
+3 -12
View File
@@ -6,8 +6,6 @@ use crate::node::client_handling::clients_handler::{ClientsHandler, ClientsHandl
use crate::node::client_handling::websocket; use crate::node::client_handling::websocket;
use crate::node::mixnet_handling::receiver::connection_handler::ConnectionHandler; use crate::node::mixnet_handling::receiver::connection_handler::ConnectionHandler;
use crate::node::storage::{inboxes, ClientLedger}; use crate::node::storage::{inboxes, ClientLedger};
use coconut_interface::VerificationKey;
use credentials::obtain_aggregate_verification_key;
use crypto::asymmetric::{encryption, identity}; use crypto::asymmetric::{encryption, identity};
use log::*; use log::*;
use mixnet_client::forwarder::{MixForwardingSender, PacketForwarder}; use mixnet_client::forwarder::{MixForwardingSender, PacketForwarder};
@@ -85,7 +83,6 @@ impl Gateway {
&self, &self,
forwarding_channel: MixForwardingSender, forwarding_channel: MixForwardingSender,
clients_handler_sender: ClientsHandlerRequestSender, clients_handler_sender: ClientsHandlerRequestSender,
verification_key: VerificationKey,
) { ) {
info!("Starting client [web]socket listener..."); info!("Starting client [web]socket listener...");
@@ -94,12 +91,8 @@ impl Gateway {
self.config.get_clients_port(), self.config.get_clients_port(),
); );
websocket::Listener::new( websocket::Listener::new(listening_address, Arc::clone(&self.identity))
listening_address, .start(clients_handler_sender, forwarding_channel);
Arc::clone(&self.identity),
verification_key,
)
.start(clients_handler_sender, forwarding_channel);
} }
fn start_packet_forwarder(&self) -> MixForwardingSender { fn start_packet_forwarder(&self) -> MixForwardingSender {
@@ -183,13 +176,11 @@ impl Gateway {
} }
} }
let validators_verification_key = obtain_aggregate_verification_key(&self.config.get_validator_api_endpoints()).await.expect("failed to contact validators to obtain their verification keys");
let mix_forwarding_channel = self.start_packet_forwarder(); let mix_forwarding_channel = self.start_packet_forwarder();
let clients_handler_sender = self.start_clients_handler(); let clients_handler_sender = self.start_clients_handler();
self.start_mix_socket_listener(clients_handler_sender.clone(), mix_forwarding_channel.clone()); self.start_mix_socket_listener(clients_handler_sender.clone(), mix_forwarding_channel.clone());
self.start_client_websocket_listener(mix_forwarding_channel, clients_handler_sender, validators_verification_key); self.start_client_websocket_listener(mix_forwarding_channel, clients_handler_sender);
info!("Finished nym gateway startup procedure - it should now be able to receive mix and client traffic!"); info!("Finished nym gateway startup procedure - it should now be able to receive mix and client traffic!");
-3
View File
@@ -48,9 +48,6 @@ nymsphinx = { path="../common/nymsphinx" }
topology = { path="../common/topology" } topology = { path="../common/topology" }
validator-client = { path="../common/client-libs/validator-client", features = ["nymd-client"] } validator-client = { path="../common/client-libs/validator-client", features = ["nymd-client"] }
version-checker = { path="../common/version-checker" } version-checker = { path="../common/version-checker" }
coconut-interface = { path = "../common/coconut-interface" }
credentials = { path = "../common/credentials" }
[build-dependencies] [build-dependencies]
tokio = { version = "1.4", features = ["rt-multi-thread", "macros"] } tokio = { version = "1.4", features = ["rt-multi-thread", "macros"] }
-85
View File
@@ -1,85 +0,0 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use coconut_interface::{
elgamal::PublicKey, Attribute, BlindSignRequest, BlindSignRequestBody, BlindedSignature,
BlindedSignatureResponse, KeyPair, Parameters, VerificationKeyResponse,
};
use config::defaults::VALIDATOR_API_VERSION;
use getset::{CopyGetters, Getters};
use rocket::fairing::AdHoc;
use rocket::serde::json::Json;
use rocket::State;
#[derive(Getters, CopyGetters, Debug)]
pub(crate) struct InternalSignRequest {
// Total number of parameters to generate for
#[getset(get_copy)]
total_params: u32,
#[getset(get)]
public_attributes: Vec<Attribute>,
#[getset(get)]
public_key: PublicKey,
#[getset(get)]
blind_sign_request: BlindSignRequest,
}
impl InternalSignRequest {
pub fn new(
total_params: u32,
public_attributes: Vec<Attribute>,
public_key: PublicKey,
blind_sign_request: BlindSignRequest,
) -> InternalSignRequest {
InternalSignRequest {
total_params,
public_attributes,
public_key,
blind_sign_request,
}
}
pub fn stage(key_pair: KeyPair) -> AdHoc {
AdHoc::on_ignite("Internal Sign Request Stage", |rocket| async {
rocket.manage(key_pair).mount(
// this format! is so ugly...
format!("/{}", VALIDATOR_API_VERSION),
routes![post_blind_sign, get_verification_key],
)
})
}
}
fn blind_sign(request: InternalSignRequest, key_pair: &KeyPair) -> BlindedSignature {
let params = Parameters::new(request.total_params()).unwrap();
coconut_interface::blind_sign(
&params,
&key_pair.secret_key(),
request.public_key(),
request.blind_sign_request(),
request.public_attributes(),
)
.unwrap()
}
#[post("/blind_sign", data = "<blind_sign_request_body>")]
// Until we have serialization and deserialization traits we'll be using a crutch
pub async fn post_blind_sign(
blind_sign_request_body: Json<BlindSignRequestBody>,
key_pair: &State<KeyPair>,
) -> Json<BlindedSignatureResponse> {
debug!("{:?}", blind_sign_request_body);
let internal_request = InternalSignRequest::new(
*blind_sign_request_body.total_params(),
blind_sign_request_body.public_attributes(),
blind_sign_request_body.public_key().clone(),
blind_sign_request_body.blind_sign_request().clone(),
);
let blinded_signature = blind_sign(internal_request, key_pair);
Json(BlindedSignatureResponse::new(blinded_signature))
}
#[get("/verification_key")]
pub async fn get_verification_key(key_pair: &State<KeyPair>) -> Json<VerificationKeyResponse> {
Json(VerificationKeyResponse::new(key_pair.verification_key()))
}
+1 -14
View File
@@ -2,7 +2,6 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::config::template::config_template; use crate::config::template::config_template;
use coconut_interface::{Base58, KeyPair};
use config::defaults::{ use config::defaults::{
default_api_endpoints, DEFAULT_EPOCH_LENGTH, DEFAULT_FIRST_EPOCH_START, default_api_endpoints, DEFAULT_EPOCH_LENGTH, DEFAULT_FIRST_EPOCH_START,
DEFAULT_MIXNET_CONTRACT_ADDRESS, DEFAULT_MIXNET_CONTRACT_ADDRESS,
@@ -80,9 +79,6 @@ pub struct Base {
/// Address of the validator contract managing the network /// Address of the validator contract managing the network
mixnet_contract_address: String, mixnet_contract_address: String,
// Avoid breaking derives for now
keypair_bs58: String,
} }
impl Default for Base { impl Default for Base {
@@ -92,7 +88,6 @@ impl Default for Base {
.parse() .parse()
.expect("default local validator is malformed!"), .expect("default local validator is malformed!"),
mixnet_contract_address: DEFAULT_MIXNET_CONTRACT_ADDRESS.to_string(), mixnet_contract_address: DEFAULT_MIXNET_CONTRACT_ADDRESS.to_string(),
keypair_bs58: String::default(),
} }
} }
} }
@@ -254,10 +249,6 @@ impl Config {
Config::default() Config::default()
} }
pub fn keypair(&self) -> KeyPair {
KeyPair::try_from_bs58(self.base.keypair_bs58.clone()).unwrap()
}
pub fn with_network_monitor_enabled(mut self, enabled: bool) -> Self { pub fn with_network_monitor_enabled(mut self, enabled: bool) -> Self {
self.network_monitor.enabled = enabled; self.network_monitor.enabled = enabled;
self self
@@ -298,11 +289,6 @@ impl Config {
self self
} }
pub fn with_keypair<S: Into<String>>(mut self, keypair_bs58: S) -> Self {
self.base.keypair_bs58 = keypair_bs58.into();
self
}
pub fn with_custom_validator_apis(mut self, validator_api_urls: Vec<Url>) -> Self { pub fn with_custom_validator_apis(mut self, validator_api_urls: Vec<Url>) -> Self {
self.network_monitor.all_validator_apis = validator_api_urls; self.network_monitor.all_validator_apis = validator_api_urls;
self self
@@ -391,6 +377,7 @@ impl Config {
self.node_status_api.database_path.clone() self.node_status_api.database_path.clone()
} }
#[allow(dead_code)]
pub fn get_all_validator_api_endpoints(&self) -> Vec<Url> { pub fn get_all_validator_api_endpoints(&self) -> Vec<Url> {
self.network_monitor.all_validator_apis.clone() self.network_monitor.all_validator_apis.clone()
} }
-3
View File
@@ -16,9 +16,6 @@ local_validator = '{{ base.local_validator }}'
# Address of the validator contract managing the network. # Address of the validator contract managing the network.
mixnet_contract_address = '{{ base.mixnet_contract_address }}' mixnet_contract_address = '{{ base.mixnet_contract_address }}'
# Mnemonic (currently of the network monitor) used for rewarding
mnemonic = '{{ base.mnemonic }}'
##### network monitor config options ##### ##### network monitor config options #####
[network_monitor] [network_monitor]
+4 -32
View File
@@ -12,11 +12,10 @@ use crate::nymd_client::Client;
use crate::rewarding::epoch::Epoch; use crate::rewarding::epoch::Epoch;
use crate::rewarding::Rewarder; use crate::rewarding::Rewarder;
use crate::storage::NodeStatusStorage; use crate::storage::NodeStatusStorage;
use ::config::{defaults::DEFAULT_VALIDATOR_API_PORT, NymConfig}; use ::config::NymConfig;
use anyhow::Result; use anyhow::Result;
use cache::ValidatorCache; use cache::ValidatorCache;
use clap::{App, Arg, ArgMatches}; use clap::{App, Arg, ArgMatches};
use coconut::InternalSignRequest;
use log::{info, warn}; use log::{info, warn};
use rocket::fairing::AdHoc; use rocket::fairing::AdHoc;
use rocket::http::Method; use rocket::http::Method;
@@ -32,7 +31,6 @@ use url::Url;
use validator_client::nymd::SigningNymdClient; use validator_client::nymd::SigningNymdClient;
pub(crate) mod cache; pub(crate) mod cache;
mod coconut;
pub(crate) mod config; pub(crate) mod config;
mod network_monitor; mod network_monitor;
mod node_status_api; mod node_status_api;
@@ -49,7 +47,6 @@ const DETAILED_REPORT_ARG: &str = "detailed-report";
const MIXNET_CONTRACT_ARG: &str = "mixnet-contract"; const MIXNET_CONTRACT_ARG: &str = "mixnet-contract";
const MNEMONIC_ARG: &str = "mnemonic"; const MNEMONIC_ARG: &str = "mnemonic";
const WRITE_CONFIG_ARG: &str = "save-config"; const WRITE_CONFIG_ARG: &str = "save-config";
const KEYPAIR_ARG: &str = "keypair";
const NYMD_VALIDATOR_ARG: &str = "nymd-validator"; const NYMD_VALIDATOR_ARG: &str = "nymd-validator";
const EPOCH_LENGTH_ARG: &str = "epoch-length"; const EPOCH_LENGTH_ARG: &str = "epoch-length";
@@ -89,14 +86,13 @@ fn parse_args<'a>() -> ArgMatches<'a> {
Arg::with_name(V4_TOPOLOGY_ARG) Arg::with_name(V4_TOPOLOGY_ARG)
.help("location of .json file containing IPv4 'good' network topology") .help("location of .json file containing IPv4 'good' network topology")
.long(V4_TOPOLOGY_ARG) .long(V4_TOPOLOGY_ARG)
.requires(MONITORING_ENABLED) .takes_value(true)
) )
.arg( .arg(
Arg::with_name(V6_TOPOLOGY_ARG) Arg::with_name(V6_TOPOLOGY_ARG)
.help("location of .json file containing IPv6 'good' network topology") .help("location of .json file containing IPv6 'good' network topology")
.long(V6_TOPOLOGY_ARG) .long(V6_TOPOLOGY_ARG)
.takes_value(true) .takes_value(true)
.requires(MONITORING_ENABLED)
) )
.arg( .arg(
Arg::with_name(NYMD_VALIDATOR_ARG) Arg::with_name(NYMD_VALIDATOR_ARG)
@@ -119,13 +115,11 @@ fn parse_args<'a>() -> ArgMatches<'a> {
.long(MNEMONIC_ARG) .long(MNEMONIC_ARG)
.help("Mnemonic of the network monitor used for rewarding operators") .help("Mnemonic of the network monitor used for rewarding operators")
.takes_value(true) .takes_value(true)
.requires(REWARDING_ENABLED),
) )
.arg( .arg(
Arg::with_name(DETAILED_REPORT_ARG) Arg::with_name(DETAILED_REPORT_ARG)
.help("specifies whether a detailed report should be printed after each run") .help("specifies whether a detailed report should be printed after each run")
.long(DETAILED_REPORT_ARG) .long(DETAILED_REPORT_ARG)
.requires(MONITORING_ENABLED)
) )
.arg( .arg(
Arg::with_name(WRITE_CONFIG_ARG) Arg::with_name(WRITE_CONFIG_ARG)
@@ -133,32 +127,23 @@ fn parse_args<'a>() -> ArgMatches<'a> {
.long(WRITE_CONFIG_ARG) .long(WRITE_CONFIG_ARG)
.short("w") .short("w")
) )
.arg(
Arg::with_name(KEYPAIR_ARG)
.help("Path to the secret key file")
.takes_value(true)
.long(KEYPAIR_ARG)
)
.arg( .arg(
Arg::with_name(FIRST_REWARDING_EPOCH_ARG) Arg::with_name(FIRST_REWARDING_EPOCH_ARG)
.help("Datetime specifying beginning of the first rewarding epoch of this length. It must be a valid rfc3339 datetime.") .help("Datetime specifying beginning of the first rewarding epoch of this length. It must be a valid rfc3339 datetime.")
.takes_value(true) .takes_value(true)
.long(FIRST_REWARDING_EPOCH_ARG) .long(FIRST_REWARDING_EPOCH_ARG)
.requires(REWARDING_ENABLED)
) )
.arg( .arg(
Arg::with_name(EPOCH_LENGTH_ARG) Arg::with_name(EPOCH_LENGTH_ARG)
.help("Length of the current rewarding epoch in hours") .help("Length of the current rewarding epoch in hours")
.takes_value(true) .takes_value(true)
.long(EPOCH_LENGTH_ARG) .long(EPOCH_LENGTH_ARG)
.requires(REWARDING_ENABLED)
) )
.arg( .arg(
Arg::with_name(REWARDING_MONITOR_THRESHOLD_ARG) Arg::with_name(REWARDING_MONITOR_THRESHOLD_ARG)
.help("Specifies the minimum percentage of monitor test run data present in order to distribute rewards for given epoch.") .help("Specifies the minimum percentage of monitor test run data present in order to distribute rewards for given epoch.")
.takes_value(true) .takes_value(true)
.long(REWARDING_MONITOR_THRESHOLD_ARG) .long(REWARDING_MONITOR_THRESHOLD_ARG)
.requires(REWARDING_ENABLED)
) )
.get_matches() .get_matches()
@@ -264,13 +249,6 @@ fn override_config(mut config: Config, matches: &ArgMatches) -> Config {
if matches.is_present(DETAILED_REPORT_ARG) { if matches.is_present(DETAILED_REPORT_ARG) {
config = config.with_detailed_network_monitor_report(true) config = config.with_detailed_network_monitor_report(true)
} }
if let Some(keypair_path) = matches.value_of(KEYPAIR_ARG) {
let keypair_bs58 = std::fs::read_to_string(keypair_path)
.unwrap()
.trim()
.to_string();
config = config.with_keypair(keypair_bs58)
}
if matches.is_present(WRITE_CONFIG_ARG) { if matches.is_present(WRITE_CONFIG_ARG) {
info!("Saving the configuration to a file"); info!("Saving the configuration to a file");
@@ -374,16 +352,10 @@ fn setup_rewarder(
async fn setup_rocket(config: &Config, liftoff_notify: Arc<Notify>) -> Result<Rocket<Ignite>> { async fn setup_rocket(config: &Config, liftoff_notify: Arc<Notify>) -> Result<Rocket<Ignite>> {
// let's build our rocket! // let's build our rocket!
let rocket_config = rocket::config::Config { let rocket = rocket::build()
// TODO: probably the port should be configurable?
port: DEFAULT_VALIDATOR_API_PORT,
..Default::default()
};
let rocket = rocket::custom(rocket_config)
.attach(setup_cors()?) .attach(setup_cors()?)
.attach(setup_liftoff_notify(liftoff_notify)) .attach(setup_liftoff_notify(liftoff_notify))
.attach(ValidatorCache::stage()) .attach(ValidatorCache::stage());
.attach(InternalSignRequest::stage(config.keypair()));
// see if we should start up network monitor and if so, attach the node status api // see if we should start up network monitor and if so, attach the node status api
if config.get_network_monitor_enabled() { if config.get_network_monitor_enabled() {
-36
View File
@@ -15,9 +15,6 @@ use crate::network_monitor::monitor::summary_producer::SummaryProducer;
use crate::network_monitor::monitor::Monitor; use crate::network_monitor::monitor::Monitor;
use crate::network_monitor::tested_network::TestedNetwork; use crate::network_monitor::tested_network::TestedNetwork;
use crate::storage::NodeStatusStorage; use crate::storage::NodeStatusStorage;
use coconut_interface::Credential;
use credentials::bandwidth::prepare_for_spending;
use credentials::obtain_aggregate_verification_key;
use crypto::asymmetric::{encryption, identity}; use crypto::asymmetric::{encryption, identity};
use futures::channel::mpsc; use futures::channel::mpsc;
use log::info; use log::info;
@@ -90,14 +87,10 @@ impl<'a> NetworkMonitorBuilder<'a> {
*encryption_keypair.public_key(), *encryption_keypair.public_key(),
); );
let bandwidth_credential =
TEMPORARY_obtain_bandwidth_credential(self.config, identity_keypair.public_key()).await;
let packet_sender = new_packet_sender( let packet_sender = new_packet_sender(
self.config, self.config,
gateway_status_update_sender, gateway_status_update_sender,
Arc::clone(&identity_keypair), Arc::clone(&identity_keypair),
bandwidth_credential,
self.config.get_gateway_sending_rate(), self.config.get_gateway_sending_rate(),
); );
@@ -161,44 +154,15 @@ fn new_packet_preparer(
) )
} }
// SECURITY:
// this implies we are re-using the same credential for all gateways all the time (which unfortunately is true!)
#[allow(non_snake_case)]
async fn TEMPORARY_obtain_bandwidth_credential(
config: &Config,
identity: &identity::PublicKey,
) -> Credential {
info!("Trying to obtain bandwidth credential...");
let validators = config.get_all_validator_api_endpoints();
let verification_key = obtain_aggregate_verification_key(&validators)
.await
.expect("could not obtain aggregate verification key of ALL validators");
let bandwidth_credential =
credentials::bandwidth::obtain_signature(&identity.to_bytes(), &validators)
.await
.expect("failed to obtain bandwidth credential!");
prepare_for_spending(
&identity.to_bytes(),
&bandwidth_credential,
&verification_key,
)
.expect("failed to prepare bandwidth credential for spending!")
}
fn new_packet_sender( fn new_packet_sender(
config: &Config, config: &Config,
gateways_status_updater: GatewayClientUpdateSender, gateways_status_updater: GatewayClientUpdateSender,
local_identity: Arc<identity::KeyPair>, local_identity: Arc<identity::KeyPair>,
bandwidth_credential: Credential,
max_sending_rate: usize, max_sending_rate: usize,
) -> PacketSender { ) -> PacketSender {
PacketSender::new( PacketSender::new(
gateways_status_updater, gateways_status_updater,
local_identity, local_identity,
bandwidth_credential,
config.get_gateway_response_timeout(), config.get_gateway_response_timeout(),
config.get_gateway_connection_timeout(), config.get_gateway_connection_timeout(),
config.get_max_concurrent_gateway_clients(), config.get_max_concurrent_gateway_clients(),
@@ -2,7 +2,6 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::network_monitor::monitor::receiver::{GatewayClientUpdate, GatewayClientUpdateSender}; use crate::network_monitor::monitor::receiver::{GatewayClientUpdate, GatewayClientUpdateSender};
use coconut_interface::Credential;
use crypto::asymmetric::identity::{self, PUBLIC_KEY_LENGTH}; use crypto::asymmetric::identity::{self, PUBLIC_KEY_LENGTH};
use futures::channel::mpsc; use futures::channel::mpsc;
use futures::stream::{self, FuturesUnordered, StreamExt}; use futures::stream::{self, FuturesUnordered, StreamExt};
@@ -63,15 +62,6 @@ struct FreshGatewayClientData {
gateways_status_updater: GatewayClientUpdateSender, gateways_status_updater: GatewayClientUpdateSender,
local_identity: Arc<identity::KeyPair>, local_identity: Arc<identity::KeyPair>,
gateway_response_timeout: Duration, gateway_response_timeout: Duration,
// I guess in the future this struct will require aggregated verification key and....
// ... something for obtaining actual credential
// TODO:
// SECURITY:
// since currently we have no double spending protection, just to get things running
// we're re-using the same credential for all gateways all the time. THIS IS VERY BAD!!
bandwidth_credential: Credential,
} }
pub(crate) struct PacketSender { pub(crate) struct PacketSender {
@@ -93,7 +83,6 @@ impl PacketSender {
pub(crate) fn new( pub(crate) fn new(
gateways_status_updater: GatewayClientUpdateSender, gateways_status_updater: GatewayClientUpdateSender,
local_identity: Arc<identity::KeyPair>, local_identity: Arc<identity::KeyPair>,
bandwidth_credential: Credential,
gateway_response_timeout: Duration, gateway_response_timeout: Duration,
gateway_connection_timeout: Duration, gateway_connection_timeout: Duration,
max_concurrent_clients: usize, max_concurrent_clients: usize,
@@ -105,7 +94,6 @@ impl PacketSender {
gateways_status_updater, gateways_status_updater,
local_identity, local_identity,
gateway_response_timeout, gateway_response_timeout,
bandwidth_credential,
}), }),
gateway_connection_timeout, gateway_connection_timeout,
max_concurrent_clients, max_concurrent_clients,
@@ -137,7 +125,6 @@ impl PacketSender {
message_sender, message_sender,
ack_sender, ack_sender,
fresh_gateway_client_data.gateway_response_timeout, fresh_gateway_client_data.gateway_response_timeout,
fresh_gateway_client_data.bandwidth_credential.clone(),
), ),
(message_receiver, ack_receiver), (message_receiver, ack_receiver),
) )
+80 -18
View File
@@ -10,7 +10,9 @@ use crate::rewarding::{
use config::defaults::DEFAULT_VALIDATOR_API_PORT; use config::defaults::DEFAULT_VALIDATOR_API_PORT;
use mixnet_contract::{Delegation, ExecuteMsg, GatewayBond, IdentityKey, MixNodeBond}; use mixnet_contract::{Delegation, ExecuteMsg, GatewayBond, IdentityKey, MixNodeBond};
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration;
use tokio::sync::RwLock; use tokio::sync::RwLock;
use tokio::time::sleep;
use validator_client::nymd::{ use validator_client::nymd::{
CosmWasmClient, Fee, QueryNymdClient, SigningCosmWasmClient, SigningNymdClient, TendermintTime, CosmWasmClient, Fee, QueryNymdClient, SigningCosmWasmClient, SigningNymdClient, TendermintTime,
}; };
@@ -186,16 +188,46 @@ impl<C> Client<C> {
.get_mixnet_contract_address() .get_mixnet_contract_address()
.ok_or(RewardingError::UnspecifiedContractAddress)?; .ok_or(RewardingError::UnspecifiedContractAddress)?;
// technically we don't require a write lock here, however, we really don't want to be executing // grab the write lock here so we're sure nothing else is executing anything on the contract
// multiple blocks concurrently as one of them WILL fail due to incorrect sequence number // in the meantime
self.0 // however, we're not 100% guarded against everything
.write() // for example somebody might have taken the mnemonic used by the validator
.await // and sent a transaction manually using the same account. The sequence number
.nymd // would have gotten incremented, yet the rewarding transaction might have actually not
.execute_multiple(&contract, msgs, fee, memo) // been included in the block. sadly we can't do much about that.
.await?; let client_guard = self.0.write().await;
let pre_sequence = client_guard.nymd.account_sequence().await?;
Ok(()) let res = client_guard
.nymd
.execute_multiple(&contract, msgs.clone(), fee.clone(), memo.clone())
.await;
match res {
Ok(_) => Ok(()),
Err(err) => {
if err.is_tendermint_timeout() {
// wait until we're sure we're into the next block (remember we're holding the lock)
sleep(Duration::from_secs(11)).await;
let curr_sequence = client_guard.nymd.account_sequence().await?;
if curr_sequence.sequence > pre_sequence.sequence {
// unless somebody was messing around doing stuff manually in that tiny time interval
// we're good. It was a false negative.
Ok(())
} else {
// the sequence number has not increased, meaning the transaction was not executed
// so attempt to send it again
client_guard
.nymd
.execute_multiple(&contract, msgs, fee, memo)
.await?;
Ok(())
}
} else {
Err(err.into())
}
}
}
} }
pub(crate) async fn reward_gateways( pub(crate) async fn reward_gateways(
@@ -224,15 +256,45 @@ impl<C> Client<C> {
.get_mixnet_contract_address() .get_mixnet_contract_address()
.ok_or(RewardingError::UnspecifiedContractAddress)?; .ok_or(RewardingError::UnspecifiedContractAddress)?;
// technically we don't require a write lock here, however, we really don't want to be executing // grab the write lock here so we're sure nothing else is executing anything on the contract
// multiple blocks concurrently as one of them WILL fail due to incorrect sequence number // in the meantime
self.0 // however, we're not 100% guarded against everything
.write() // for example somebody might have taken the mnemonic used by the validator
.await // and sent a transaction manually using the same account. The sequence number
.nymd // would have gotten incremented, yet the rewarding transaction might have actually not
.execute_multiple(&contract, msgs, fee, memo) // been included in the block. sadly we can't do much about that.
.await?; let client_guard = self.0.write().await;
let pre_sequence = client_guard.nymd.account_sequence().await?;
Ok(()) let res = client_guard
.nymd
.execute_multiple(&contract, msgs.clone(), fee.clone(), memo.clone())
.await;
match res {
Ok(_) => Ok(()),
Err(err) => {
if err.is_tendermint_timeout() {
// wait until we're sure we're into the next block (remember we're holding the lock)
sleep(Duration::from_secs(11)).await;
let curr_sequence = client_guard.nymd.account_sequence().await?;
if curr_sequence.sequence > pre_sequence.sequence {
// unless somebody was messing around doing stuff manually in that tiny time interval
// we're good. It was a false negative.
Ok(())
} else {
// the sequence number has not increased, meaning the transaction was not executed
// so attempt to send it again
client_guard
.nymd
.execute_multiple(&contract, msgs, fee, memo)
.await?;
Ok(())
}
} else {
Err(err.into())
}
}
}
} }
} }
+11
View File
@@ -45,3 +45,14 @@ impl From<ValidatorClientError> for RewardingError {
RewardingError::ValidatorClientError(err) RewardingError::ValidatorClientError(err)
} }
} }
impl RewardingError {
pub fn is_tendermint_duplicate(&self) -> bool {
match &self {
RewardingError::ValidatorClientError(ValidatorClientError::NymdError(nymd_err)) => {
nymd_err.is_tendermint_duplicate()
}
_ => false,
}
}
}
+22 -10
View File
@@ -374,11 +374,17 @@ impl Rewarder {
for (i, mix_chunk) in eligible_mixnodes.chunks(MAX_TO_REWARD_AT_ONCE).enumerate() { for (i, mix_chunk) in eligible_mixnodes.chunks(MAX_TO_REWARD_AT_ONCE).enumerate() {
if let Err(err) = self.nymd_client.reward_mixnodes(mix_chunk).await { if let Err(err) = self.nymd_client.reward_mixnodes(mix_chunk).await {
error!("failed to reward mixnodes... - {}", err); // this is a super weird edge case that we didn't catch change to sequence and
failed_chunks.push(FailedMixnodeRewardChunkDetails { // resent rewards unnecessarily, but the mempool saved us from executing it again
possibly_unrewarded: mix_chunk.to_vec(), // however, still we want to wait until we're sure we're into the next block
error_message: err.to_string(), if !err.is_tendermint_duplicate() {
}) error!("failed to reward mixnodes... - {}", err);
failed_chunks.push(FailedMixnodeRewardChunkDetails {
possibly_unrewarded: mix_chunk.to_vec(),
error_message: err.to_string(),
});
}
sleep(Duration::from_secs(11)).await;
} }
let rewarded = i * MAX_TO_REWARD_AT_ONCE + mix_chunk.len(); let rewarded = i * MAX_TO_REWARD_AT_ONCE + mix_chunk.len();
let percentage = rewarded as f32 * 100.0 / eligible_mixnodes.len() as f32; let percentage = rewarded as f32 * 100.0 / eligible_mixnodes.len() as f32;
@@ -419,11 +425,17 @@ impl Rewarder {
for (i, gateway_chunk) in eligible_gateways.chunks(MAX_TO_REWARD_AT_ONCE).enumerate() { for (i, gateway_chunk) in eligible_gateways.chunks(MAX_TO_REWARD_AT_ONCE).enumerate() {
if let Err(err) = self.nymd_client.reward_gateways(gateway_chunk).await { if let Err(err) = self.nymd_client.reward_gateways(gateway_chunk).await {
error!("failed to reward gateways... - {}", err); // this is a super weird edge case that we didn't catch change to sequence and
failed_chunks.push(FailedGatewayRewardChunkDetails { // resent rewards unnecessarily, but the mempool saved us from executing it again
possibly_unrewarded: gateway_chunk.to_vec(), // however, still we want to wait until we're sure we're into the next block
error_message: err.to_string(), if !err.is_tendermint_duplicate() {
}) error!("failed to reward gateways... - {}", err);
failed_chunks.push(FailedGatewayRewardChunkDetails {
possibly_unrewarded: gateway_chunk.to_vec(),
error_message: err.to_string(),
});
}
sleep(Duration::from_secs(11)).await;
} }
let rewarded = i * MAX_TO_REWARD_AT_ONCE + gateway_chunk.len(); let rewarded = i * MAX_TO_REWARD_AT_ONCE + gateway_chunk.len();