PunchNet [24/04/24 Testnet] [Offline]

With this testnet we’re going to punch some holes!

Computers in a home network will normally be unreachable from the outside, unless ports are forwarded manually. Lately, we’ve been experimenting with relays and hole punching, meaning nodes from inside a home network can participate in the network.

Home nodes will be reachable through public nodes that feature relay server capability. When home nodes are contacted through these relays, this relayed connection is attempted to be upgraded to a direct connection. Upgrading will involve hole punching. On success, data can flow between the home node and peer directly, without involvement of the relay.

For the first iteration of this testnet, we must manually specify --home-network to enable hole punching for a node. We are planning to eliminate this argument further down the line with the help of AutoNAT, but for now, if you know you’re behind a NAT, you can use this argument. Publically reachable nodes can ignore this argument.

Some Caveats

  • This is an experimental version where the relay servers are practically uncapped, so you can expect some extra incoming connections from home nodes.
  • If you are running both a client and node from the same home network, they still have issue talking with each other. So your own home node cannot get chunk rewards from the uploads that are made from your home client.

Network Details

Node version: 0.106.0-alpha.4
Client version: 0.91.0-alpha.4
Faucet url:

We have 50 droplets running a total of 2000 nodes. One droplet has 2vcpu and 4GB of memory.

If you are a regular user, see the ‘quickstart’ section for getting up and running.

If you are a first-time user, or would like more information, see the ‘further information’ section.


If you already have safeup, you can obtain the client and node binaries:

safeup client --version 0.91.0-alpha.4
safeup node --version 0.106.0-alpha.4

Run a Node

safenode [--home-network]

Notice the --home-network argument here, use this if you know you are behind a NAT firewall.

Check local node’s reward balance

Your local node’s peer id will be printed to the terminal on startup with an example command). (You can also retrieve this from the node directory.)

safe wallet balance --peer-id="<local-node-peer-id>"

Connect to the Network as a Client

safe wallet get-faucet
safe files upload <directory-path>

To do this with non-default batch-sizes (along with SAFE_PEERS set as above):

safe files upload --batch-size 40 <directory-path> 

40 being the integer value you want to set

Further Information

You can participate in the testnet either by connecting as a client or running your own node.

Connecting as a client requires the safe client binary; running a node requires the safenode binary.

Obtaining Binaries

We have a tool named safeup which is intended to make it easy to obtain the client, node, and other utility binaries.

Installing Safeup

On Linux/macOS, run the following command in your terminal:

curl -sSL https://raw.githubusercontent.com/maidsafe/safeup/main/install.sh | bash

On Windows, run the following command in a Powershell session (be careful to use Powershell, not cmd.exe):

iex (Invoke-RestMethod -Uri "https://raw.githubusercontent.com/maidsafe/safeup/main/install.ps1")

On either platform, you may need to restart your shell session for safeup to become available.

Installing Binaries

After obtaining safeup, you can install binaries like so:

safeup client # get the latest version of the client
safeup client --version 0.91.0-alpha.4 # get a specific version

safeup node # get the latest version of the node
safeup node --version 0.106.0-alpha.4 # get a specific version

safeup update # update all installed components to latest versions

When participating in our testnets, it is recommended to use a specific version. In our project we release a new version of the binaries every time we merge new code. This happens frequently, so over the lifetime of a testnet, many new releases will probably occur. So for participating in this particular testnet, you may not want the latest version.

The binaries are installed to ~/.local/bin on Linux and macOS, and on Windows they go to C:\Users\<username>\safe. Windows doesn’t really have a standard location for binaries that doesn’t require elevated privileges.

The safeup tool will modify the PATH variable on Linux/macOS, or the user Path variable on Windows. The effect of this is that the installed binaries will then become available in your shell without having to refer to them with their full paths. However, if you’re installing for the first time, you may need to start a new shell session for this change to be picked up.

Running a Node

You can participate in the testnet by running your own node. If you are running the node from your home machine, you must specify the home-network argument. But if you run from a cloud provider like Digital Ocean or AWS, you can ignore this argument.

Not specifying this argument will make your node act as a Relay Server, which will facilitate the people behind NATs to perform hole punching.

You can run the node process like so:

# Home machine:
safenode --home-network --peer /ip4/

# Cloud Providers:
safenode --peer /ip4/

This will output all the logs to the filesystem, with the location of logs being platform specific:

# Linux
~/.local/share/safe/node/<peer id>/logs

# macOS
/Users/<username>/Library/Application Support/safe/node/<peer id>/logs

# Windows

If you wish, you can also provide your own path:

# Linux/macOS
SN_LOG=all safenode --log-output-dest <path>

# Windows
$env:SN_LOG = "all"; safenode --log-output-dest <path>

