Skip to content
This repository has been archived by the owner on Jan 11, 2024. It is now read-only.

Include gateway addr in subnet config #137

Merged
merged 8 commits into from
Mar 30, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions config/template.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ json_rpc_address = "127.0.0.1:3030"

[subnets]

[subnets.root]
[[subnets]]
id = "/root"
network_name = "root"
gateway_addr = 64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of a curiosity, why did you use a u64 instead of an Address here? I can think of a few reasons why we may want to do this, but I don´t know if it would be the best approach for users. @hmoniz, thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps, it's just convenience I guess. Convert actor id to address is quite straightforward. If we want to use string, it works too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's either use gateway_addr = "t064" or let's call this field gateway_id and make it an uint. Whatever works best for you.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use the first option, please check

jsonrpc_api_http = "https://example.org/rpc/v0"
jsonrpc_api_ws = "wss://example.org/rpc/v0"
auth_token = "YOUR ROOT AUTH TOKEN"

[subnets.child]
[[subnets]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From total ignorance, would it be possible to make the config something like so that we use the id already as the key of the map?:

[subnets]

[[/root]]
....
[[/root/t01011]]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one I'm not so sure, but I think it cannot be done, because [[/root]] would translate to hashmap of "/root" as key and whatever in the ... as an array of deserialized struct. But I think we should avoid using subnet id string because of /, everytime we have to escape it with ", which is easy to make mistake.

id = "/root/t0100"
network_name = "child"
gateway_addr = 64
jsonrpc_api_http = "https://example.org/rpc/v2"
auth_token = "YOUR CHILD AUTH TOKEN"
accounts = ["t3thgjtvoi65yzdcoifgqh6utjbaod3ukidxrx34heu34d6avx6z7r5766t5jqt42a44ehzcnw3u5ehz47n42a"]
46 changes: 45 additions & 1 deletion src/config/deserialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,57 @@
// SPDX-License-Identifier: MIT
//! Deserialization utils for config mod.

use crate::config::Subnet;
use fvm_shared::address::Address;
use ipc_sdk::subnet_id::SubnetID;
use serde::de::{Error, SeqAccess};
use serde::Deserializer;
use serde::{Deserialize, Deserializer};
use std::collections::HashMap;
use std::fmt::Formatter;
use std::str::FromStr;

/// A serde deserialization method to deserialize a hashmap of subnets with subnet id as key and
/// Subnet struct as value from a vec of subnets
pub(crate) fn deserialize_subnets_from_vec<'de, D>(
deserializer: D,
) -> anyhow::Result<HashMap<SubnetID, Subnet>, D::Error>
where
D: Deserializer<'de>,
{
let subnets = <Vec<Subnet>>::deserialize(deserializer)?;

let mut hashmap = HashMap::new();
for subnet in subnets {
hashmap.insert(subnet.id.clone(), subnet);
}
Ok(hashmap)
}

/// A serde deserialization method to deserialize an address from i64
pub(crate) fn deserialize_address_from_i64<'de, D>(
deserializer: D,
) -> anyhow::Result<Address, D::Error>
where
D: Deserializer<'de>,
{
struct Visitor;
impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = Address;

fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("an u64")
}

fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Address::new_id(v as u64))
}
}
deserializer.deserialize_i64(Visitor)
}

/// A serde deserialization method to deserialize a subnet path string into a [`SubnetID`].
pub(crate) fn deserialize_subnet_id<'de, D>(deserializer: D) -> anyhow::Result<SubnetID, D::Error>
where
Expand Down
15 changes: 10 additions & 5 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use std::fs;
use std::path::Path;

use anyhow::Result;
use deserialize::deserialize_subnets_from_vec;
use ipc_sdk::subnet_id::SubnetID;
pub use reload::ReloadableConfig;
use serde::Deserialize;
pub use server::JSON_RPC_ENDPOINT;
Expand All @@ -32,17 +34,19 @@ pub const DEFAULT_CONFIG_TEMPLATE: &str = r#"
[server]
json_rpc_address = "127.0.0.1:3030"

[subnets]

[subnets."/root"]
[[subnets]]
id = "/root"
gateway_addr = 64
network_name = "root"
jsonrpc_api_http = "http://127.0.0.1:1235/rpc/v1"
jsonrpc_api_ws = "wss://example.org/rpc/v0"
auth_token = "YOUR TOKEN"
accounts = ["t01"]

