Skip to content

Commit

Permalink
Improve consistency and documentation of configuration API (#528)
Browse files Browse the repository at this point in the history
* Correct value name for clap args

* Remove wildcard option from block list config

* Allow wildcard in clap for allow-peer-ids

* Move workers section to the end of config.toml

* Extend description for allow and block lists

* Consistent ordering of config keys

* Consistent doc strings for all configuration APIs

* Move warnings into separate method

* Do not connect to other relays when relay mode is enabled

* Print private key configuration

* Add entry to CHANGELOG.md
  • Loading branch information
adzialocha authored Aug 25, 2023
1 parent 99ed7e8 commit 8b1ba91
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 161 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- By default, nodes support _any_ schema [#487](https://github.com/p2panda/aquadoggo/pull/487)
- Rework networking service [#502](https://github.com/p2panda/aquadoggo/pull/502)
- Deduplicate peer connections when initiating replication sessions [#525](https://github.com/p2panda/aquadoggo/pull/525)
- Improve consistency and documentation of configuration API [#528](https://github.com/p2panda/aquadoggo/pull/528)

### Fixed

Expand Down
22 changes: 15 additions & 7 deletions aquadoggo/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ use crate::network::NetworkConfiguration;
/// Configuration object holding all important variables throughout the application.
#[derive(Debug, Clone)]
pub struct Configuration {
/// List of schema ids which a node will replicate, persist and expose on the GraphQL API.
///
/// When allowing a schema you automatically opt into announcing, replicating and materializing
/// documents connected to it, supporting applications and networks which are dependent on this
/// data.
///
/// It is recommended to set this list to all schema ids your own application should support,
/// including all important system schemas.
///
/// **Warning**: When set to `AllowList::Wildcard`, your node will support _any_ schemas it
/// will encounter on the network. This is useful for experimentation and local development but
/// _not_ recommended for production settings.
pub allow_schema_ids: AllowList<SchemaId>,

/// URL / connection string to PostgreSQL or SQLite database.
pub database_url: String,

Expand All @@ -29,24 +43,18 @@ pub struct Configuration {
/// number for low-energy devices with limited resources.
pub worker_pool_size: u32,

/// List of schema ids which a node will replicate and expose on the GraphQL API.
///
/// When allowing a schema you automatically opt into announcing, replicating and materializing
/// documents connected to it, supporting applications which are dependent on this data.
pub allow_schema_ids: AllowList<SchemaId>,

/// Network configuration.
pub network: NetworkConfiguration,
}

impl Default for Configuration {
fn default() -> Self {
Self {
allow_schema_ids: AllowList::Wildcard,
database_url: "sqlite::memory:".into(),
database_max_connections: 32,
http_port: 2020,
worker_pool_size: 16,
allow_schema_ids: AllowList::Wildcard,
network: NetworkConfiguration::default(),
}
}
Expand Down
36 changes: 18 additions & 18 deletions aquadoggo/src/network/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use log::debug;
use crate::network::config::NODE_NAMESPACE;
use crate::network::peers;
use crate::network::NetworkConfiguration;
use crate::AllowList;

/// How often do we broadcast mDNS queries into the network.
const MDNS_QUERY_INTERVAL: Duration = Duration::from_secs(5);
Expand Down Expand Up @@ -73,14 +74,14 @@ pub struct P2pandaBehaviour {
/// to each other to their predicted external address with help of a third-party relay server.
pub dcutr: Toggle<dcutr::Behaviour>,

/// Register peer connections and handle p2panda messaging with them.
pub peers: peers::Behaviour,

/// Allow connections based on an allow list of peer ids.
pub allowed_peers: Toggle<allow_block_list::Behaviour<AllowedPeers>>,

/// Block connections based on a block list of peer ids.
pub blocked_peers: Toggle<allow_block_list::Behaviour<BlockedPeers>>,

/// Register peer connections and handle p2panda messaging with them.
pub peers: peers::Behaviour,
}

impl P2pandaBehaviour {
Expand Down Expand Up @@ -169,13 +170,10 @@ impl P2pandaBehaviour {
None
};

// Always create behaviour to manage peer connections and handle p2panda messaging
let peers = peers::Behaviour::new();

// Construct behaviour to manage an allow list of peers when configured.
// Construct behaviour to manage an allow list of peers when configured
let allowed_peers = match &network_config.allow_peer_ids {
crate::AllowList::Wildcard => None,
crate::AllowList::Set(allow_peer_ids) => {
AllowList::Wildcard => None,
AllowList::Set(allow_peer_ids) => {
let mut allowed_peers = allow_block_list::Behaviour::default();
for peer_id in allow_peer_ids {
allowed_peers.allow_peer(*peer_id)
Expand All @@ -184,18 +182,20 @@ impl P2pandaBehaviour {
}
};

// Construct behaviour to manage a block list of peers when configured.
let blocked_peers = match &network_config.block_peer_ids {
crate::AllowList::Wildcard => None,
crate::AllowList::Set(block_peer_ids) => {
let mut blocked_peers = allow_block_list::Behaviour::default();
for peer_id in block_peer_ids {
blocked_peers.block_peer(*peer_id)
}
Some(blocked_peers)
// Construct behaviour to manage a block list of peers when configured
let blocked_peers = if network_config.block_peer_ids.is_empty() {
None
} else {
let mut blocked_peers = allow_block_list::Behaviour::default();
for peer_id in &network_config.block_peer_ids {
blocked_peers.block_peer(*peer_id)
}
Some(blocked_peers)
};

// Always create behaviour to manage peer connections and handle p2panda messaging
let peers = peers::Behaviour::new();

Ok(Self {
identify: identify.into(),
mdns: mdns.into(),
Expand Down
91 changes: 53 additions & 38 deletions aquadoggo/src/network/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,51 +11,66 @@ pub const NODE_NAMESPACE: &str = "aquadoggo";
/// Network config for the node.
#[derive(Debug, Clone)]
pub struct NetworkConfiguration {
/// QUIC port for node-to-node communication.
/// QUIC port for node-node communication and data replication.
pub quic_port: u16,

/// Discover peers on the local network via mDNS (over IPv4 only, using port 5353).
pub mdns: bool,

/// List of known node addresses (IP + port) we want to connect to directly.
/// List of known node addresses we want to connect to directly.
///
/// Make sure that nodes mentioned in this list are directly reachable (for example they need
/// to be hosted with a static IP Address). If you need to connect to nodes with changing,
/// dynamic IP addresses or even with nodes behind a firewall or NAT, do not use this field but
/// use at least one relay.
/// Make sure that nodes mentioned in this list are directly reachable (they need to be hosted
/// with a static IP Address). If you need to connect to nodes with changing, dynamic IP
/// addresses or even with nodes behind a firewall or NAT, do not use this field but use at
/// least one relay.
pub direct_node_addresses: Vec<Multiaddr>,

/// Set to true if node should also function as a relay. Other nodes can use relays to aid
/// discovery and establishing connectivity.
/// List of peers which are allowed to connect to your node.
///
/// Relays _need_ to be hosted in a way where they can be reached directly, for example with a
/// static IP address through an VPS.
pub relay_mode: bool,
/// If set then only nodes (identified by their peer id) contained in this list will be able to
/// connect to your node (via a relay or directly). When not set any other node can connect to
/// yours.
///
/// Peer IDs identify nodes by using their hashed public keys. They do _not_ represent authored
/// data from clients and are only used to authenticate nodes towards each other during
/// networking.
///
/// Use this list for example for setups where the identifier of the nodes you want to form a
/// network with is known but you still need to use relays as their IP addresses change
/// dynamically.
pub allow_peer_ids: AllowList<PeerId>,

/// Addresses of a peers which can act as a relay/rendezvous server.
/// List of peers which will be blocked from connecting to your node.
///
/// Relays help discover other nodes on the internet (also known as "rendesvouz" or "bootstrap"
/// server) and help establishing direct p2p connections when node is behind a firewall or NAT
/// (also known as "holepunching").
/// If set then any peers (identified by their peer id) contained in this list will be blocked
/// from connecting to your node (via a relay or directly). When an empty list is provided then
/// there are no restrictions on which nodes can connect to yours.
///
/// When a direct connection is not possible the relay will help to redirect the (encrypted)
/// traffic as an intermediary between us and other nodes. The node will contact each server
/// and register our IP address for other peers.
pub relay_addresses: Vec<Multiaddr>,
/// Block lists and allow lists are exclusive, which means that you should _either_ use a block
/// list _or_ an allow list depending on your setup.
///
/// Use this list for example if you want to allow _any_ node to connect to yours _except_ of a
/// known number of excluded nodes.
pub block_peer_ids: Vec<PeerId>,

/// List of peers which can connect to our node.
/// List of relay addresses.
///
/// If set then only peers (identified by their peer id) contained in this list will be able
/// to connect to our node (via a relay or directly). When not set then there are no
/// restrictions on which nodes can connect to ours.
pub allow_peer_ids: AllowList<PeerId>,
/// A relay helps discover other nodes on the internet (also known as "rendesvouz" or
/// "bootstrap" server) and helps establishing direct p2p connections when node is behind a
/// firewall or NAT (also known as "holepunching").
///
/// WARNING: This will potentially expose your IP address on the network. Do only connect to
/// trusted relays or make sure your IP address is hidden via a VPN or proxy if you're
/// concerned about leaking your IP.
pub relay_addresses: Vec<Multiaddr>,

/// List of peers which can connect to our node.
/// Enable if node should also function as a relay.
///
/// Other nodes can use relays to aid discovery and establishing connectivity.
///
/// If set then only peers (identified by their peer id) contained in this list will be able
/// to connect to our node (via a relay or directly). When not set then there are no
/// restrictions on which nodes can connect to ours.
pub block_peer_ids: AllowList<PeerId>,
/// Relays _need_ to be hosted in a way where they can be reached directly, for example with a
/// static IP address through an VPS.
pub relay_mode: bool,

/// Notify handler buffer size.
///
Expand Down Expand Up @@ -101,21 +116,21 @@ pub struct NetworkConfiguration {
impl Default for NetworkConfiguration {
fn default() -> Self {
Self {
quic_port: 2022,
mdns: true,
direct_node_addresses: Vec::new(),
allow_peer_ids: AllowList::<PeerId>::Wildcard,
block_peer_ids: Vec::new(),
relay_addresses: Vec::new(),
relay_mode: false,
notify_handler_buffer_size: 128,
per_connection_event_buffer_size: 8,
dial_concurrency_factor: 8,
max_connections_in: 16,
max_connections_out: 16,
max_connections_pending_in: 8,
max_connections_pending_out: 8,
max_connections_per_peer: 8,
mdns: true,
direct_node_addresses: Vec::new(),
notify_handler_buffer_size: 128,
per_connection_event_buffer_size: 8,
quic_port: 2022,
relay_mode: false,
relay_addresses: Vec::new(),
allow_peer_ids: AllowList::<PeerId>::Wildcard,
block_peer_ids: AllowList::<PeerId>::Wildcard,
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion aquadoggo/src/network/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ pub async fn network_service(

// If relay node addresses were provided, then connect to each and perform necessary setup before we
// run the main event loop.
//
// We are not connecting to other relays when in relay mode (is this even supported by libp2p)?
// See related issue: https://github.com/p2panda/aquadoggo/issues/529
let mut connected_relays = HashMap::new();
if !network_config.relay_addresses.is_empty() {
if !network_config.relay_addresses.is_empty() && !network_config.relay_mode {
// First we need to stop the "peers" behaviour.
//
// We do this so that the connections we create during initialization do not trigger
Expand Down
72 changes: 41 additions & 31 deletions aquadoggo_cli/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,6 @@ allow_schema_ids = "*"
#
database_max_connections = 32

# ゚・。+☆+。・
# WORKERS
# ゚・。+☆+。・

# Number of concurrent workers which defines the maximum of materialization
# tasks which can be worked on simultaneously.
#
# Use a higher number if you run your node on a powerful machine with many CPU
# cores. Lower number for low-energy devices with limited resources.
#
worker_pool_size = 16

# ゚・。+☆
# PORTS
# ゚・。+☆
Expand Down Expand Up @@ -130,42 +118,52 @@ mdns = true

# List of known node addresses (IP + port) we want to connect to directly.
#
# NOTE: Make sure that nodes mentioned in this list are directly reachable (for
# example they need to be hosted with a static IP Address). If you need to
# connect to nodes with changing, dynamic IP addresses or even with nodes
# behind a firewall or NAT, do not use this field but use at least one relay.
# NOTE: Make sure that nodes mentioned in this list are directly reachable
# (they need to be hosted with a static IP Address). If you need to connect to
# nodes with changing, dynamic IP addresses or even with nodes behind a
# firewall or NAT, do not use this field but use at least one relay.
#
direct_node_addresses = [
# "192.0.2.0:2022",
# "192.0.2.2:3000",
]

# List of peers which can connect to our node.
# List of peers which are allowed to connect to your node.
#
# If set then only peers (identified by their peer id) contained in this list
# will be able to connect to our node (via a relay or directly). When not set
# then there are no restrictions on which nodes can connect to ours.
# If set then only nodes (identified by their peer id) contained in this list
# will be able to connect to your node (via a relay or directly). When not set
# any other node can connect to yours.
#
# WARNING: When set to wildcard "*", your node will accept connections requests
# from any peers. This is useful for experimentation and local development or
# settings where access to the network is secured via other means.
# Peer IDs identify nodes by using their hashed public keys. They do _not_
# represent authored data from clients and are only used to authenticate nodes
# towards each other during networking.
#
# Use this list for example for setups where the identifier of the nodes you
# want to form a network with is known but you still need to use relays as
# their IP addresses change dynamically.
#
allow_peer_ids = "*"

# List of peers which will be blocked from connecting to our node.
# List of peers which will be blocked from connecting to your node.
#
# If set then any peers (identified by their peer id) contained in this list
# will be blocked from connecting to our node (via a relay or directly). When
# will be blocked from connecting to your node (via a relay or directly). When
# an empty list is provided then there are no restrictions on which nodes can
# connect to ours.
# connect to yours.
#
# Block lists and allow lists are exclusive, which means that you should
# _either_ use a block list _or_ an allow list depending on your setup.
#
# Use this list for example if you want to allow _any_ node to connect to yours
# _except_ of a known number of excluded nodes.
#
block_peer_ids = []

# ゚・。+☆
# RELAY
# ゚・。+☆
# ゚・。+☆+
# RELAYS
# ゚・。+☆+

# Address of a relays.
# List of relay addresses.
#
# A relay helps discover other nodes on the internet (also known as
# "rendesvouz" or "bootstrap" server) and helps establishing direct p2p
Expand All @@ -174,7 +172,7 @@ block_peer_ids = []
#
# When a direct connection is not possible the relay will help to redirect the
# (encrypted) traffic as an intermediary between us and other nodes. The node
# will contact the relay and register our IP address for other peers.
# will contact the relay and register your IP address for other peers.
#
# WARNING: This will potentially expose your IP address on the network. Do only
# connect to trusted relays or make sure your IP address is hidden via a VPN or
Expand All @@ -197,3 +195,15 @@ relay_addresses = [
# for example with a static IP address through an VPS.
#
relay_mode = false

# ゚・。+☆+。・
# WORKERS
# ゚・。+☆+。・

# Number of concurrent workers which defines the maximum of materialization
# tasks which can be worked on simultaneously.
#
# Use a higher number if you run your node on a powerful machine with many CPU
# cores. Lower number for low-energy devices with limited resources.
#
worker_pool_size = 16
Loading

0 comments on commit 8b1ba91

Please sign in to comment.