The advantage of using the predefined data-dir location is you can run multiple nodes on one machine without having to specify your own unique path for each node and manage that overhead yourself.

Connecting as a Client

You can use the safe client binary to connect as a client and upload or download files to/from the network.

Using the Client

You’ll first need to get some Safe Network Tokens:

safe wallet get-faucet

You can now proceed to use the client, by, e.g., uploading files:

safe files upload <directory-path>

To download that same content:

safe files download

This will download the files to the default location, which is platform specific:

# Linux

# macOS
/Users/<username>/Library/Application Support/safe/client/downloaded_files

# Windows

To download to a particular file or directory:

safe file download [directory/filename] [NetworkAddress]



If you’ve used previous versions of the network before and you find problems when running commands, you may want to consider clearing out previous data (worthless DBCs from previous runs, old logs, old keys, etc.).

# Linux
rm -rf ~/.local/share/safe

# macOS
rm -rf ~/Library/Application\ Support/safe

# Windows
rmdir /s C:\Users\<username>\AppData\Roaming\safe

If you encounter a problem running any of our binaries on Windows, it’s possible you need the Visual C++ Redistributable installed.


It is show time :slight_smile: good to see this.

Hey, Satoshi. As long as there is a limit to the bandwidth, We dont repeat Gentleman’s agreement again.

Hat off team.


Almost first! Welcome PunchNet


Oh, exciting! I’ll fire up some nodes shortly!


Damn some warning would be nice, I am going to pick myself off the floor now after that knockout punch


Can we use safenode-manager together with the new parameter for the home network somehow?


First attempt at starting safenode-manager failed. The second one had success. This has already happened few times

 $ safenode-manager start
             Start Safenode Services
Refreshing the node registry...
Attempting to start safenode1...
Attempting to start safenode2...
Attempting to start safenode3...
Attempting to start safenode4...
Attempting to start safenode5...
Attempting to start safenode6...
Attempting to start safenode7...
Attempting to start safenode8...
Attempting to start safenode9...
Attempting to start safenode10...
Failed to start 10 service(s):
✕ safenode1: Could not connect to RPC endpoint 'abcd'
✕ safenode2: Could not connect to RPC endpoint 'abcd'
✕ safenode3: Could not connect to RPC endpoint 'abcd'
✕ safenode4: Could not connect to RPC endpoint 'abcd'
✕ safenode5: Could not connect to RPC endpoint 'abcd'
✕ safenode6: Could not connect to RPC endpoint 'abcd'
✕ safenode7: Could not connect to RPC endpoint 'abcd'
✕ safenode8: Could not connect to RPC endpoint 'abcd'
✕ safenode9: Could not connect to RPC endpoint 'abcd'
✕ safenode10: Could not connect to RPC endpoint 'abcd'
   0: Failed to start one or more services


Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.
 $ safenode-manager start
             Start Safenode Services
Refreshing the node registry...
Attempting to start safenode1...
✓ Started safenode1 service
  - PID: 45234
  - Bin path: /var/safenode-manager/services/safenode1/safenode
  - Data path: /var/safenode-manager/services/safenode1
  - Logs path: /var/log/safenode/safenode1
Attempting to start safenode2...
✓ Started safenode2 service
  - PID: 45243
  - Bin path: /var/safenode-manager/services/safenode2/safenode
  - Data path: /var/safenode-manager/services/safenode2
  - Logs path: /var/log/safenode/safenode2
Attempting to start safenode3...
✓ Started safenode3 service
  - PID: 45250
  - Bin path: /var/safenode-manager/services/safenode3/safenode
  - Data path: /var/safenode-manager/services/safenode3
  - Logs path: /var/log/safenode/safenode3
Attempting to start safenode4...
✓ Started safenode4 service
  - PID: 45263
  - Bin path: /var/safenode-manager/services/safenode4/safenode
  - Data path: /var/safenode-manager/services/safenode4
  - Logs path: /var/log/safenode/safenode4
Attempting to start safenode5...
✓ Started safenode5 service
  - PID: 45271
  - Bin path: /var/safenode-manager/services/safenode5/safenode
  - Data path: /var/safenode-manager/services/safenode5
  - Logs path: /var/log/safenode/safenode5
Attempting to start safenode6...
✓ Started safenode6 service
  - PID: 45278
  - Bin path: /var/safenode-manager/services/safenode6/safenode
  - Data path: /var/safenode-manager/services/safenode6
  - Logs path: /var/log/safenode/safenode6
Attempting to start safenode7...
✓ Started safenode7 service
  - PID: 45287
  - Bin path: /var/safenode-manager/services/safenode7/safenode
  - Data path: /var/safenode-manager/services/safenode7
  - Logs path: /var/log/safenode/safenode7
