Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Max/echo server clap #5317

Draft
wants to merge 102 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
c406814
tcp conn tracker
mfahampshire Nov 6, 2024
f53d2aa
small tweak to tcp tracker
mfahampshire Nov 6, 2024
1130d0f
name change + specific inc and dec logging
mfahampshire Nov 6, 2024
d423cde
changed logging
mfahampshire Nov 6, 2024
0c36e64
tweak
mfahampshire Nov 6, 2024
109de83
tweak
mfahampshire Nov 6, 2024
2e8e9a4
tweak existing conn tracker logic
mfahampshire Nov 21, 2024
530d744
make default decay const
mfahampshire Nov 21, 2024
5464829
first pass connpool
mfahampshire Nov 25, 2024
8e8eceb
fix flipped lowerthan waiting for pool
mfahampshire Nov 25, 2024
415c30f
first pass disconnect
mfahampshire Nov 26, 2024
6f4421d
trying to get disconnect to remove from pool
mfahampshire Nov 26, 2024
5083b42
remove double accounting for moment
mfahampshire Nov 26, 2024
4519bd6
remove comments and reduce logging verbosity
mfahampshire Nov 27, 2024
699aa61
comments
mfahampshire Nov 27, 2024
4273959
removed a bunch of commenting from example
mfahampshire Nov 27, 2024
8fcea5f
removed a bunch of commenting from example
mfahampshire Nov 27, 2024
4bb05f3
err handling conpool start
mfahampshire Nov 27, 2024
8c8e085
added notes for next features
mfahampshire Nov 27, 2024
c49f7f9
first version working
mfahampshire Nov 27, 2024
f87f57b
first pass spin out client_pool
mfahampshire Nov 27, 2024
4f1bac2
cancel token
mfahampshire Nov 27, 2024
13a6f0b
logging change
mfahampshire Nov 27, 2024
56becc3
minor tweaks
mfahampshire Nov 27, 2024
4eccc59
bump default decay time
mfahampshire Dec 2, 2024
c8ca174
updated code commnet
mfahampshire Dec 2, 2024
95274e3
bump default decay time
mfahampshire Dec 2, 2024
7563ccc
bump default decay time (again)
mfahampshire Dec 2, 2024
a0e55f4
temp commit
mfahampshire Dec 3, 2024
731f69a
add duplicate packets received to troubleshooting
mfahampshire Dec 13, 2024
e9ade22
slightly dropped default decay time
mfahampshire Dec 13, 2024
fa6efba
comments to examples
mfahampshire Dec 13, 2024
6fc2318
some inline comments
mfahampshire Dec 13, 2024
c7b3bd1
minor comments
mfahampshire Dec 13, 2024
747675f
client_pool.rs mod
mfahampshire Dec 13, 2024
7660f00
client pool example
mfahampshire Dec 13, 2024
fedaf00
clippy
mfahampshire Dec 13, 2024
68a1d43
comments
mfahampshire Dec 13, 2024
8630cef
client pool example done
mfahampshire Dec 13, 2024
5047ed2
added disconnect to client pool
mfahampshire Dec 13, 2024
70c1e4f
update mod file
mfahampshire Dec 13, 2024
0492d84
add cancel token disconnect fn
mfahampshire Dec 16, 2024
1015251
comments
mfahampshire Dec 16, 2024
3573d1e
comments
mfahampshire Dec 16, 2024
08f5749
add clone
mfahampshire Dec 16, 2024
7d2b1ca
added disconnect thread
mfahampshire Dec 16, 2024
f819b33
update example files tcpproxy
mfahampshire Dec 16, 2024
d59f05f
client pool docs
mfahampshire Dec 16, 2024
7fa1cdb
remove comments for future ffi push + lower default pool size from 4 …
mfahampshire Dec 16, 2024
7608ca7
comment on ffi
mfahampshire Dec 16, 2024
8864921
update command help
mfahampshire Dec 16, 2024
5cc5484
clone impl
mfahampshire Dec 16, 2024
349e95a
remove clone
mfahampshire Dec 16, 2024
f78bb83
fix clippy
mfahampshire Dec 16, 2024
9400140
fix clippy again
mfahampshire Dec 17, 2024
99d2a80
fix clippy again
mfahampshire Dec 17, 2024
d99cb96
version bump
mfahampshire Dec 17, 2024
7248218
version bump
mfahampshire Dec 17, 2024
9d8f14d
fix test
mfahampshire Dec 17, 2024
4f5d86a
tweaked text grammar
mfahampshire Dec 17, 2024
16c3e5f
updated comment in example
mfahampshire Dec 17, 2024
3fdaa7b
future is now
mfahampshire Dec 17, 2024
0f35f5c
add configurable gw to server
mfahampshire Dec 18, 2024
2fc359f
first pass echo server lib
mfahampshire Dec 19, 2024
d247c88
cargo fix
mfahampshire Dec 19, 2024
e2114dd
add disconnect
mfahampshire Dec 19, 2024
d7d2aaf
comment
mfahampshire Dec 19, 2024
b6b8ec4
first pass all fns
mfahampshire Dec 19, 2024
9761644
tweaks to lib
mfahampshire Dec 19, 2024
a9ef209
temp commit
mfahampshire Dec 19, 2024
060f785
temp commit
mfahampshire Dec 19, 2024
45bef0d
temp commit
mfahampshire Dec 20, 2024
814aeb5
clap standalone echo_server
mfahampshire Dec 30, 2024
fb63555
add metric getter + debug print
mfahampshire Dec 30, 2024
7066c11
deps
mfahampshire Dec 30, 2024
60e8f82
fix test
mfahampshire Dec 30, 2024
2d7957a
remove active conn
mfahampshire Dec 30, 2024
eef3405
logging tweak
mfahampshire Dec 30, 2024
6606fc8
work on test
mfahampshire Dec 30, 2024
1cd42bd
working on script fr testing all
mfahampshire Dec 30, 2024
ec77f1e
minor log tweak
mfahampshire Dec 31, 2024
0337c04
fixed test: needed proxiedMessage format
mfahampshire Dec 31, 2024
ffcc4e8
first pass tester
mfahampshire Jan 2, 2025
49e1134
cargo + todo list
mfahampshire Jan 2, 2025
5e9d253
cancel token
mfahampshire Jan 2, 2025
a87753f
remove scratch
mfahampshire Jan 2, 2025
20697fd
remove runs
mfahampshire Jan 2, 2025
54cec26
add dir creation + time dir to results
mfahampshire Jan 2, 2025
376eca6
cancel token fixes ongoing
mfahampshire Jan 2, 2025
93f063b
added test start fn to client_pool: uses specified gw for all clients
mfahampshire Jan 3, 2025
8dda5fb
comment
mfahampshire Jan 3, 2025
54d7b37
debugging failing lock quiring
mfahampshire Jan 3, 2025
50191cf
re-add commented out code fr sharing
mfahampshire Jan 6, 2025
3e1ea8e
remove comments
mfahampshire Jan 6, 2025
378ed88
comments
mfahampshire Jan 6, 2025
b73d66e
rearrange code, comment for rewrite of run()
mfahampshire Jan 6, 2025
d86286e
trying to make run_with_shutdown killable
mfahampshire Jan 7, 2025
e638f87
first pass done
mfahampshire Jan 8, 2025
3f90de1
update lock
mfahampshire Jan 8, 2025
45617cd
proper disconnect signals
mfahampshire Jan 8, 2025
5b536ee
proper disconnect signal management
mfahampshire Jan 8, 2025
499b1c7
license
mfahampshire Jan 8, 2025
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
34 changes: 32 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ members = [
"nym-node-status-api/nym-node-status-client",
"nym-outfox",
"nym-validator-rewarder",
"tools/echo-server",
# "tools/echo-server",
"tools/internal/ssl-inject",
# "tools/internal/sdk-version-bump",
"tools/internal/testnet-manager",
Expand All @@ -149,7 +149,7 @@ members = [
"tools/internal/testnet-manager",
"tools/internal/testnet-manager/dkg-bypass-contract",
"common/verloc",
"tools/internal/mixnet-connectivity-check",
"tools/internal/mixnet-connectivity-check", "tools/internal/mixnet-check-all-gateways",
]

default-members = [
Expand Down
1 change: 1 addition & 0 deletions documentation/docs/pages/developers/rust/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"development-status": "Development Status",
"mixnet": "Mixnet Module",
"tcpproxy": "TcpProxy Module",
"client-pool": "Client Pool",
"ffi": "FFI",
"tutorials": "Tutorials (Coming Soon)"
}
7 changes: 7 additions & 0 deletions documentation/docs/pages/developers/rust/client-pool.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Client Pool

We have a configurable-size Client Pool for processes that require multiple clients in quick succession (this is used by default by the [`TcpProxyClient`](./tcpproxy) for instance)

This will be useful for developers looking to build connection logic, or just are using raw SDK clients in a sitatuation where there are multiple connections with a lot of churn.

> You can find this code [here](https://github.com/nymtech/nym/blob/develop/sdk/rust/nym-sdk/examples/client_pool.rs)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"architecture": "Architecture",
"example": "Example"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Client Pool Architecture

## Motivations
In situations where multiple connections are expected, and the number of connections can vary greatly, the Client Pool reduces time spent waiting for the creation of a Mixnet Client blocking your code sending traffic through the Mixnet. Instead, a configurable number of Clients can be generated and run in the background which can be very quickly grabbed, used, and disconnected.

The Pool can be simply run as a background process for the runtime of your program.

## Clients & Lifetimes
The Client Pool creates **ephemeral Mixnet Clients** which are used and then disconnected. Using the [`TcpProxy`](../tcpproxy) as an example, Clients are used for the lifetime of a single incoming TCP connection; after the TCP connection is closed, the Mixnet client is disconnected.

Clients are popped from the pool when in use, and another Client is created to take its place. If connections are coming in faster than Clients are replenished, you can instead generate an ephemeral Client on the fly, or wait; this is up to the developer to decide. You can see an example of this logic in the example on the next page.

## Runtime Loop
Aside from a few helper / getter functions and a graceful `disconnect_pool()`, the Client Pool is mostly made up of a very simple loop around some conditional logic making up `start()`:
- if the number of Clients in the pool is `< client_pool_reserve_number` (set on `new()`) then create more,
- if the number of Clients in the pool `== client_pool_reserve_number` (set on `new()`) then `sleep`,
- if `client_pool_reserve_number == 0` just `sleep`.

`disconnect_pool()` will cause this loop to `break` via cancellation token.
100 changes: 100 additions & 0 deletions documentation/docs/pages/developers/rust/client-pool/example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Client Pool Example

> You can find this code [here](https://github.com/nymtech/nym/blob/develop/sdk/rust/nym-sdk/examples/client_pool.rs)

```rust
use anyhow::Result;
use nym_network_defaults::setup_env;
use nym_sdk::client_pool::ClientPool;
use nym_sdk::mixnet::{MixnetClientBuilder, NymNetworkDetails};
use tokio::signal::ctrl_c;

// This client pool is used internally by the TcpProxyClient but can also be used by the Mixnet module, in case you're quickly swapping clients in and out but won't want to use the TcpProxy module.
//
// Run with: cargo run --example client_pool -- ../../../envs/<NETWORK>.env
#[tokio::main]
async fn main() -> Result<()> {
nym_bin_common::logging::setup_logging();
setup_env(std::env::args().nth(1));

let conn_pool = ClientPool::new(2); // Start the Client Pool with 2 Clients always being kept in reserve
let client_maker = conn_pool.clone();
tokio::spawn(async move {
client_maker.start().await?;
Ok::<(), anyhow::Error>(())
});

println!("\n\nWaiting a few seconds to fill pool\n\n");
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;

let pool_clone_one = conn_pool.clone();
let pool_clone_two = conn_pool.clone();

tokio::spawn(async move {
let client_one = match pool_clone_one.get_mixnet_client().await {
Some(client) => {
println!("Grabbed client {} from pool", client.nym_address());
client
}
None => {
println!("Not enough clients in pool, creating ephemeral client");
let net = NymNetworkDetails::new_from_env();
let client = MixnetClientBuilder::new_ephemeral()
.network_details(net)
.build()?
.connect_to_mixnet()
.await?;
println!(
"Using {} for the moment, created outside of the connection pool",
client.nym_address()
);
client
}
};
let our_address = client_one.nym_address();
println!("\n\nClient 1: {our_address}\n\n");
client_one.disconnect().await;
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await; // Emulate doing something
return Ok::<(), anyhow::Error>(());
});

tokio::spawn(async move {
let client_two = match pool_clone_two.get_mixnet_client().await {
Some(client) => {
println!("Grabbed client {} from pool", client.nym_address());
client
}
None => {
println!("Not enough clients in pool, creating ephemeral client");
let net = NymNetworkDetails::new_from_env();
let client = MixnetClientBuilder::new_ephemeral()
.network_details(net)
.build()?
.connect_to_mixnet()
.await?;
println!(
"Using {} for the moment, created outside of the connection pool",
client.nym_address()
);
client
}
};
let our_address = *client_two.nym_address();
println!("\n\nClient 2: {our_address}\n\n");
client_two.disconnect().await;
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await; // Emulate doing something
return Ok::<(), anyhow::Error>(());
});

wait_for_ctrl_c(conn_pool).await?;
Ok(())
}

async fn wait_for_ctrl_c(pool: ClientPool) -> Result<()> {
println!("\n\nPress CTRL_C to disconnect pool\n\n");
ctrl_c().await?;
println!("CTRL_C received. Killing client pool");
pool.disconnect_pool().await;
Ok(())
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ In the future the SDK will be made up of several modules, each of which will all
|-----------|---------------------------------------------------------------------------------------|----------|
| Mixnet | Create / load clients & keypairs, subscribe to Mixnet events, send & receive messages | ✔️ |
| TcpProxy | Utilise the TcpProxyClient and TcpProxyServer abstractions for streaming | ✔️ |
| ClientPool| Create a pool of quickly useable Mixnet clients | ✔️ |
| Ecash | Create & verify Ecash credentials | ❌ |
| Validator | Sign & broadcast Nyx blockchain transactions, query the blockchain | ❌ |

The `Mixnet` module currently exposes the logic of two clients: the [websocket client](../clients/websocket), and the [socks client](../clients/socks5).

The `TcpProxy` module exposes functionality to set up client/server instances that expose a localhost TcpSocket to read/write to.

The `ClientPool` is a configurable pool of ephemeral clients which can be created as a background process and quickly grabbed.
9 changes: 6 additions & 3 deletions documentation/docs/pages/developers/rust/ffi.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The main functionality of exposed functions will be imported from `sdk/ffi/share

Furthermore, the `shared/` code makes sure that client access is thread-safe, and that client actions happen in blocking threads on the Rust side of the FFI boundary.

### Mixnet Module
## Mixnet Module
This is the basic mixnet component of the SDK, exposing client functionality with which people can build custom interfaces with the Mixnet. These functions are exposed to both Go and C/C++ via the `sdk/ffi/shared/` crate.

| `shared/lib.rs` function | Rust Function |
Expand All @@ -36,13 +36,13 @@ This is the basic mixnet component of the SDK, exposing client functionality wit

> We have also implemented `listen_for_incoming_internal()` which is a wrapper around the Mixnet client's `wait_for_messages()`. This is a helper method for listening out for and handling incoming messages.

#### Currently Unsupported Functionality
### Currently Unsupported Functionality
At the time of writing the following functionality is not exposed to the shared FFI library:
- `split_sender()`: the ability to [split a client into sender and receiver](./mixnet/examples/split-send) for concurrent send/receive.
- The use of [custom network topologies](./mixnet/examples/custom-topology).
- `Socks5::new()`: creation and use of the [socks5/4a/4 proxy client](./mixnet/examples/socks).

### TcpProxy Module
## TcpProxy Module
A connection abstraction which exposes a local TCP socket which developers are able to interact with basically as expected, being able to read/write to/from a bytestream, without really having to take into account the workings of the Mixnet/Sphinx/the [message-based](../concepts/messages) format of the underlying client.

<Callout type="info" emoji="ℹ️">
Expand All @@ -58,3 +58,6 @@ A connection abstraction which exposes a local TCP socket which developers are a
| `proxy_server_new_internal(upstream_address: &str, config_dir: &str, env: Option<String>)` | `NymProxyServer::new(upstream_address, config_dir, env)` |
| `proxy_server_run_internal()` | `NymProxyServer.run_with_shutdown()` |
| `proxy_server_address_internal()` | `NymProxyServer.nym_address()` |

## Client Pool
There are currently no FFI bindings for the Client Pool. This will be coming in the future. The bindings for the TcpProxy have been updated to be able to use the Client Pool under the hood, but the standalone Pool is not yet exposed to FFI.
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,6 @@ Whether the `data` of a SURB request being empty is a feature or a bug is to be
You can find a few helper functions [here](./message-helpers.md) to help deal with this issue in the meantime.

> If you can think of a more succinct or different way of handling this do reach out - we're happy to hear other opinions

## Lots of `duplicate fragment received` messages
You might see a lot of `WARN` level logs about duplicate fragments in your logs, depending on the log level you're using. This occurs when a packet is retransmitted somewhere in the Mixnet, but then the original makes it to the destination client as well. This is not something to do with your client logic, but instead the state of the Mixnet.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"architecture": "Architecture",
"examples": "Examples"
"examples": "Examples",
"troubleshooting": "Troubleshooting"
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The motivation behind the creation of the `TcpProxy` module is to allow develope

## Clients
Each of the sub-modules exposed by the `TcpProxy` deal with Nym clients in a different way.
- the `NymProxyClient` creates an ephemeral client per new TCP connection, which is closed according to the configurable timeout: we map one ephemeral client per TCP connection. This is to deal with multiple simultaneous streams. In the future, this will be superceded by a connection pool in order to speed up new connections.
- the `NymProxyClient` relies on the [`Client Pool`](../client-pool) to create clients and keep a certain number of them in reserve. If the amount of incoming TCP connections rises quicker than the Client Pool can create clients, or you have the pool size set to `0`, the `TcpProxyClient` creates an ephemeral client per new TCP connection, which is closed according to the configurable timeout: we map one ephemeral client per TCP connection. This is to deal with multiple simultaneous streams.
- the `NymProxyServer` has a single Nym client with a persistent identity.

## Framing
Expand Down
Loading
Loading