Skip to content

Commit

Permalink
[fix] change type in configs from string to GenesisSignatureConfig; c…
Browse files Browse the repository at this point in the history
…hange how data is passed to compact & full peers

Signed-off-by: VAmuzing <amuzik95@gmail.com>
  • Loading branch information
VAmuzing committed Apr 23, 2024
1 parent f13897e commit 366dd70
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 40 deletions.
11 changes: 7 additions & 4 deletions cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,9 @@ mod tests {
use std::path::PathBuf;

use assertables::{assert_contains, assert_contains_as_result};
use iroha_config::parameters::user::RootPartial as PartialUserConfig;
use iroha_config::parameters::{
actual::GenesisSignatureConfig, user::RootPartial as PartialUserConfig,
};
use iroha_crypto::KeyPair;
use iroha_primitives::addr::socket_addr;
use path_absolutize::Absolutize as _;
Expand Down Expand Up @@ -682,9 +684,10 @@ mod tests {
genesis_block,
&cfg.chain_id.clone().get().unwrap(),
&keypair,
)
.to_hex_string();
cfg.genesis.signature.set(genesis_signature);
);
cfg.genesis
.signature
.set(GenesisSignatureConfig::new(genesis_signature));

cfg.kura.store_dir.set("../storage".into());
cfg.snapshot.store_dir.set("../snapshots".into());
Expand Down
4 changes: 2 additions & 2 deletions cli/src/samples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{collections::HashSet, path::Path, str::FromStr, time::Duration};
use iroha_config::{
base::{HumanDuration, UnwrapPartial},
parameters::{
actual::Root as Config,
actual::{GenesisSignatureConfig, Root as Config},
user::{CliContext, RootPartial as UserConfig},
},
snapshot::Mode as SnapshotMode,
Expand Down Expand Up @@ -96,7 +96,7 @@ pub fn get_user_config(
config
.genesis
.signature
.set(genesis_signature.to_hex_string());
.set(GenesisSignatureConfig::new(genesis_signature.clone()));
// There is no need in persistency in tests
// If required to should be set explicitly not to overlap with other existing tests
config.snapshot.mode.set(SnapshotMode::Disabled);
Expand Down
13 changes: 9 additions & 4 deletions config/src/parameters/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@
#![allow(missing_docs)]

use std::{
error::Error, fmt::Debug, fs::File, io::Read, num::{NonZeroU32, NonZeroUsize}, path::{Path, PathBuf}, str::FromStr, time::Duration
error::Error,
fmt::Debug,
fs::File,
io::Read,
num::{NonZeroU32, NonZeroUsize},
path::{Path, PathBuf},
time::Duration,
};

pub use boilerplate::*;
Expand Down Expand Up @@ -344,7 +350,7 @@ pub(crate) fn private_key_from_env<E: Error>(
pub struct Genesis {
pub public_key: PublicKey,
pub file: Option<PathBuf>,
pub signature: Option<String>,
pub signature: Option<GenesisSignatureConfig>,
}

impl Genesis {
Expand All @@ -356,8 +362,7 @@ impl Genesis {
(Some(file), Some(signature), true) => Ok(actual::Genesis::Full {
public_key: self.public_key,
file,
signature: GenesisSignatureConfig::from_str(&signature)
.map_err(GenesisConfigError::from)?,
signature,
}),
(_, _, false) => Err(GenesisConfigError::GenesisWithoutSubmit),
(_, _, true) => Err(GenesisConfigError::SubmitWithoutGenesis),
Expand Down
9 changes: 7 additions & 2 deletions config/src/parameters/user/boilerplate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ use crate::{
kura::InitMode as KuraInitMode,
logger::Format,
parameters::{
defaults::{self, chain_wide::*, network::*, queue::*, torii::*}, user::{self, ChainWide, DevTelemetry, Genesis, Kura, KuraDebug, Logger, Network, Queue, Root, Snapshot, Sumeragi, SumeragiDebug, Telemetry, Torii}
actual::GenesisSignatureConfig,
defaults::{self, chain_wide::*, network::*, queue::*, torii::*},
user::{
self, ChainWide, DevTelemetry, Genesis, Kura, KuraDebug, Logger, Network, Queue, Root,
Snapshot, Sumeragi, SumeragiDebug, Telemetry, Torii,
},
},
snapshot::Mode as SnapshotMode,
};
Expand Down Expand Up @@ -185,7 +190,7 @@ impl FromEnv for RootPartial {
pub struct GenesisPartial {
pub public_key: UserField<PublicKey>,
pub file: UserField<PathBuf>,
pub signature: UserField<String>,
pub signature: UserField<GenesisSignatureConfig>,
}

impl UnwrapPartial for GenesisPartial {
Expand Down
43 changes: 40 additions & 3 deletions genesis/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
//! Genesis-related logic and constructs. Contains the `GenesisBlock`,
//! `RawGenesisBlock` and the `RawGenesisBlockBuilder` structures.
use std::{
fmt::Debug,
fmt::{Debug, Formatter},
fs::{self, File},
io::BufReader,
path::{Path, PathBuf},
str::FromStr,
time::Duration,
};

Expand All @@ -19,7 +20,7 @@ use iroha_data_model::{
};
use once_cell::sync::Lazy;
use parity_scale_codec::{Decode, Encode};
use serde::{Deserialize, Serialize};
use serde::{de, Deserialize, Deserializer, Serialize};

/// [`DomainId`] of the genesis account.
pub static GENESIS_DOMAIN_ID: Lazy<DomainId> = Lazy::new(|| "genesis".parse().expect("Valid"));
Expand Down Expand Up @@ -56,13 +57,49 @@ pub enum GenesisSignatureParseError {
impl std::error::Error for GenesisSignatureParseError {}

/// [`SignedGenesisConfig`] contains data that is used for loading signed genesis from config.
#[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize)]
#[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Serialize)]
pub struct GenesisSignature {
chain_id: ChainId,
creation_time: Duration,
signatures: SignaturesOf<TransactionPayload>,
}

struct GenesisSignatureVisitor;

impl de::Visitor<'_> for GenesisSignatureVisitor {
type Value = GenesisSignature;

fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("a string literal containing a number")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
let parsed = GenesisSignature::from_hex_string(&v).map_err(|e| E::custom(e))?;

Ok(parsed)
}
}

impl<'de> Deserialize<'de> for GenesisSignature {
fn deserialize<D>(deserializer: D) -> Result<GenesisSignature, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(GenesisSignatureVisitor)
}
}

impl FromStr for GenesisSignature {
type Err = GenesisSignatureParseError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(GenesisSignature::from_hex_string(&s.as_bytes())?)
}
}

impl GenesisSignature {
/// Create [`SignedGenesisConfig`] from it's components
pub fn new(
Expand Down
49 changes: 24 additions & 25 deletions tools/swarm/src/compose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,21 @@ impl DockerComposeServiceBuilder {
PairColon(peer.port_api, peer.port_api),
];

let command = if genesis_signature.is_some() {
ServiceCommand::SubmitGenesis
let (command, genesis_signature) = if genesis_signature.is_some() {
(
ServiceCommand::SubmitGenesis,
Some(generate_hex_string_signature(&chain_id, &peer.key_pair)),
)
} else {
ServiceCommand::None
(ServiceCommand::None, None)
};

let compact_env = CompactPeerEnv {
chain_id,
trusted_peers,
genesis_public_key,
genesis_file,
genesis_public_key,
genesis_signature,
key_pair: peer.key_pair.clone(),
p2p_addr: socket_addr!(0.0.0.0:peer.port_p2p),
api_addr: socket_addr!(0.0.0.0:peer.port_api),
Expand Down Expand Up @@ -318,27 +322,17 @@ struct FullPeerEnv {
struct CompactPeerEnv {
chain_id: ChainId,
key_pair: KeyPair,
genesis_public_key: PublicKey,
/// Genesis file is only needed for a peer that is submitting the genesis block
genesis_file: Option<String>,
genesis_public_key: PublicKey,
genesis_signature: Option<String>,
p2p_addr: SocketAddr,
api_addr: SocketAddr,
trusted_peers: BTreeSet<PeerId>,
}

impl From<CompactPeerEnv> for FullPeerEnv {
fn from(value: CompactPeerEnv) -> Self {
let (genesis_file, genesis_signature) =
value.genesis_file.map_or((None, None), |genesis_path| {
(
Some(genesis_path),
Some(generate_hex_string_signature(
&value.chain_id,
&value.key_pair,
)),
)
});

let (private_key_algorithm, private_key_payload) = {
let (algorithm, payload) = value.key_pair.private_key().clone().to_bytes();
(algorithm, payload)
Expand All @@ -349,9 +343,9 @@ impl From<CompactPeerEnv> for FullPeerEnv {
public_key: value.key_pair.public_key().clone(),
private_key_algorithm,
private_key_payload,
genesis_file,
genesis_file: value.genesis_file,
genesis_public_key: value.genesis_public_key,
genesis_signature,
genesis_signature: value.genesis_signature,
p2p_address: value.p2p_addr,
api_address: value.api_addr,
sumeragi_trusted_peers: if value.trusted_peers.is_empty() {
Expand Down Expand Up @@ -616,13 +610,14 @@ mod tests {

#[test]
fn default_config_with_swarm_env_is_exhaustive() {
let keypair = KeyPair::from_seed(vec![1, 5, 1, 2, 2, 3, 4, 1, 2, 3], Algorithm::default());
println!("{:?}", keypair);
let key_pair = KeyPair::from_seed(vec![1, 5, 1, 2, 2, 3, 4, 1, 2, 3], Algorithm::default());
let chain_id = ChainId::from("00000000-0000-0000-0000-000000000000");
let env: TestEnv = CompactPeerEnv {
chain_id: ChainId::from("00000000-0000-0000-0000-000000000000"),
key_pair: keypair.clone(),
chain_id: chain_id.clone(),
key_pair: key_pair.clone(),
genesis_file: Some(PATH_TO_GENESIS.into()),
genesis_public_key: keypair.public_key().clone(),
genesis_public_key: key_pair.public_key().clone(),
genesis_signature: Some(generate_hex_string_signature(&chain_id, &key_pair)),
p2p_addr: socket_addr!(127.0.0.1:1337),
api_addr: socket_addr!(127.0.0.1:1338),
trusted_peers: {
Expand Down Expand Up @@ -672,10 +667,13 @@ mod tests {
platform: PlatformArchitecture,
source: ServiceSource::Build(PathBuf::from(".")),
environment: CompactPeerEnv {
chain_id,
chain_id: chain_id.clone(),
key_pair: key_pair.clone(),
genesis_file: Some(PATH_TO_GENESIS.into()),
genesis_public_key: key_pair.public_key().clone(),
genesis_signature: Some(generate_hex_string_signature(
&chain_id, &key_pair,
)),
p2p_addr: SocketAddr::from_str("iroha1:1339").unwrap(),
api_addr: SocketAddr::from_str("iroha1:1338").unwrap(),
trusted_peers: BTreeSet::new(),
Expand Down Expand Up @@ -737,10 +735,11 @@ mod tests {
let key_pair = KeyPair::from_seed(vec![0, 1, 2], Algorithm::default());

let env: FullPeerEnv = CompactPeerEnv {
chain_id,
chain_id: chain_id.clone(),
key_pair: key_pair.clone(),
genesis_file: Some(PATH_TO_GENESIS.into()),
genesis_public_key: key_pair.public_key().clone(),
genesis_signature: Some(generate_hex_string_signature(&chain_id, &key_pair)),
p2p_addr: SocketAddr::from_str("iroha0:1337").unwrap(),
api_addr: SocketAddr::from_str("iroha0:1337").unwrap(),
trusted_peers: BTreeSet::new(),
Expand Down

0 comments on commit 366dd70

Please sign in to comment.