[subnets."/root/t01"]
[[subnets]]
id = "/root/t01"
gateway_addr = 64
network_name = "child"
jsonrpc_api_http = "http://127.0.0.1:1235/rpc/v1"
auth_token = "YOUR TOKEN"
accounts = ["t01"]
Expand All @@ -53,7 +57,8 @@ accounts = ["t01"]
#[derive(Deserialize, Debug)]
pub struct Config {
pub server: Server,
pub subnets: HashMap<String, Subnet>,
#[serde(deserialize_with = "deserialize_subnets_from_vec")]
pub subnets: HashMap<SubnetID, Subnet>,
}

impl Config {
Expand Down
8 changes: 7 additions & 1 deletion src/config/subnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@ use ipc_sdk::subnet_id::SubnetID;
use serde::Deserialize;
use url::Url;

use crate::config::deserialize::{deserialize_accounts, deserialize_subnet_id};
use crate::config::deserialize::{
deserialize_accounts, deserialize_address_from_i64, deserialize_subnet_id,
};

/// Represents a subnet declaration in the config.
#[derive(Deserialize, Clone, Debug)]
pub struct Subnet {
#[serde(deserialize_with = "deserialize_subnet_id")]
pub id: SubnetID,
#[serde(deserialize_with = "deserialize_address_from_i64")]
// toml is interpreting number as i64
pub gateway_addr: Address,
pub network_name: String,
pub jsonrpc_api_http: Url,
pub jsonrpc_api_ws: Option<Url>,
pub auth_token: Option<String>,
Expand Down
42 changes: 29 additions & 13 deletions src/config/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::config::{Config, ReloadableConfig};
const SERVER_JSON_RPC_ADDR: &str = "127.0.0.1:3030";
const ROOT_ID: &str = "/root";
const CHILD_ID: &str = "/root/t0100";
const GATEWAY_ADDR: u64 = 64;
const ROOT_AUTH_TOKEN: &str = "ROOT_AUTH_TOKEN";
const CHILD_AUTH_TOKEN: &str = "CHILD_AUTH_TOKEN";
const JSONRPC_API_HTTP: &str = "https://example.org/rpc/v0";
Expand Down Expand Up @@ -96,8 +97,10 @@ fn check_server_config() {
fn check_subnets_config() {
let config = read_config().subnets;

let root = &config["root"];
let root = &config[&ROOTNET_ID];
assert_eq!(root.id, *ROOTNET_ID);
assert_eq!(root.network_name, "root");
assert_eq!(root.gateway_addr, Address::new_id(GATEWAY_ADDR));
assert_eq!(
root.jsonrpc_api_http,
Url::from_str(JSONRPC_API_HTTP).unwrap()
Expand All @@ -108,8 +111,11 @@ fn check_subnets_config() {
);
assert_eq!(root.auth_token.as_ref().unwrap(), ROOT_AUTH_TOKEN);

let child = &config["child"];
assert_eq!(child.id, SubnetID::from_str(CHILD_ID).unwrap(),);
let child_id = SubnetID::from_str(CHILD_ID).unwrap();
let child = &config[&child_id];
assert_eq!(child.id, child_id);
assert_eq!(child.network_name, "child");
assert_eq!(child.gateway_addr, Address::new_id(GATEWAY_ADDR));
assert_eq!(
child.jsonrpc_api_http,
Url::from_str(JSONRPC_API_HTTP).unwrap(),
Expand All @@ -127,14 +133,18 @@ fn config_str() -> String {
[server]
json_rpc_address = "{SERVER_JSON_RPC_ADDR}"

[subnets]
[subnets.root]
[[subnets]]
id = "{ROOT_ID}"
gateway_addr = {GATEWAY_ADDR}
network_name = "root"
jsonrpc_api_http = "{JSONRPC_API_HTTP}"
jsonrpc_api_ws = "{JSONRPC_API_WS}"
auth_token = "{ROOT_AUTH_TOKEN}"
[subnets.child]

[[subnets]]
id = "{CHILD_ID}"
network_name = "child"
gateway_addr = {GATEWAY_ADDR}
jsonrpc_api_http = "{JSONRPC_API_HTTP}"
auth_token = "{CHILD_AUTH_TOKEN}"
accounts = ["{ACCOUNT_ADDRESS}"]
Expand All @@ -148,14 +158,18 @@ fn config_str_diff_addr() -> String {
[server]
json_rpc_address = "127.0.0.1:3031"

[subnets]
[subnets.root]
[[subnets]]
id = "{ROOT_ID}"
network_name = "root"
gateway_addr = {GATEWAY_ADDR}
jsonrpc_api_http = "{JSONRPC_API_HTTP}"
jsonrpc_api_ws = "{JSONRPC_API_WS}"
auth_token = "{ROOT_AUTH_TOKEN}"
[subnets.child]

[[subnets]]
id = "{CHILD_ID}"
network_name = "child"
gateway_addr = {GATEWAY_ADDR}
jsonrpc_api_http = "{JSONRPC_API_HTTP}"
auth_token = "{CHILD_AUTH_TOKEN}"
accounts = ["{ACCOUNT_ADDRESS}"]
Expand All @@ -169,16 +183,18 @@ fn read_config() -> Config {
[server]
json_rpc_address = "{SERVER_JSON_RPC_ADDR}"

[subnets]

[subnets.root]
[[subnets]]
id = "{ROOT_ID}"
network_name = "root"
gateway_addr = {GATEWAY_ADDR}
jsonrpc_api_http = "{JSONRPC_API_HTTP}"
jsonrpc_api_ws = "{JSONRPC_API_WS}"
auth_token = "{ROOT_AUTH_TOKEN}"

[subnets.child]
[[subnets]]
id = "{CHILD_ID}"
network_name = "child"
gateway_addr = {GATEWAY_ADDR}
jsonrpc_api_http = "{JSONRPC_API_HTTP}"
auth_token = "{CHILD_AUTH_TOKEN}"
accounts = ["{ACCOUNT_ADDRESS}"]
Expand Down
10 changes: 2 additions & 8 deletions src/manager/checkpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,8 @@ impl IntoSubsystem<anyhow::Error> for CheckpointSubsystem {
/// manage checkpoint for. This means that for each `child_subnet` there exists at least one account
/// for which we need to submit checkpoints on behalf of to `parent_subnet`, which must also be
/// present in the map.
fn subnets_to_manage(subnets: &HashMap<String, Subnet>) -> Vec<(Subnet, Subnet)> {
// First, we remap subnets by SubnetID.
let subnets_by_id: HashMap<SubnetID, Subnet> = subnets
.values()
.map(|s| (s.id.clone(), s.clone()))
.collect();

// Then, we filter for subnets that have at least one account and for which the parent subnet
fn subnets_to_manage(subnets_by_id: &HashMap<SubnetID, Subnet>) -> Vec<(Subnet, Subnet)> {
// We filter for subnets that have at least one account and for which the parent subnet
// is also in the map, and map into a Vec of (child_subnet, parent_subnet) tuples.
subnets_by_id
.values()
Expand Down
7 changes: 3 additions & 4 deletions src/server/handlers/manager/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,14 @@ impl JsonRPCRequestHandler for CreateSubnetHandler {
type Response = CreateSubnetResponse;

async fn handle(&self, request: Self::Request) -> anyhow::Result<Self::Response> {
let parent = &request.parent;

let conn = match self.pool.get(parent) {
let parent = SubnetID::from_str(&request.parent)?;
let conn = match self.pool.get(&parent) {
None => return Err(anyhow!("target parent subnet not found")),
Some(conn) => conn,
};

let constructor_params = ConstructParams {
parent: SubnetID::from_str(parent)?,
parent,
name: request.name,
ipc_gateway_addr: DEFAULT_IPC_GATEWAY_ADDR,
consensus: ConsensusType::Mir,
Expand Down
5 changes: 1 addition & 4 deletions src/server/handlers/manager/fund.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@ impl JsonRPCRequestHandler for FundHandler {

async fn handle(&self, request: Self::Request) -> anyhow::Result<Self::Response> {
let subnet = SubnetID::from_str(&request.subnet)?;
let parent = subnet
.parent()
.ok_or_else(|| anyhow!("no parent found"))?
.to_string();
let parent = subnet.parent().ok_or_else(|| anyhow!("no parent found"))?;
let conn = match self.pool.get(&parent) {
None => return Err(anyhow!("target parent subnet not found")),
Some(conn) => conn,
Expand Down
5 changes: 1 addition & 4 deletions src/server/handlers/manager/join.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ impl JsonRPCRequestHandler for JoinSubnetHandler {

async fn handle(&self, request: Self::Request) -> anyhow::Result<Self::Response> {
let subnet = SubnetID::from_str(&request.subnet)?;
let parent = subnet
.parent()
.ok_or_else(|| anyhow!("no parent found"))?
.to_string();
let parent = subnet.parent().ok_or_else(|| anyhow!("no parent found"))?;
let conn = match self.pool.get(&parent) {
None => return Err(anyhow!("target parent subnet not found")),
Some(conn) => conn,
Expand Down
6 changes: 1 addition & 5 deletions src/server/handlers/manager/kill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,7 @@ impl JsonRPCRequestHandler for KillSubnetHandler {

async fn handle(&self, request: Self::Request) -> anyhow::Result<Self::Response> {
let subnet = SubnetID::from_str(&request.subnet)?;
let parent = subnet
.parent()
.ok_or_else(|| anyhow!("no parent found"))?
.to_string();

let parent = subnet.parent().ok_or_else(|| anyhow!("no parent found"))?;
let conn = match self.pool.get(&parent) {
None => return Err(anyhow!("target parent subnet not found")),
Some(conn) => conn,
Expand Down
6 changes: 1 addition & 5 deletions src/server/handlers/manager/leave.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,7 @@ impl JsonRPCRequestHandler for LeaveSubnetHandler {

async fn handle(&self, request: Self::Request) -> anyhow::Result<Self::Response> {
let subnet = SubnetID::from_str(&request.subnet)?;
let parent = subnet
.parent()
.ok_or_else(|| anyhow!("no parent found"))?
.to_string();

let parent = subnet.parent().ok_or_else(|| anyhow!("no parent found"))?;
let conn = match self.pool.get(&parent) {
None => return Err(anyhow!("target parent subnet not found")),
Some(conn) => conn,
Expand Down
4 changes: 3 additions & 1 deletion src/server/handlers/manager/list_subnets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::server::JsonRPCRequestHandler;
use anyhow::anyhow;
use async_trait::async_trait;
use fvm_shared::address::Address;
use ipc_sdk::subnet_id::SubnetID;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::str::FromStr;
Expand Down Expand Up @@ -38,7 +39,8 @@ impl JsonRPCRequestHandler for ListSubnetsHandler {
type Response = HashMap<String, SubnetInfo>;

async fn handle(&self, request: Self::Request) -> anyhow::Result<Self::Response> {
let conn = match self.pool.get(&request.subnet_id) {
let subnet = SubnetID::from_str(&request.subnet_id)?;
let conn = match self.pool.get(&subnet) {
None => return Err(anyhow!("target parent subnet not found")),
Some(conn) => conn,
};
Expand Down
3 changes: 2 additions & 1 deletion src/server/handlers/manager/propagate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ impl JsonRPCRequestHandler for PropagateHandler {
type Response = ();

async fn handle(&self, request: Self::Request) -> anyhow::Result<Self::Response> {
let conn = match self.pool.get(&request.subnet) {
let subnet = SubnetID::from_str(&request.subnet)?;
let conn = match self.pool.get(&subnet) {
None => return Err(anyhow!("target subnet not found")),
Some(conn) => conn,
};
Expand Down
5 changes: 2 additions & 3 deletions src/server/handlers/manager/release.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,16 @@ impl JsonRPCRequestHandler for ReleaseHandler {
type Response = ();

async fn handle(&self, request: Self::Request) -> anyhow::Result<Self::Response> {
let conn = match self.pool.get(&request.subnet) {
let subnet = SubnetID::from_str(&request.subnet)?;
let conn = match self.pool.get(&subnet) {
None => return Err(anyhow!("target subnet not found")),
Some(conn) => conn,
};

let subnet_config = conn.subnet();
check_subnet(subnet_config)?;

let subnet = SubnetID::from_str(&request.subnet)?;
let amount = TokenAmount::from_whole(request.amount);

let from = parse_from(subnet_config, request.from)?;

conn.manager().release(subnet, from, amount).await
Expand Down
4 changes: 3 additions & 1 deletion src/server/handlers/manager/send_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use anyhow::anyhow;
use async_trait::async_trait;
use fvm_shared::address::Address;
use fvm_shared::econ::TokenAmount;
use ipc_sdk::subnet_id::SubnetID;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use std::sync::Arc;
Expand Down Expand Up @@ -39,7 +40,8 @@ impl JsonRPCRequestHandler for SendValueHandler {
type Response = ();

async fn handle(&self, request: Self::Request) -> anyhow::Result<Self::Response> {
let conn = match self.pool.get(&request.subnet) {
let subnet = SubnetID::from_str(&request.subnet)?;
let conn = match self.pool.get(&subnet) {
None => return Err(anyhow!("target parent subnet not found")),
Some(conn) => conn,
};
Expand Down
Loading