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

Commit

Permalink
Include gateway addr in subnet config (#137)
Browse files Browse the repository at this point in the history
* update config

* format code

* Update checkpoint.rs

* use addr instead of id

* merge with main

* initial commit (#142)
  • Loading branch information
cryptoAtwill authored Mar 30, 2023
1 parent 2ab43a3 commit 507c009
Show file tree
Hide file tree
Showing 23 changed files with 199 additions and 92 deletions.
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 = "t064"
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]]
id = "/root/t0100"
network_name = "child"
gateway_addr = "t064"
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_str<'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 string")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
Address::from_str(v).map_err(E::custom)
}
}
deserializer.deserialize_str(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
16 changes: 10 additions & 6 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,34 @@ 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;
pub use server::{json_rpc_methods, Server};
pub use subnet::Subnet;

pub const JSON_RPC_VERSION: &str = "2.0";
pub const DEFAULT_IPC_GATEWAY_ADDR: u64 = 64;

/// Default config template
pub const DEFAULT_CONFIG_TEMPLATE: &str = r#"
[server]
json_rpc_address = "127.0.0.1:3030"
[subnets]
[subnets."/root"]
[[subnets]]
id = "/root"
gateway_addr = "t064"
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 = "t064"
network_name = "child"
jsonrpc_api_http = "http://127.0.0.1:1235/rpc/v1"
auth_token = "YOUR TOKEN"
accounts = ["t01"]
Expand All @@ -53,7 +56,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_str, 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_str")]
// 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: &str = "t064";
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::from_str(GATEWAY_ADDR).unwrap());
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::from_str(GATEWAY_ADDR).unwrap());
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
35 changes: 27 additions & 8 deletions src/manager/lotus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use ipc_gateway::{Checkpoint, PropagateParams, WhitelistPropagatorParams};
use ipc_sdk::subnet_id::SubnetID;
use ipc_subnet_actor::{types::MANIFEST_ID, ConstructParams, JoinParams};

use crate::config::{Subnet, DEFAULT_IPC_GATEWAY_ADDR};
use crate::config::Subnet;
use crate::jsonrpc::{JsonRpcClient, JsonRpcClientImpl};
use crate::lotus::client::LotusJsonRPCClient;
use crate::lotus::message::ipc::{CheckpointResponse, SubnetInfo};
Expand Down Expand Up @@ -155,7 +155,13 @@ impl<T: JsonRpcClient + Send + Sync> SubnetManager for LotusSubnetManager<T> {
Ok(map)
}

async fn fund(&self, subnet: SubnetID, from: Address, amount: TokenAmount) -> Result<()> {
async fn fund(
&self,
subnet: SubnetID,
gateway_addr: Address,
from: Address,
amount: TokenAmount,
) -> Result<()> {
// When we perform the fund, we should send to the gateway of the subnet's parent
let parent = subnet.parent().ok_or_else(|| anyhow!("cannot fund root"))?;
if !self.is_network_match(&parent).await? {
Expand All @@ -166,7 +172,7 @@ impl<T: JsonRpcClient + Send + Sync> SubnetManager for LotusSubnetManager<T> {

let fund_params = cbor::serialize(&subnet, "fund subnet actor params")?;
let mut message = MpoolPushMessage::new(
Address::new_id(DEFAULT_IPC_GATEWAY_ADDR),
gateway_addr,
from,
ipc_gateway::Method::Fund as MethodNum,
fund_params.to_vec(),
Expand All @@ -177,7 +183,13 @@ impl<T: JsonRpcClient + Send + Sync> SubnetManager for LotusSubnetManager<T> {
Ok(())
}

async fn release(&self, subnet: SubnetID, from: Address, amount: TokenAmount) -> Result<()> {
async fn release(
&self,
subnet: SubnetID,
gateway_addr: Address,
from: Address,
amount: TokenAmount,
) -> Result<()> {
// When we perform the release, we should send to the gateway of the subnet
if !self.is_network_match(&subnet).await? {
return Err(anyhow!(
Expand All @@ -186,7 +198,7 @@ impl<T: JsonRpcClient + Send + Sync> SubnetManager for LotusSubnetManager<T> {
}

let mut message = MpoolPushMessage::new(
Address::new_id(DEFAULT_IPC_GATEWAY_ADDR),
gateway_addr,
from,
ipc_gateway::Method::Release as MethodNum,
vec![],
Expand All @@ -197,7 +209,13 @@ impl<T: JsonRpcClient + Send + Sync> SubnetManager for LotusSubnetManager<T> {
Ok(())
}

async fn propagate(&self, subnet: SubnetID, from: Address, postbox_msg_cid: Cid) -> Result<()> {
async fn propagate(
&self,
subnet: SubnetID,
gateway_addr: Address,
from: Address,
postbox_msg_cid: Cid,
) -> Result<()> {
if !self.is_network_match(&subnet).await? {
return Err(anyhow!("propagation not targeting the correct network"));
}
Expand All @@ -210,7 +228,7 @@ impl<T: JsonRpcClient + Send + Sync> SubnetManager for LotusSubnetManager<T> {
)?;

let message = MpoolPushMessage::new(
Address::new_id(DEFAULT_IPC_GATEWAY_ADDR),
gateway_addr,
from,
ipc_gateway::Method::Propagate as MethodNum,
params.to_vec(),
Expand Down Expand Up @@ -253,6 +271,7 @@ impl<T: JsonRpcClient + Send + Sync> SubnetManager for LotusSubnetManager<T> {
async fn whitelist_propagator(
&self,
subnet: SubnetID,
gateway_addr: Address,
postbox_msg_cid: Cid,
from: Address,
to_add: Vec<Address>,
Expand All @@ -270,7 +289,7 @@ impl<T: JsonRpcClient + Send + Sync> SubnetManager for LotusSubnetManager<T> {
)?;

let message = MpoolPushMessage::new(
Address::new_id(DEFAULT_IPC_GATEWAY_ADDR),
gateway_addr,
from,
ipc_gateway::Method::WhiteListPropagator as MethodNum,
params.to_vec(),
Expand Down
Loading

0 comments on commit 507c009

Please sign in to comment.