From 7d82fe0c0d570285eb04f17e4e8bda00a47fa8c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 24 May 2022 10:52:00 +0200 Subject: [PATCH] Feature/various improvements (#1282) * Added abci::Data field to ExecuteResult * optional serde support for ed25519 keys * optional serde support for x25519 keys * actually calling dotenv at validator API startup * Added STATE_DENOM network specific constant * unit test fixes --- Cargo.lock | 8 +- .../nymd/cosmwasm_client/signing_client.rs | 2 + .../src/nymd/cosmwasm_client/types.rs | 3 + common/credentials/src/coconut/bandwidth.rs | 5 +- common/crypto/Cargo.toml | 3 + .../crypto/src/asymmetric/encryption/mod.rs | 47 +++++++++++- common/crypto/src/asymmetric/identity/mod.rs | 75 ++++++++++++++++++- common/crypto/src/lib.rs | 4 +- common/network-defaults/src/lib.rs | 3 + common/network-defaults/src/mainnet.rs | 1 + common/network-defaults/src/qa.rs | 1 + common/network-defaults/src/sandbox.rs | 1 + .../network-requester/src/core.rs | 2 +- .../network-requester/src/storage/mod.rs | 4 +- validator-api/src/coconut/deposit.rs | 5 +- validator-api/src/coconut/tests.rs | 10 ++- validator-api/src/main.rs | 2 + 17 files changed, 163 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3391dfb4b3..cd20c29c44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1063,6 +1063,8 @@ dependencies = [ "pemstore", "rand 0.7.3", "rand_chacha 0.2.2", + "serde", + "serde_bytes", "subtle-encoding", "x25519-dalek", ] @@ -1427,6 +1429,7 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d5c4b5e5959dc2c2b89918d8e2cc40fcdd623cef026ed09d2f0ee05199dc8e4" dependencies = [ + "serde", "signature", ] @@ -1440,6 +1443,7 @@ dependencies = [ "ed25519", "rand 0.7.3", "serde", + "serde_bytes", "sha2", "zeroize", ] @@ -4835,9 +4839,9 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" +checksum = "212e73464ebcde48d723aa02eb270ba62eff38a9b732df31f33f1b4e145f3a54" dependencies = [ "serde", ] diff --git a/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs b/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs index 50e72eaeae..50b0f9dfe6 100644 --- a/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs +++ b/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs @@ -324,6 +324,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient { Ok(ExecuteResult { logs: parse_raw_logs(tx_res.tx_result.log)?, + data: tx_res.tx_result.data, transaction_hash: tx_res.hash, gas_info, }) @@ -364,6 +365,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient { Ok(ExecuteResult { logs: parse_raw_logs(tx_res.tx_result.log)?, + data: tx_res.tx_result.data, transaction_hash: tx_res.hash, gas_info, }) diff --git a/common/client-libs/validator-client/src/nymd/cosmwasm_client/types.rs b/common/client-libs/validator-client/src/nymd/cosmwasm_client/types.rs index 89373141d4..f928857c7e 100644 --- a/common/client-libs/validator-client/src/nymd/cosmwasm_client/types.rs +++ b/common/client-libs/validator-client/src/nymd/cosmwasm_client/types.rs @@ -25,6 +25,7 @@ use cosmrs::proto::cosmwasm::wasm::v1::{ CodeInfoResponse, ContractCodeHistoryEntry as ProtoContractCodeHistoryEntry, ContractCodeHistoryOperationType, ContractInfo as ProtoContractInfo, }; +use cosmrs::tendermint::abci::Data; use cosmrs::tendermint::{abci, chain}; use cosmrs::tx::{AccountNumber, Gas, SequenceNumber}; use cosmrs::{tx, AccountId, Any, Coin}; @@ -672,6 +673,8 @@ pub struct MigrateResult { pub struct ExecuteResult { pub logs: Vec, + pub data: Data, + /// Transaction hash (might be used as transaction ID) pub transaction_hash: tx::Hash, diff --git a/common/credentials/src/coconut/bandwidth.rs b/common/credentials/src/coconut/bandwidth.rs index 23c357188d..ed38fbb14c 100644 --- a/common/credentials/src/coconut/bandwidth.rs +++ b/common/credentials/src/coconut/bandwidth.rs @@ -204,7 +204,10 @@ mod test { .to_base58_string(), ) .unwrap(), - encryption::KeyPair::new(&mut rng).private_key().clone(), + encryption::PrivateKey::from_bytes( + &encryption::KeyPair::new(&mut rng).private_key().to_bytes(), + ) + .unwrap(), ); assert!(!BandwidthVoucher::verify_against_plain( &[], diff --git a/common/crypto/Cargo.toml b/common/crypto/Cargo.toml index af5d24b904..c0b7d29bcc 100644 --- a/common/crypto/Cargo.toml +++ b/common/crypto/Cargo.toml @@ -19,6 +19,8 @@ cipher = { version = "0.4.3", optional = true } x25519-dalek = { version = "1.1", optional = true } ed25519-dalek = { version = "1.0", optional = true } rand = { version = "0.7.3", features = ["wasm-bindgen"], optional = true } +serde_bytes = { version = "0.11.6", optional = true } +serde_crate = { version = "1.0", optional = true, default_features = false, package = "serde" } subtle-encoding = { version = "0.5", features = ["bech32-preview"]} # internal @@ -30,6 +32,7 @@ config = { path="../../common/config" } rand_chacha = "0.2" [features] +serde = ["serde_crate", "serde_bytes", "ed25519-dalek/serde", "x25519-dalek/serde"] asymmetric = ["x25519-dalek", "ed25519-dalek"] hashing = ["blake3", "digest", "hkdf", "hmac", "generic-array"] symmetric = ["aes", "ctr", "cipher", "generic-array"] diff --git a/common/crypto/src/asymmetric/encryption/mod.rs b/common/crypto/src/asymmetric/encryption/mod.rs index 5e3a4897e4..5c7b5398ad 100644 --- a/common/crypto/src/asymmetric/encryption/mod.rs +++ b/common/crypto/src/asymmetric/encryption/mod.rs @@ -4,6 +4,8 @@ use pemstore::traits::{PemStorableKey, PemStorableKeyPair}; #[cfg(feature = "rand")] use rand::{CryptoRng, RngCore}; +#[cfg(feature = "serde")] +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt::{self, Display, Formatter}; /// Size of a X25519 private key @@ -127,6 +129,28 @@ impl PublicKey { } } +#[cfg(feature = "serde")] +impl Serialize for PublicKey { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +#[cfg(feature = "serde")] +impl<'d> Deserialize<'d> for PublicKey { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'d>, + { + Ok(PublicKey(x25519_dalek::PublicKey::deserialize( + deserializer, + )?)) + } +} + impl PemStorableKey for PublicKey { type Error = KeyRecoveryError; @@ -143,7 +167,6 @@ impl PemStorableKey for PublicKey { } } -#[derive(Clone)] pub struct PrivateKey(x25519_dalek::StaticSecret); impl Display for PrivateKey { @@ -187,6 +210,28 @@ impl PrivateKey { } } +#[cfg(feature = "serde")] +impl Serialize for PrivateKey { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +#[cfg(feature = "serde")] +impl<'d> Deserialize<'d> for PrivateKey { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'d>, + { + Ok(PrivateKey(x25519_dalek::StaticSecret::deserialize( + deserializer, + )?)) + } +} + impl PemStorableKey for PrivateKey { type Error = KeyRecoveryError; diff --git a/common/crypto/src/asymmetric/identity/mod.rs b/common/crypto/src/asymmetric/identity/mod.rs index d020d1953f..8ba1de8ec6 100644 --- a/common/crypto/src/asymmetric/identity/mod.rs +++ b/common/crypto/src/asymmetric/identity/mod.rs @@ -10,6 +10,13 @@ use pemstore::traits::{PemStorableKey, PemStorableKeyPair}; use rand::{CryptoRng, RngCore}; use std::fmt::{self, Display, Formatter}; +#[cfg(feature = "serde")] +use serde::de::Error as SerdeError; +#[cfg(feature = "serde")] +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +#[cfg(feature = "serde")] +use serde_bytes::{ByteBuf as SerdeByteBuf, Bytes as SerdeBytes}; + #[derive(Debug)] pub enum Ed25519RecoveryError { MalformedBytes(SignatureError), @@ -40,6 +47,7 @@ impl fmt::Display for Ed25519RecoveryError { impl std::error::Error for Ed25519RecoveryError {} /// Keypair for usage in ed25519 EdDSA. +#[derive(Debug)] pub struct KeyPair { private_key: PrivateKey, public_key: PublicKey, @@ -135,6 +143,28 @@ impl PublicKey { } } +#[cfg(feature = "serde")] +impl Serialize for PublicKey { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +#[cfg(feature = "serde")] +impl<'d> Deserialize<'d> for PublicKey { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'d>, + { + Ok(PublicKey(ed25519_dalek::PublicKey::deserialize( + deserializer, + )?)) + } +} + impl PemStorableKey for PublicKey { type Error = Ed25519RecoveryError; @@ -200,6 +230,28 @@ impl PrivateKey { } } +#[cfg(feature = "serde")] +impl Serialize for PrivateKey { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +#[cfg(feature = "serde")] +impl<'d> Deserialize<'d> for PrivateKey { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'d>, + { + Ok(PrivateKey(ed25519_dalek::SecretKey::deserialize( + deserializer, + )?)) + } +} + impl PemStorableKey for PrivateKey { type Error = Ed25519RecoveryError; @@ -216,7 +268,7 @@ impl PemStorableKey for PrivateKey { } } -#[derive(Debug)] +#[derive(Copy, Clone, Debug)] pub struct Signature(ed25519_dalek::Signature); impl Signature { @@ -237,3 +289,24 @@ impl Signature { Ok(Signature(ed25519_dalek::Signature::from_bytes(bytes)?)) } } + +#[cfg(feature = "serde")] +impl Serialize for Signature { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + SerdeBytes::new(&self.to_bytes()).serialize(serializer) + } +} + +#[cfg(feature = "serde")] +impl<'d> Deserialize<'d> for Signature { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'d>, + { + let bytes = ::deserialize(deserializer)?; + Signature::from_bytes(bytes.as_ref()).map_err(SerdeError::custom) + } +} diff --git a/common/crypto/src/lib.rs b/common/crypto/src/lib.rs index 456c4358fd..19aab595d4 100644 --- a/common/crypto/src/lib.rs +++ b/common/crypto/src/lib.rs @@ -29,5 +29,5 @@ pub use blake3; #[cfg(feature = "symmetric")] pub use ctr; -// TODO: this function uses all three modules: asymmetric crypto, symmetric crypto and derives key..., -// so I don't know where to put it... +#[cfg(feature = "serde")] +extern crate serde_crate as serde; diff --git a/common/network-defaults/src/lib.rs b/common/network-defaults/src/lib.rs index 8c4e397050..a992d5bed6 100644 --- a/common/network-defaults/src/lib.rs +++ b/common/network-defaults/src/lib.rs @@ -18,6 +18,7 @@ cfg_if::cfg_if! { if #[cfg(network = "mainnet")] { pub const DEFAULT_NETWORK: all::Network = all::Network::MAINNET; pub const DENOM: &str = mainnet::DENOM; + pub const STAKE_DENOM: &str = mainnet::STAKE_DENOM; pub const ETH_CONTRACT_ADDRESS: [u8; 20] = mainnet::_ETH_CONTRACT_ADDRESS; pub const ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] = mainnet::_ETH_ERC20_CONTRACT_ADDRESS; @@ -25,6 +26,7 @@ cfg_if::cfg_if! { } else if #[cfg(network = "qa")] { pub const DEFAULT_NETWORK: all::Network = all::Network::QA; pub const DENOM: &str = qa::DENOM; + pub const STAKE_DENOM: &str = qa::STAKE_DENOM; pub const ETH_CONTRACT_ADDRESS: [u8; 20] = qa::_ETH_CONTRACT_ADDRESS; pub const ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] = qa::_ETH_ERC20_CONTRACT_ADDRESS; @@ -32,6 +34,7 @@ cfg_if::cfg_if! { } else if #[cfg(network = "sandbox")] { pub const DEFAULT_NETWORK: all::Network = all::Network::SANDBOX; pub const DENOM: &str = sandbox::DENOM; + pub const STAKE_DENOM: &str = sandbox::STAKE_DENOM; pub const ETH_CONTRACT_ADDRESS: [u8; 20] = sandbox::_ETH_CONTRACT_ADDRESS; pub const ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] = sandbox::_ETH_ERC20_CONTRACT_ADDRESS; diff --git a/common/network-defaults/src/mainnet.rs b/common/network-defaults/src/mainnet.rs index b70df6f735..69f34c92a2 100644 --- a/common/network-defaults/src/mainnet.rs +++ b/common/network-defaults/src/mainnet.rs @@ -5,6 +5,7 @@ use crate::ValidatorDetails; pub(crate) const BECH32_PREFIX: &str = "n"; pub const DENOM: &str = "unym"; +pub const STAKE_DENOM: &str = "unyx"; pub(crate) const MIXNET_CONTRACT_ADDRESS: &str = "n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g"; diff --git a/common/network-defaults/src/qa.rs b/common/network-defaults/src/qa.rs index 5bf6fa1720..38ada60537 100644 --- a/common/network-defaults/src/qa.rs +++ b/common/network-defaults/src/qa.rs @@ -5,6 +5,7 @@ use crate::ValidatorDetails; pub(crate) const BECH32_PREFIX: &str = "n"; pub const DENOM: &str = "unym"; +pub const STAKE_DENOM: &str = "unyx"; pub(crate) const MIXNET_CONTRACT_ADDRESS: &str = "n1suhgf5svhu4usrurvxzlgn54ksxmn8gljarjtxqnapv8kjnp4nrsd3qaep"; diff --git a/common/network-defaults/src/sandbox.rs b/common/network-defaults/src/sandbox.rs index 28c25c792b..3ec1f746a9 100644 --- a/common/network-defaults/src/sandbox.rs +++ b/common/network-defaults/src/sandbox.rs @@ -5,6 +5,7 @@ use crate::ValidatorDetails; pub(crate) const BECH32_PREFIX: &str = "nymt"; pub const DENOM: &str = "unymt"; +pub const STAKE_DENOM: &str = "unyxt"; pub(crate) const MIXNET_CONTRACT_ADDRESS: &str = "nymt1ghd753shjuwexxywmgs4xz7x2q732vcnstz02j"; pub(crate) const VESTING_CONTRACT_ADDRESS: &str = "nymt14ejqjyq8um4p3xfqj74yld5waqljf88fn549lh"; diff --git a/service-providers/network-requester/src/core.rs b/service-providers/network-requester/src/core.rs index b452f77aab..dd17a7cf38 100644 --- a/service-providers/network-requester/src/core.rs +++ b/service-providers/network-requester/src/core.rs @@ -308,7 +308,7 @@ impl ServiceProvider { }); #[cfg(feature = "stats-service")] - let storage = crate::storage::NetworkRequesterStorage::init(&self.db_path) + let storage = crate::storage::NetworkRequesterStorage::init(self.db_path.as_path()) .await .expect("Could not create network requester storage"); diff --git a/service-providers/network-requester/src/storage/mod.rs b/service-providers/network-requester/src/storage/mod.rs index 4e1f31ea83..2e35565d24 100644 --- a/service-providers/network-requester/src/storage/mod.rs +++ b/service-providers/network-requester/src/storage/mod.rs @@ -4,7 +4,7 @@ use log::*; use sqlx::types::chrono::{DateTime, Utc}; use sqlx::ConnectOptions; -use std::path::PathBuf; +use std::path::Path; use crate::statistics::StatsMessage; use crate::storage::error::NetworkRequesterStorageError; @@ -24,7 +24,7 @@ pub(crate) struct NetworkRequesterStorage { } impl NetworkRequesterStorage { - pub async fn init(database_path: &PathBuf) -> Result { + pub async fn init(database_path: &Path) -> Result { let mut opts = sqlx::sqlite::SqliteConnectOptions::new() .filename(database_path) .create_if_missing(true); diff --git a/validator-api/src/coconut/deposit.rs b/validator-api/src/coconut/deposit.rs index f773b60151..8c3dbcb899 100644 --- a/validator-api/src/coconut/deposit.rs +++ b/validator-api/src/coconut/deposit.rs @@ -121,7 +121,10 @@ mod test { .to_base58_string(), ) .unwrap(), - encryption::KeyPair::new(&mut rng).private_key().clone(), + encryption::PrivateKey::from_bytes( + &encryption::KeyPair::new(&mut rng).private_key().to_bytes(), + ) + .unwrap(), ); let (_, blind_sign_req) = prepare_blind_sign( ¶ms, diff --git a/validator-api/src/coconut/tests.rs b/validator-api/src/coconut/tests.rs index 4e5aaa5315..5f0c745a69 100644 --- a/validator-api/src/coconut/tests.rs +++ b/validator-api/src/coconut/tests.rs @@ -146,7 +146,10 @@ async fn signed_before() { .to_base58_string(), ) .unwrap(), - encryption::KeyPair::new(&mut rng).private_key().clone(), + encryption::PrivateKey::from_bytes( + &encryption::KeyPair::new(&mut rng).private_key().to_bytes(), + ) + .unwrap(), ); let (_, blind_sign_req) = prepare_blind_sign( ¶ms, @@ -342,7 +345,10 @@ async fn blind_sign_correct() { .to_base58_string(), ) .unwrap(), - encryption::KeyPair::new(&mut rng).private_key().clone(), + encryption::PrivateKey::from_bytes( + &encryption::KeyPair::new(&mut rng).private_key().to_bytes(), + ) + .unwrap(), ); let key_pair = ttp_keygen(¶ms, 1, 1).unwrap().remove(0); diff --git a/validator-api/src/main.rs b/validator-api/src/main.rs index 967419ccd1..461d11ab51 100644 --- a/validator-api/src/main.rs +++ b/validator-api/src/main.rs @@ -590,6 +590,8 @@ async fn run_validator_api(matches: ArgMatches<'static>) -> Result<()> { async fn main() -> Result<()> { println!("Starting validator api..."); + dotenv::dotenv()?; + cfg_if::cfg_if! {if #[cfg(feature = "console-subscriber")] { // instriment tokio console subscriber needs RUSTFLAGS="--cfg tokio_unstable" at build time console_subscriber::init();