testnet manager: start multiple gateways
This commit is contained in:
@@ -36,5 +36,16 @@ CREATE TABLE contract (
|
||||
|
||||
CREATE TABLE account (
|
||||
address TEXT NOT NULL UNIQUE,
|
||||
-- for the future 'import' feature this will have to be nullable
|
||||
mnemonic TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE node (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
identity_key TEXT NOT NULL,
|
||||
network_id INTEGER NOT NULL REFERENCES network(id),
|
||||
|
||||
-- i.e. mixnode or gateway
|
||||
bonded_type TEXT NOT NULL,
|
||||
owner_address TEXT NOT NULL REFERENCES account(address)
|
||||
);
|
||||
@@ -15,6 +15,12 @@ pub(crate) struct Args {
|
||||
#[clap(long)]
|
||||
nym_node_bin: PathBuf,
|
||||
|
||||
#[clap(long, default_value_t = 3)]
|
||||
num_mixnodes: u16,
|
||||
|
||||
#[clap(long, default_value_t = 1)]
|
||||
num_gateways: u16,
|
||||
|
||||
#[clap(long)]
|
||||
network_name: Option<String>,
|
||||
|
||||
@@ -27,7 +33,12 @@ pub(crate) async fn execute(args: Args) -> Result<(), NetworkManagerError> {
|
||||
let network = manager.load_existing_network(args.network_name).await?;
|
||||
|
||||
let run_cmds = manager
|
||||
.init_local_nym_nodes(args.nym_node_bin, &network)
|
||||
.init_local_nym_nodes(
|
||||
args.nym_node_bin,
|
||||
&network,
|
||||
args.num_mixnodes,
|
||||
args.num_gateways,
|
||||
)
|
||||
.await?;
|
||||
|
||||
if !args.output.is_text() {
|
||||
|
||||
@@ -178,6 +178,9 @@ impl NetworkManager {
|
||||
let id = &ctx.client_id;
|
||||
|
||||
self.wait_for_gateway(ctx).await?;
|
||||
let mut rng = thread_rng();
|
||||
let mut port = rng.next_u32();
|
||||
port = (port + 1000) % (u16::MAX as u32);
|
||||
|
||||
ctx.set_pb_message(format!("initialising client {id}..."));
|
||||
ctx.println(format!("\tinitialising client {id}..."));
|
||||
@@ -190,6 +193,8 @@ impl NetworkManager {
|
||||
id,
|
||||
"--enabled-credentials-mode",
|
||||
"true",
|
||||
"--port",
|
||||
&port.to_string(),
|
||||
])
|
||||
.stdout(Stdio::null())
|
||||
.stdin(Stdio::null())
|
||||
|
||||
@@ -3,17 +3,12 @@
|
||||
|
||||
use crate::error::NetworkManagerError;
|
||||
use crate::helpers::{ProgressCtx, ProgressTracker, RunCommands};
|
||||
use crate::manager::contract::Account;
|
||||
use crate::manager::network::LoadedNetwork;
|
||||
use crate::manager::node::NymNode;
|
||||
use crate::manager::NetworkManager;
|
||||
use console::style;
|
||||
use nym_contracts_common::signing::MessageSignature;
|
||||
use nym_mixnet_contract_common::{
|
||||
construct_gateway_bonding_sign_payload, construct_mixnode_bonding_sign_payload, Addr, Gateway,
|
||||
Layer, LayerAssignment, MixNode, MixNodeCostParams, Percent,
|
||||
};
|
||||
use nym_mixnet_contract_common::{Layer, LayerAssignment};
|
||||
use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient};
|
||||
use nym_validator_client::nyxd::CosmWasmCoin;
|
||||
use nym_validator_client::DirectSigningHttpRpcNyxdClient;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs;
|
||||
@@ -23,99 +18,6 @@ use std::process::Stdio;
|
||||
use tokio::process::Command;
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
struct NymNode {
|
||||
// host is always 127.0.0.1
|
||||
mix_port: u16,
|
||||
verloc_port: u16,
|
||||
http_port: u16,
|
||||
clients_port: u16,
|
||||
sphinx_key: String,
|
||||
identity_key: String,
|
||||
version: String,
|
||||
|
||||
owner: Account,
|
||||
bonding_signature: String,
|
||||
}
|
||||
|
||||
impl NymNode {
|
||||
fn new_empty() -> NymNode {
|
||||
NymNode {
|
||||
mix_port: 0,
|
||||
verloc_port: 0,
|
||||
http_port: 0,
|
||||
clients_port: 0,
|
||||
sphinx_key: "".to_string(),
|
||||
identity_key: "".to_string(),
|
||||
version: "".to_string(),
|
||||
owner: Account::new(),
|
||||
bonding_signature: "".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn pledge(&self) -> CosmWasmCoin {
|
||||
CosmWasmCoin::new(100_000000, "unym")
|
||||
}
|
||||
|
||||
fn gateway(&self) -> Gateway {
|
||||
Gateway {
|
||||
host: "127.0.0.1".to_string(),
|
||||
mix_port: self.mix_port,
|
||||
clients_port: self.clients_port,
|
||||
location: "foomp".to_string(),
|
||||
sphinx_key: self.sphinx_key.clone(),
|
||||
identity_key: self.identity_key.clone(),
|
||||
version: self.version.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn mixnode(&self) -> MixNode {
|
||||
MixNode {
|
||||
host: "127.0.0.1".to_string(),
|
||||
mix_port: self.mix_port,
|
||||
verloc_port: self.verloc_port,
|
||||
http_api_port: self.http_port,
|
||||
sphinx_key: self.sphinx_key.clone(),
|
||||
identity_key: self.identity_key.clone(),
|
||||
version: self.version.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn cost_params(&self) -> MixNodeCostParams {
|
||||
MixNodeCostParams {
|
||||
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
||||
interval_operating_cost: CosmWasmCoin::new(40_000000, "unym"),
|
||||
}
|
||||
}
|
||||
|
||||
fn bonding_signature(&self) -> MessageSignature {
|
||||
// this is a valid bs58
|
||||
self.bonding_signature.parse().unwrap()
|
||||
}
|
||||
|
||||
fn mixnode_bonding_payload(&self) -> String {
|
||||
let payload = construct_mixnode_bonding_sign_payload(
|
||||
0,
|
||||
Addr::unchecked(self.owner.address.to_string()),
|
||||
None,
|
||||
self.pledge(),
|
||||
self.mixnode(),
|
||||
self.cost_params(),
|
||||
);
|
||||
payload.to_base58_string().unwrap()
|
||||
}
|
||||
|
||||
fn gateway_bonding_payload(&self) -> String {
|
||||
let payload = construct_gateway_bonding_sign_payload(
|
||||
0,
|
||||
Addr::unchecked(self.owner.address.to_string()),
|
||||
None,
|
||||
self.pledge(),
|
||||
self.gateway(),
|
||||
);
|
||||
payload.to_base58_string().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
struct LocalNodesCtx<'a> {
|
||||
nym_node_binary: PathBuf,
|
||||
|
||||
@@ -124,7 +26,7 @@ struct LocalNodesCtx<'a> {
|
||||
admin: DirectSigningHttpRpcNyxdClient,
|
||||
|
||||
mix_nodes: Vec<NymNode>,
|
||||
gateway: Option<NymNode>,
|
||||
gateways: Vec<NymNode>,
|
||||
}
|
||||
|
||||
impl<'a> ProgressCtx for LocalNodesCtx<'a> {
|
||||
@@ -135,7 +37,7 @@ impl<'a> ProgressCtx for LocalNodesCtx<'a> {
|
||||
|
||||
impl<'a> LocalNodesCtx<'a> {
|
||||
fn nym_node_id(&self, node: &NymNode) -> String {
|
||||
format!("{}-{}", node.owner.address, self.network.name)
|
||||
format!("{}-{}", self.network.name, node.identity_key)
|
||||
}
|
||||
|
||||
fn new(
|
||||
@@ -158,7 +60,7 @@ impl<'a> LocalNodesCtx<'a> {
|
||||
)?,
|
||||
mix_nodes: Vec::new(),
|
||||
progress,
|
||||
gateway: None,
|
||||
gateways: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -335,7 +237,7 @@ impl NetworkManager {
|
||||
));
|
||||
|
||||
if is_gateway {
|
||||
ctx.gateway = Some(node)
|
||||
ctx.gateways.push(node)
|
||||
} else {
|
||||
ctx.mix_nodes.push(node)
|
||||
}
|
||||
@@ -345,16 +247,24 @@ impl NetworkManager {
|
||||
async fn initialise_nym_nodes<'a>(
|
||||
&self,
|
||||
ctx: &mut LocalNodesCtx<'a>,
|
||||
num_mixnodes: u16,
|
||||
num_gateways: u16,
|
||||
) -> Result<(), NetworkManagerError> {
|
||||
const OFFSET: u16 = 100;
|
||||
if num_mixnodes > OFFSET {
|
||||
panic!("seriously? over 100 mixnodes?")
|
||||
}
|
||||
|
||||
ctx.println(format!(
|
||||
"🔏 {}Initialising local nym-nodes...",
|
||||
style("[1/4]").bold().dim()
|
||||
style("[1/5]").bold().dim()
|
||||
));
|
||||
|
||||
// 3 mixnodes, 1 gateway; maybe at some point make it configurable
|
||||
for i in 0..4 {
|
||||
let is_gateway = i == 0;
|
||||
self.initialise_nym_node(ctx, i, is_gateway).await?;
|
||||
for i in 0..num_mixnodes {
|
||||
self.initialise_nym_node(ctx, i, false).await?;
|
||||
}
|
||||
for i in 0..num_gateways {
|
||||
self.initialise_nym_node(ctx, i + OFFSET, true).await?;
|
||||
}
|
||||
|
||||
ctx.println("\t✅ all nym nodes got initialised!");
|
||||
@@ -368,15 +278,11 @@ impl NetworkManager {
|
||||
) -> Result<(), NetworkManagerError> {
|
||||
ctx.println(format!(
|
||||
"💸 {}Transferring tokens to the bond owners...",
|
||||
style("[2/4]").bold().dim()
|
||||
style("[2/5]").bold().dim()
|
||||
));
|
||||
|
||||
let mut receivers = Vec::new();
|
||||
for node in ctx
|
||||
.mix_nodes
|
||||
.iter()
|
||||
.chain(std::iter::once(ctx.gateway.as_ref().unwrap()))
|
||||
{
|
||||
for node in ctx.mix_nodes.iter().chain(ctx.gateways.iter()) {
|
||||
// send 101nym to the owner
|
||||
receivers.push((node.owner.address.clone(), ctx.admin.mix_coins(101_000000)))
|
||||
}
|
||||
@@ -439,14 +345,15 @@ impl NetworkManager {
|
||||
async fn bond_nym_nodes<'a>(&self, ctx: &LocalNodesCtx<'a>) -> Result<(), NetworkManagerError> {
|
||||
ctx.println(format!(
|
||||
"⛓️ {}Bonding the local nym-nodes...",
|
||||
style("[3/4]").bold().dim()
|
||||
style("[3/5]").bold().dim()
|
||||
));
|
||||
|
||||
self.bond_node(ctx, ctx.gateway.as_ref().unwrap(), true)
|
||||
.await?;
|
||||
for mix_node in &ctx.mix_nodes {
|
||||
self.bond_node(ctx, mix_node, false).await?;
|
||||
}
|
||||
for gateway in &ctx.gateways {
|
||||
self.bond_node(ctx, gateway, true).await?;
|
||||
}
|
||||
|
||||
ctx.println("\t✅ all nym nodes got bonded!");
|
||||
|
||||
@@ -459,7 +366,7 @@ impl NetworkManager {
|
||||
) -> Result<(), NetworkManagerError> {
|
||||
ctx.println(format!(
|
||||
"🔌 {}Assigning mixnodes to the active set...",
|
||||
style("[4/4]").bold().dim()
|
||||
style("[4/5]").bold().dim()
|
||||
));
|
||||
|
||||
let rewarder = ctx.signing_rewarder()?;
|
||||
@@ -500,12 +407,23 @@ impl NetworkManager {
|
||||
let env_canon_display = env_canon.display();
|
||||
|
||||
let mut cmds = Vec::new();
|
||||
for node in ctx
|
||||
.mix_nodes
|
||||
.iter()
|
||||
.chain(std::iter::once(ctx.gateway.as_ref().unwrap()))
|
||||
{
|
||||
let id = ctx.nym_node_id(node);
|
||||
for mixnode in ctx.mix_nodes.iter() {
|
||||
ctx.println(format!(
|
||||
"\tpreparing node {} (mixnode)",
|
||||
mixnode.identity_key
|
||||
));
|
||||
let id = ctx.nym_node_id(mixnode);
|
||||
cmds.push(format!(
|
||||
"{bin_canon_display} -c {env_canon_display} run --id {id} --local"
|
||||
));
|
||||
}
|
||||
|
||||
for gateway in ctx.gateways.iter() {
|
||||
ctx.println(format!(
|
||||
"\tpreparing node {} (mixnode)",
|
||||
gateway.identity_key
|
||||
));
|
||||
let id = ctx.nym_node_id(gateway);
|
||||
cmds.push(format!(
|
||||
"{bin_canon_display} -c {env_canon_display} run --id {id} --local"
|
||||
));
|
||||
@@ -518,10 +436,36 @@ impl NetworkManager {
|
||||
ctx.progress.output_run_commands(cmds)
|
||||
}
|
||||
|
||||
async fn persist_nodes_in_database<'a>(
|
||||
&self,
|
||||
ctx: &LocalNodesCtx<'a>,
|
||||
) -> Result<(), NetworkManagerError> {
|
||||
ctx.println(format!(
|
||||
"📦 {}Storing the node information in the database",
|
||||
style("[5/5]").bold().dim()
|
||||
));
|
||||
|
||||
ctx.set_pb_message("attempting to persist node information...");
|
||||
let mix_save_future = self
|
||||
.storage
|
||||
.persist_mixnodes(&ctx.mix_nodes, ctx.network.id);
|
||||
let gw_save_future = self.storage.persist_gateways(&ctx.gateways, ctx.network.id);
|
||||
ctx.async_with_progress(mix_save_future).await?;
|
||||
ctx.async_with_progress(gw_save_future).await?;
|
||||
|
||||
ctx.println(
|
||||
"\t✅ the bonded node information got persisted in the database for future use",
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn init_local_nym_nodes<P: AsRef<Path>>(
|
||||
&self,
|
||||
nym_node_binary: P,
|
||||
network: &LoadedNetwork,
|
||||
num_mixnodes: u16,
|
||||
num_gateways: u16,
|
||||
) -> Result<RunCommands, NetworkManagerError> {
|
||||
let mut ctx = LocalNodesCtx::new(
|
||||
nym_node_binary.as_ref().to_path_buf(),
|
||||
@@ -534,10 +478,12 @@ impl NetworkManager {
|
||||
return Err(NetworkManagerError::EnvFileNotGenerated);
|
||||
}
|
||||
|
||||
self.initialise_nym_nodes(&mut ctx).await?;
|
||||
self.initialise_nym_nodes(&mut ctx, num_mixnodes, num_gateways)
|
||||
.await?;
|
||||
self.transfer_bonding_tokens(&ctx).await?;
|
||||
self.bond_nym_nodes(&ctx).await?;
|
||||
self.assign_to_active_set(&ctx).await?;
|
||||
self.persist_nodes_in_database(&ctx).await?;
|
||||
let cmds = self.prepare_nym_nodes_run_commands(&ctx)?;
|
||||
self.output_nym_nodes_run_commands(&ctx, &cmds);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ mod local_client;
|
||||
mod local_nodes;
|
||||
pub(crate) mod network;
|
||||
mod network_init;
|
||||
mod node;
|
||||
pub(crate) mod storage;
|
||||
|
||||
pub(crate) struct NetworkManager {
|
||||
|
||||
@@ -34,6 +34,7 @@ impl Network {
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub(crate) struct LoadedNetwork {
|
||||
pub(crate) id: i64,
|
||||
pub(crate) name: String,
|
||||
|
||||
pub(crate) rpc_endpoint: Url,
|
||||
@@ -49,6 +50,7 @@ pub(crate) struct LoadedNetwork {
|
||||
impl From<Network> for LoadedNetwork {
|
||||
fn from(value: Network) -> Self {
|
||||
LoadedNetwork {
|
||||
id: i64::MAX,
|
||||
name: value.name,
|
||||
rpc_endpoint: value.rpc_endpoint,
|
||||
created_at: value.created_at,
|
||||
|
||||
@@ -662,7 +662,7 @@ impl NetworkManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn persist_in_database(&self, ctx: &InitCtx) -> Result<(), NetworkManagerError> {
|
||||
async fn persist_network_in_database(&self, ctx: &InitCtx) -> Result<(), NetworkManagerError> {
|
||||
ctx.println(format!(
|
||||
"📦 {}Storing all the results in the database",
|
||||
style("[8/8]").bold().dim()
|
||||
@@ -694,7 +694,7 @@ impl NetworkManager {
|
||||
.await?;
|
||||
self.perform_final_migrations(&mut ctx).await?;
|
||||
self.get_build_info(&mut ctx).await?;
|
||||
self.persist_in_database(&ctx).await?;
|
||||
self.persist_network_in_database(&ctx).await?;
|
||||
|
||||
Ok(ctx.network.clone())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::manager::contract::Account;
|
||||
use nym_coconut_dkg_common::types::Addr;
|
||||
use nym_contracts_common::signing::MessageSignature;
|
||||
use nym_contracts_common::Percent;
|
||||
use nym_mixnet_contract_common::{
|
||||
construct_gateway_bonding_sign_payload, construct_mixnode_bonding_sign_payload, Gateway,
|
||||
MixNode, MixNodeCostParams,
|
||||
};
|
||||
use nym_validator_client::nyxd::CosmWasmCoin;
|
||||
|
||||
pub(crate) struct NymNode {
|
||||
// host is always 127.0.0.1
|
||||
pub(crate) mix_port: u16,
|
||||
pub(crate) verloc_port: u16,
|
||||
pub(crate) http_port: u16,
|
||||
pub(crate) clients_port: u16,
|
||||
pub(crate) sphinx_key: String,
|
||||
pub(crate) identity_key: String,
|
||||
pub(crate) version: String,
|
||||
|
||||
pub(crate) owner: Account,
|
||||
pub(crate) bonding_signature: String,
|
||||
}
|
||||
|
||||
impl NymNode {
|
||||
pub(crate) fn new_empty() -> NymNode {
|
||||
NymNode {
|
||||
mix_port: 0,
|
||||
verloc_port: 0,
|
||||
http_port: 0,
|
||||
clients_port: 0,
|
||||
sphinx_key: "".to_string(),
|
||||
identity_key: "".to_string(),
|
||||
version: "".to_string(),
|
||||
owner: Account::new(),
|
||||
bonding_signature: "".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn pledge(&self) -> CosmWasmCoin {
|
||||
CosmWasmCoin::new(100_000000, "unym")
|
||||
}
|
||||
|
||||
pub(crate) fn gateway(&self) -> Gateway {
|
||||
Gateway {
|
||||
host: "127.0.0.1".to_string(),
|
||||
mix_port: self.mix_port,
|
||||
clients_port: self.clients_port,
|
||||
location: "foomp".to_string(),
|
||||
sphinx_key: self.sphinx_key.clone(),
|
||||
identity_key: self.identity_key.clone(),
|
||||
version: self.version.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn mixnode(&self) -> MixNode {
|
||||
MixNode {
|
||||
host: "127.0.0.1".to_string(),
|
||||
mix_port: self.mix_port,
|
||||
verloc_port: self.verloc_port,
|
||||
http_api_port: self.http_port,
|
||||
sphinx_key: self.sphinx_key.clone(),
|
||||
identity_key: self.identity_key.clone(),
|
||||
version: self.version.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn cost_params(&self) -> MixNodeCostParams {
|
||||
MixNodeCostParams {
|
||||
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
||||
interval_operating_cost: CosmWasmCoin::new(40_000000, "unym"),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn bonding_signature(&self) -> MessageSignature {
|
||||
// this is a valid bs58 string
|
||||
self.bonding_signature.parse().unwrap()
|
||||
}
|
||||
|
||||
pub(crate) fn mixnode_bonding_payload(&self) -> String {
|
||||
let payload = construct_mixnode_bonding_sign_payload(
|
||||
0,
|
||||
Addr::unchecked(self.owner.address.to_string()),
|
||||
None,
|
||||
self.pledge(),
|
||||
self.mixnode(),
|
||||
self.cost_params(),
|
||||
);
|
||||
payload.to_base58_string().unwrap()
|
||||
}
|
||||
|
||||
pub(crate) fn gateway_bonding_payload(&self) -> String {
|
||||
let payload = construct_gateway_bonding_sign_payload(
|
||||
0,
|
||||
Addr::unchecked(self.owner.address.to_string()),
|
||||
None,
|
||||
self.pledge(),
|
||||
self.gateway(),
|
||||
);
|
||||
payload.to_base58_string().unwrap()
|
||||
}
|
||||
}
|
||||
@@ -180,4 +180,26 @@ impl StorageManager {
|
||||
.fetch_one(&self.connection_pool)
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn save_node(
|
||||
&self,
|
||||
identity_key: &str,
|
||||
network_id: i64,
|
||||
bonded_type: &str,
|
||||
owner_address: &str,
|
||||
) -> Result<(), sqlx::Error> {
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO node(identity_key, network_id, bonded_type, owner_address)
|
||||
VALUES (?, ?, ?, ?)
|
||||
"#,
|
||||
identity_key,
|
||||
network_id,
|
||||
bonded_type,
|
||||
owner_address
|
||||
)
|
||||
.execute(&self.connection_pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ use std::fs;
|
||||
use crate::error::NetworkManagerError;
|
||||
use crate::manager::contract::{Account, Contract, LoadedNymContracts};
|
||||
use crate::manager::network::{LoadedNetwork, Network, SpecialAddresses};
|
||||
use crate::manager::node::NymNode;
|
||||
use crate::manager::storage::manager::StorageManager;
|
||||
use sqlx::ConnectOptions;
|
||||
use std::path::Path;
|
||||
@@ -117,6 +118,38 @@ impl NetworkManagerStorage {
|
||||
.await?)
|
||||
}
|
||||
|
||||
async fn persist_mixnode(
|
||||
&self,
|
||||
node: &NymNode,
|
||||
network_id: i64,
|
||||
) -> Result<(), NetworkManagerError> {
|
||||
Ok(self
|
||||
.manager
|
||||
.save_node(
|
||||
&node.identity_key,
|
||||
network_id,
|
||||
"mixnode",
|
||||
node.owner.address.as_ref(),
|
||||
)
|
||||
.await?)
|
||||
}
|
||||
|
||||
async fn persist_gateway(
|
||||
&self,
|
||||
node: &NymNode,
|
||||
network_id: i64,
|
||||
) -> Result<(), NetworkManagerError> {
|
||||
Ok(self
|
||||
.manager
|
||||
.save_node(
|
||||
&node.identity_key,
|
||||
network_id,
|
||||
"gateway",
|
||||
node.owner.address.as_ref(),
|
||||
)
|
||||
.await?)
|
||||
}
|
||||
|
||||
async fn persist_account(&self, account: &Account) -> Result<(), NetworkManagerError> {
|
||||
let as_str = Zeroizing::new(account.mnemonic.to_string());
|
||||
Ok(self
|
||||
@@ -125,6 +158,30 @@ impl NetworkManagerStorage {
|
||||
.await?)
|
||||
}
|
||||
|
||||
pub(crate) async fn persist_mixnodes(
|
||||
&self,
|
||||
nodes: &[NymNode],
|
||||
network_id: i64,
|
||||
) -> Result<(), NetworkManagerError> {
|
||||
for node in nodes {
|
||||
self.persist_account(&node.owner).await?;
|
||||
self.persist_mixnode(node, network_id).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn persist_gateways(
|
||||
&self,
|
||||
nodes: &[NymNode],
|
||||
network_id: i64,
|
||||
) -> Result<(), NetworkManagerError> {
|
||||
for node in nodes {
|
||||
self.persist_account(&node.owner).await?;
|
||||
self.persist_gateway(node, network_id).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn persist_network(
|
||||
&self,
|
||||
network: &Network,
|
||||
@@ -191,6 +248,7 @@ impl NetworkManagerStorage {
|
||||
.ok_or_else(|| NetworkManagerError::RpcEndpointNotSet)?;
|
||||
|
||||
Ok(LoadedNetwork {
|
||||
id: base_network.id,
|
||||
name: base_network.name,
|
||||
rpc_endpoint,
|
||||
created_at: base_network.created_at,
|
||||
|
||||
@@ -60,7 +60,6 @@ impl TryFrom<RawContract> for LoadedContract {
|
||||
|
||||
#[derive(FromRow)]
|
||||
pub(crate) struct RawNetwork {
|
||||
#[allow(unused)]
|
||||
pub(crate) id: i64,
|
||||
pub(crate) name: String,
|
||||
pub(crate) created_at: OffsetDateTime,
|
||||
|
||||
Reference in New Issue
Block a user