Start TNT with python test_net.py
or, on Linux and Mac, simply ./test_net.py
.
When you first start TNT it automatically calls the init
command and the info
command.
Then, TNT prints a list of available commands, and continues to accept and run commands until a blank line is entered at the top level, which exits TNT. Commands which accept additional input will usually be canceled if a blank line is entered, but that doesn't exit TNT -- just the command. If an unrecognized command is entered, the initial list of commands is displayed again.
There are currently 2 kinds of commands in TNT: SelectCommands and regular Commands.
A SelectCommand operates on one or more of the configured INSTANCES
, as specified by the user.
If a SelectCommand is called with no additional input (e.g. start
), it will prompt for which instances to operate on:
it lists the available instances by name, and you can specify one or more of those (space-delimited),
or all
to operate on all of them.
If one or only a few instances are specified when a SelectCommand prompts, it will run for the instances
specified and then prompt again; a blank line will cancel additional runs of the SelectCommand.
If all
is specified, or if all instances are manually specified, a SelectCommand will not prompt for additional
instances once it completes.
Once you get comfortable using TNT and are familiar with which commands are SelectCommands, you can specify
instances inline with the command to avoid multiple prompts (e.g. start node-0
).
SelectCommands sort the instance names provided to it before running, so if all
is specified, for example,
node-0
will be run first, followed by node-1
, then node-2
, etc.
Regular Commands are less common in TNT; they generally do not operate on the INSTANCES, or, if they do, they always operate on all of them.
Implemented in init.py
init
is a regular Command that prompts you for the information needed to set up the instances that will be used to run TNT.
It fills in the INSTANCES
global state (held in tnt_config.py
) which is how TNT talks to the instances
it uses for running nodes.
Then, once INSTANCES is configured, it "starts" the instances -- calls into the instance platform to ensure that each instance is running so that TNT can interact with it later on.
init
automatically generates local names for the instances. It names the first one node-0
, the next one node-1
,
then node-2
, etc.
WARNING: The name generator currently does not gracefully handle taking down a single node and bringing it back up.
There are notes/TODOs about this in init.py
.
init
has 2 modes:
In this mode, you will be prompted for:
- whether you want this run to use cloud instances or local ones
- currently cloud/local cannot be used together, but they may be made compatible in the future
- these options are currently hardcoded; it may be useful to pull them out into a configuration
- how many of those instances you want to use for this run
- it combines the configured instance lists of the specified platform group (from
tnt_config
), then "checks out" (removes) the specified number of nodes from the combined list. This usually results in the platforms being used serially rather than mixed (i.e. all of the Google instances will be used before any of the Amazon ones, etc). In the future, we may find it useful to change the implementation to choose more randomly.
- it combines the configured instance lists of the specified platform group (from
In this mode, you will be prompted repeatedly (until a blank line is entered) for:
- what platform you want this instance to use - current options are:
google
,amazon
,local
- these options are currently hardcoded; it may be useful to pull them out into a configuration
In manual mode, the first instance in the specified platform list is used. In the future, we should prompt for which instance to use by name to allow for better coordination between concurrent TNT users.
Implemented in info.py
info
is a regular Command that waits for each instance (in INSTANCES
) to report its ip address, then prints it out.
WARNING: It does not currently check whether the instance is running before waiting (forever) for the ip address.
There is a note about this in info.py
and it should probably be corrected.
Implemented in update.py
update
is a SelectCommand that uploads new binaries for MASQNode
and dns_utility
to the instance(s) specified.
It currently looks for the binaries in the same directory as the TNT, and be warned: it is not graceful when they are not found.
It will crash if the binaries are not found.
Implemented in start.py
start
is a SelectCommand that starts MASQNode on the instance(s) you specify.
The node-0
node must always be started first.
If you try to start any other node before node-0
, start
will complain.
start
will also complain if you try to start node-0
more than once.
However, it does not prevent you from starting any other node more than once.
If nodes are started in an acceptable order, the start
command will call the relevant instance.py
function: start_node
(sending in the node-0
node descriptor).
The first thing start
does is remove any existing MASQNode.log
file.
This is to ensure that the log will only contain the current node descriptor.
Once the previous log is removed, MASQNode is started with the following parameters:
--dns-servers 1.1.1.1
--log-level trace
--data-directory /tmp
--ip <ip addr of the instance>
--earning-wallet <fake address calculated from ip address>
--neighbors <neighbor descriptor>
Once MASQNode is started, start
waits for the node descriptor to appear in the logs before completing.
This is particularly important for the node-0
node, since all the other nodes will require its descriptor to start.
Implemented in daisy.py
daisy
is an InputCommand that starts the specified number of initialized nodes in sequence, one after another.
It begins with the first node and each new node will use the previous node descriptor for its --neighbors
parameter.
B-1-2-3-4-5-6
Implemented in cluster.py
cluster
is an InputCommand that starts the specified number of initialized nodes in a cluster around an already
started node. If no node is started it will start the first node and cluster around it. Run this command multiple
times to create multiple clusters, it will start the next cluster from the last node that was started.
For example: With docker initialize 7 nodes. cluster 3
starts the first node and three nodes clustered around
it. Running cluster 3
a second time with start 3 more nodes clustered around node-3.
2
|
B-1
|
6-3-4
|
5
Implemented in instance.py
Linux-only
tail
is a SelectCommand that calls tail -f
the MASQNode.log
of the instance(s) specified in a new terminal window (per specified instance).
Implemented in instance.py
subvert
is a SelectCommand that subverts the DNS of the instance(s) specified.
This means that any traffic originating from the instance(s) will be routed through the MASQ Network;
it is equivalent to the consuming
state in the GUI.
Implemented in instance.py
curl
is a SelectCommand that generates some internet traffic on the instance(s) specified.
It prompts for how many times you want to run curl
on each instance;
each curl
retrieves https://www.piday.org/million/
.
The website used for curl is hardcoded in instance.py
.
It might be useful to pull this out into a configuration, or prompt the user for the website they wish to curl.
Implemented in instance.py
wget
is a SelectCommand that generates some internet traffic on the instance(s) specified.
It starts wget
on each instance, retrieving each of the following websites:
- nyan.cat
- substratum.net
- amplifyexchange.com
- google.com
- youtube.com
- wikipedia.org
- reddit.com
- yahoo.com
- amazon.com
These websites are currently hardcoded in instance.py
.
It might be useful to pull these out into a configuration.
Implemented in instance.py
verify
is a SelectCommand that displays the current status of any pending wget
and/or curl
commands running
on the instance specified. Perhaps they have not started yet; perhaps they have started but not finished; perhaps
they have failed; or perhaps they have produced the expected output. Perhaps several different pending commands are
in different statuses.
Implemented in instance.py
revert
is a SelectCommand that reverts the DNS of the instance(s) specified.
This means that any traffic originating from the instance(s) will no longer be routed through the SubstratumNetwork;
it is equivalent to the earning
state in the GUI.
Implemented in instance.py
inspect
is a SelectCommand that retrieves the current state of the Neighborhood of the instance(s) specified,
and opens a visual graph of the Neighborhood in an image viewer.
It detects how many changes have happened in the Neighborhood by inspecting the MASQNode.log
file of the instance,
and prompts you for which version you would like to see (until a blank line is entered).
Implemented in instance.py
inbound
is a SelectCommand that retrieves the Neighborhood Gossip messages that the specified instance(s) has received,
and opens a visual graph of the Gossip in an image viewer.
It detects how many messages have been received by inspecting the MASQNode.log
file of the instance,
and prompts you for which one you would like to see (until a blank line is entered).
Implemented in instance.py
outbound
is a SelectCommand that retrieves the Neighborhood Gossip messages that the specified instance(s) has sent,
and opens a visual graph of the Gossip in an image viewer.
It detects how many messages have been sent by inspecting the MASQNode.log
file of the instance,
and prompts you for which one you would like to see (until a blank line is entered).
Implemented in instance.py
stop
is a SelectCommand that shuts down MASQNode on the instance(s) specified.
For each instance specified, It will:
- revert DNS
- kill the MASQNode process
- kill any traffic (
wget
orcurl
) that was being generated - clear out any stale state (e.g. node descriptor) in the TNT instance
Implemented in finish.py
finish
is a regular Command that downloads the MASQNode.log
for all instances into a local directory and calls stop
on each instance.
It prompts for a directory name to put the logs into; it will accept a name that contains no spaces and does not already exist.
If it receives invalid input, it will reprompt; a blank line will cancel the command.
unix-only
shell
is a SelectCommand that will open a shell into the instance(s) specified in a new terminal window (per specified instance)
Implemented in kill.py
kill
is a SelectCommand that shuts down the instance(s) specified -- not just MASQNode, but the whole instance.
The instances that are shut down are removed from the INSTANCES structure and put back into their corresponding "available instances" list based on their platform.
Implemented in nfo.py
nfo
is a SelectCommand that calls kill
and then restarts the instance(s) specified.
It can be useful as a last resort if your instances are behaving a little strangely.
It's like toggling the power switch of the machine off and back on.
Nuke From Orbit -- it's the only way to be sure...