Attempting to start safenode8...
✓ Started safenode8 service
  - PID: 45296
  - Bin path: /var/safenode-manager/services/safenode8/safenode
  - Data path: /var/safenode-manager/services/safenode8
  - Logs path: /var/log/safenode/safenode8
Attempting to start safenode9...
✓ Started safenode9 service
  - PID: 45303
  - Bin path: /var/safenode-manager/services/safenode9/safenode
  - Data path: /var/safenode-manager/services/safenode9
  - Logs path: /var/log/safenode/safenode9
Attempting to start safenode10...
✓ Started safenode10 service
  - PID: 45313
  - Bin path: /var/safenode-manager/services/safenode10/safenode
  - Data path: /var/safenode-manager/services/safenode10
  - Logs path: /var/log/safenode/safenode10

So far so good!

EDIT: On second thought, I have many many Error counts. Logs have a lot of these errors:

[2024-04-25T11:00:01.898092Z ERROR sn_networking::event] IncomingConnectionError from local_addr:?"/ip4/", send_back_addr "/p2p/12D3KooWGCPLY9YEnYgSjE2WLQBVfzssAL4L6rkSB77HAbCDqfxE" on ConnectionId(1666) with error Transport(Other(Custom { kind: Other, error: Left(Left(Right(Select(Failed)))) }))
[2024-04-25T11:00:01.898155Z TRACE sn_networking::event] SwarmEvent handled in 64.611µs: "Incoming ConnErr"
[2024-04-25T11:00:01.986110Z TRACE sn_networking::event] ConnectionClosed: outgoing (/ip4/ peer_id=12D3KooWD6ScE1qX9qwAXNhNkCyDAHnT1CrgyWtshDUYXMWxDicx connection_id=ConnectionId(1547) cause=Some(IO(Custom { kind: Other, error: Custom { kind: Other, error: Connection(ConnectionError(ApplicationClosed(ApplicationClose { error_code: 0, reason: b"" }))) } })) num_established=0
[2024-04-25T11:00:01.986166Z TRACE sn_networking::event] SwarmEvent handled in 68.852µs: "ConnectionClosed"
[2024-04-25T11:00:02.324637Z TRACE sn_networking::event] ConnectionClosed: outgoing (/ip4/ peer_id=12D3KooWGwin8kGhgzJjY3dsY21mNRb4cGPvsC46STJAbDCFMWXo connection_id=ConnectionId(1545) cause=Some(IO(Custom { kind: Other, error: Custom { kind: Other, error: Connection(ConnectionError(ApplicationClosed(ApplicationClose { error_code: 0, reason: b"" }))) } })) num_established=0
[2024-04-25T11:00:02.324809Z TRACE sn_networking::event] SwarmEvent handled in 184.074µs: "ConnectionClosed"

nice this worked!


I think at this point, you could only edit the service definitions created by the node manager.

Edit: actually, shortly, I’ll just add the feature and do another alpha release.


Leading into Beta, I think safenode should be retired and safenode-manager be the only way to fire up nodes.


maybe node-manager? (or auto-nodes / autonomi without node in the name at all? autonomi --add-nodes 3 … autonomi files upload … autonomi balance …)

and how large is this network? :open_mouth: uploaded 380 chunks and my nodes didn’t earn a singled nano oO …

…also it seems to hang on very specific chunks (?) … is that just my experience? are there some nodes out there being very very slow in response (?) …


The network contains 2k nodes as usual. But if you tried to upload from the same network that you’re running your nodes from, there is a bug that prevents the client from hole punching into the same network. At least that is what we observed when we were testing it out.

1 Like

Is there a way to specify a directory which is used for storage?

1 Like

nodes running in the cloud - client running behind my router - so this shouldn’t be the issue here i think … strange …


nevermind - just earned some nanos - so it is indeed possible :slight_smile:



Running two nodes from home without port forwarding.
Both have puts and one has already earned.


Same issue here with specific chunks! I tried a few uploads that went fine and super fast, but two files got stuck on a specific chunk indefinitely (waited 10 min then abort). When retrying same upload there’s only one chunk to upload (thx deduplication :white_check_mark:) but it gets stuck systematically.

Oh and congrats team on the hole punching milestone!! I didn’t expect that! Node successfully started, can’t wait to see my first test nanos :smirk: No chunk received so far after >10 min but I’m patient!


Yeah, this will be the case, and we are actually working on several other UX improvements for the node manager to accompany it.


Renaming the binaries in line with the Autonomi branding is definitely on the cards, but I don’t know how soon. I’d guess we’ll just wait until we’ve settled on names for all of them and then do it at the same time, because it will be quite a big administration task in terms of getting all the release processes updated and so on.