This modifies the dcr_tmux_simnet_setup.sh script to set the root of all of the nodes to the environment variable DCR_SIMNET_ROOT when it is set and fallback to the existing path when it is not. It also updates contrib/README.md and docs/simnet_environment.mediawiki to document the new capability.
332 lines
14 KiB
Plaintext
332 lines
14 KiB
Plaintext
==1. Overview==
|
|
|
|
When developing Decred applications or testing potential changes, it is often
|
|
extremely useful to have a private test network where transactions are actually
|
|
mined into blocks, difficulty levels are low enough to generate blocks on
|
|
demand, it is possible to easily cause chain reorganizations for testing
|
|
purposes, and otherwise have full control over the network.
|
|
|
|
In order to facilitate these scenarios, <code>dcrd</code> provides a simulation
|
|
network (<code>--simnet</code>), where the difficulty starts extremely low to
|
|
enable fast CPU mining of blocks. Simnet also has some modified functionality
|
|
that helps developers avoid common issues early in development.
|
|
|
|
Other components in the Decred ecosystem, such as <code>dcrwallet</code> and
|
|
<code>dcrctl</code>, also support the simulation network to facilitate testing.
|
|
|
|
As simnet is a temporary network for private use, there are no public block
|
|
explorers or faucets available.
|
|
|
|
===1.1 Distinguishing Properties===
|
|
|
|
The following is an overview of the most important properties that distinguish
|
|
it from the main network:
|
|
|
|
* The difficulty starts extremely low to enable fast CPU mining of blocks
|
|
* Networking changes:
|
|
** All code related to peer discovery and IP address dissemination is disabled to help ensure the network remains private
|
|
** The peer and RPC network ports are different
|
|
** A unique network byte sequence is used in the peer-to-peer message protocol so the blocks can't accidentally be crossed with the main network
|
|
* All chain and payment address parameters are unique to prevent confusion with the main network:
|
|
** Different genesis block
|
|
** Payment addresses start with different prefixes:
|
|
*** Standard pay-to-pubkeyhash (P2PKH) starts with uppercase <code>S</code>
|
|
*** Standard pay-to-scripthash (P2SH) starts with lowercase <code>s</code>
|
|
** Exported hierarchical deterministic extended keys (BIP32) start with different prefixes:
|
|
*** Public extended keys start with <code>spub</code>
|
|
*** Private extended keys start with <code>sprv</code>
|
|
** The BIP44 coin type used in HD key paths is lowercase <code>s</code>
|
|
|
|
==2. Preconfigured Simnet Environment==
|
|
|
|
The easiest way to get started using the simulation network is to make use of
|
|
the preconfigured simnet environment setup shell script that is
|
|
[[../contrib/dcr_tmux_simnet_setup.sh|provided in the repository at contrib/dcr_tmux_simnet_setup.sh]].
|
|
|
|
This script makes use of [https://github.com/tmux/tmux tmux], which is
|
|
typically readily available on Unix and Linux platforms, to setup a
|
|
self-contained environment with several terminal-based windows and panes with
|
|
<code>dcrd</code> and <code>dcrwallet</code> already configured.
|
|
|
|
The environment will be housed in the <code>$HOME/dcrdsimnetnodes</code>
|
|
directory by default. This can be overridden with the
|
|
<code>DCR_SIMNET_ROOT</code> environment variable if desired.
|
|
|
|
===2.1 Preconfigured Environment Overview===
|
|
|
|
The following provides an overview of how the environment that is automatically
|
|
setup by the aforementioned script is configured:
|
|
|
|
* Multiple windows, each with two panes
|
|
** The upper pane is either a <code>dcrd</code> instance or a <code>dcrwallet</code> instance
|
|
** The lower pane provides a shell already in the directory associated with the process running in the upper pane
|
|
* Two <code>dcrd</code> instances running simnet (named <code>dcrd1</code> and <code>dcrd2</code>)
|
|
** The second connects to the first via a persistent/permanent connection
|
|
* Two <code>dcrwallet</code> instances also running simnet (named <code>wallet1</code> and <code>wallet2</code>)
|
|
** Both wallets are configured with the same seed
|
|
** The <code>wallet1</code> instance:
|
|
*** Connects to the <code>dcrd1</code> instance via JSON-RPC
|
|
*** Automatically purchases tickets via the integrated ticket buyer
|
|
*** Automatically votes
|
|
** The <code> wallet2</code> instance:
|
|
*** Connects to the <code>dcrd2</code> instance via JSON-RPC
|
|
*** Automatically votes
|
|
* Helper scripts accessible from the lower pane in each window that communicate with the associated process in the upper pane
|
|
* Scripts available in the directories of all instances:
|
|
** <code>ctl</code> - Invokes <code>dcrctl</code> communicating to the associated instance process
|
|
** <code>stopall</code> - Stops all of the processes and closes the <code>tmux</code> session
|
|
* Additional scripts for the <code>dcrd1</code> and <code>dcrd2</code> instances:
|
|
** <code>mine</code> - Mines a specified number of blocks with a delay between
|
|
* Additional scripts for the <code>dcrd2</code> instance:
|
|
** <code>reorg</code> - Forces a chain reorganization in the instance
|
|
* Additional scripts for the <code>wallet1</code> and <code>wallet2</code> instances:
|
|
** <code>tickets</code> - Manually purchases the specified number of tickets with a default of 1
|
|
** <code>xfer</code> - Creates a transaction that transfers (sends) funds to an address owned by the instance
|
|
|
|
===2.2. Using the Preconfigured Environment===
|
|
|
|
In order to get started, first ensure that the <code>dcrd</code>,
|
|
<code>dcrwallet</code>, and <code>dcrctl</code> binaries you want to test with
|
|
are available in your system path and that <code>tmux</code> is installed:
|
|
|
|
$ dcrd -V
|
|
dcrd version x.y.z (Go version <version> <os>)
|
|
$ dcrwallet -V
|
|
dcrwallet version x.y.z (Go version <version> <os>)
|
|
$ dcrctl -V
|
|
dcrctl version x.y.z (Go version <version> <os>)
|
|
$ tmux -V
|
|
tmux x.y.z
|
|
|
|
Once that above has been verified, make the script executable and run it:
|
|
|
|
$ chmod +x dcr_tmux_simnet_setup.sh
|
|
$ ./dcr_tmux_simnet_setup.sh
|
|
|
|
It will take a few seconds before the environment appears since it mines a bunch
|
|
of initial blocks so that the environment has spendable coins immediately
|
|
available.
|
|
|
|
Once the environment launches, you will be in the bottom pane of the
|
|
<code>dcrd1</code> window. As the overview section describes, this lower pane
|
|
provides convenience scripts for interacting with the <code>dcrd</code> instance
|
|
running in the upper pane.
|
|
|
|
At this point, everything is setup and ready to go. Since it is running in a
|
|
[https://github.com/tmux/tmux tmux] session, the various windows and panes can
|
|
be accessed with normal <code>tmux</code> command sequences. By default,
|
|
<code>Ctrl+B</code> followed by a window number will switch to that number. For
|
|
example <code>Ctrl+B 1</code> will switch the window with the
|
|
<code>dcrwallet1</code> instance and <code>Ctrl+B 0</code> will switch back to
|
|
the window with the <code>dcrd1</code> instance.
|
|
|
|
See the next sections for a quick tour of performing some basic tasks.
|
|
|
|
====2.2.1 Basic Tasks - Interfacing with the <code>dcrd1</code> instance====
|
|
|
|
Ensure the window that houses the <code>dcrd1</code> instance is active and the
|
|
lower pane has focus. This '''might''' require switching to the window with the
|
|
tmux command sequence <code>Ctrl+B 0</code> and <code>Ctrl+B <down arrow></code>
|
|
to switch to the pane.
|
|
|
|
* Query the current best block of the private network:
|
|
$ ./ctl getbestblock
|
|
{
|
|
"hash": "this will be different each time the environment is launched",
|
|
"height": 32
|
|
}
|
|
|
|
* To mine a couple of blocks:
|
|
$ ./mine 2
|
|
[
|
|
"block hash here"
|
|
]
|
|
[
|
|
"different block hash here"
|
|
]
|
|
|
|
====2.2.2 Basic Tasks - Interfacing with the <code>wallet1</code> instance====
|
|
|
|
Ensure the window that houses the <code>dcrwallet1</code> instance is active and
|
|
the lower pane has focus. This '''might''' require switching to the window with
|
|
the tmux command sequence <code>Ctrl+B 1</code> and
|
|
<code>Ctrl+B <down arrow></code> to switch to the pane.
|
|
|
|
* Querying the wallet balance:
|
|
$ ./ctl getbalance
|
|
{
|
|
...
|
|
"totalimmaturecoinbaserewards": 4800,
|
|
"totallockedbytickets": 0.0006894,
|
|
"totalspendable": 4800,
|
|
"cumulativetotal": 9899.9999675,
|
|
"totalunconfirmed": 299.9992781,
|
|
"totalvotingauthority": 0.0006
|
|
}
|
|
|
|
* Manually buying tickets:
|
|
$ ./tickets 3
|
|
[
|
|
"first ticket hash here",
|
|
"second ticket hash here",
|
|
"third ticket hash here"
|
|
]
|
|
|
|
====2.2.3 Basic Tasks - Forcing a reorg via the <code>dcrd2</code> instance====
|
|
|
|
Ensure the window that houses the <code>dcrd2</code> instance is active and the
|
|
lower pane has focus. This '''might''' require switching to the window with the
|
|
tmux command sequence <code>Ctrl+B 2</code> and <code>Ctrl+B <down arrow></code>
|
|
to switch to the pane.
|
|
|
|
Force the reorg using the <code>reorg</code> convenience script:
|
|
|
|
$ ./reorg
|
|
[
|
|
"block hash mined in dcrd1 instance"
|
|
]
|
|
[
|
|
"second block hash mined in dcrd1 instance"
|
|
]
|
|
[
|
|
"block hash mined in dcrd2 instance"
|
|
]
|
|
|
|
The log file of <code>dcrd</code> in the upper pane will show something similar
|
|
to:
|
|
|
|
[INF] CHAN: REORGANIZE: Chain forks at 012419307b328916facfce7120fdb526537b5f3faccd5039e1650deda87832fe (height 34)
|
|
[INF] CHAN: REORGANIZE: Old best chain tip was 0613b391b86d07a35c0c1ad09b2d14d0aaecc09e138b2646de4475996b9b24b7 (height 35)
|
|
[INF] CHAN: REORGANIZE: New best chain tip is 003af7ab2a8ec1708694ba96ad49038c3c20d5ac01da354125b67469d120f351 (height 36)
|
|
|
|
====2.2.4 Basic Tasks - Shutting down the environment====
|
|
|
|
From any instance command pane:
|
|
|
|
$ ./stopall
|
|
dcrd stopping.
|
|
dcrwallet stopping
|
|
dcrd stopping.
|
|
dcrwallet stopping
|
|
Seconds until shutdown: 3
|
|
...
|
|
|
|
<a name="CommonIssues" />
|
|
|
|
===2.3. Common Issues===
|
|
|
|
====2.3.1. Code changes don't seem to have any effect====
|
|
|
|
The script runs the binaries from the system path. Make sure you
|
|
<code>go install</code> the changed binaries so the updated binaries are the
|
|
ones that are being run.
|
|
|
|
====2.3.2. Tickets aren't being purchased====
|
|
|
|
This happens when too many blocks are mined too quickly and the wallet can't
|
|
keep up. The solution is to use the <code>./mine</code> script which adds a
|
|
delay between each block to give the wallet a chance to purchase and send the
|
|
tickets.
|
|
|
|
====2.3.3. Rejected ticket purchases with errors similar to <code>rejected transaction X: transaction X expired at height Y</code>====
|
|
|
|
This is caused by the same thing as the previous issue and has the same
|
|
solution.
|
|
|
|
====2.3.4. Errors similar to <code>list size too small: 0 < 5</code>====
|
|
|
|
This happens if you stop buying tickets and mine enough blocks to the point the
|
|
chain is unrecoverable due to the ticket pool becoming depleted. The solution
|
|
is to start over and ensure you are purchasing enough tickets. A new chain is
|
|
created every time the simnet environment setup script is run.
|
|
|
|
Note that this error is temporary and will be replaced with a
|
|
<code>chain continuity</code> error in the future.
|
|
|
|
====2.3.5. Errors similar to <code>chain continuity not guaranteed after height X</code>====
|
|
|
|
This happens if you stop buying tickets and mining the next block would cause
|
|
the chain to become unrecoverable if no tickets are included due to depletion of
|
|
the live ticket pool. The solution is to purchase enough tickets so the block
|
|
can be mined.
|
|
|
|
==3. Manual Configuration==
|
|
|
|
'''<p>
|
|
It is _HIGHLY_ recommended to use the previously described preconfigured simnet
|
|
environment instead of manually configuring things. Not only does it greatly
|
|
simplify things, it also provides a much more sophisticated setup than the
|
|
basic one described here.
|
|
</p>'''
|
|
|
|
Running a single <code>dcrd</code> node on simnet is simply starting
|
|
<code>dcrd</code> with the <code>--simnet</code> flag. However, in order to be
|
|
really useful, you'll typically want to be able to send coins amongst addresses
|
|
which implies that blocks will need to be mined and interfacing with a wallet
|
|
will be needed.
|
|
|
|
In addition, since there are effectively no coins yet on the new private
|
|
network, an initial series of blocks will need to be mined which pay to an
|
|
address you own so there are usable coins to spend.
|
|
|
|
As previously mentioned, simnet uses unique addresses to prevent confusion with
|
|
the main network. Thus, it means that a wallet which supports the address
|
|
format must be used. For this, <code>dcrwallet</code> with the
|
|
<code>--simnet</code> flag can be used.
|
|
|
|
The following is a command reference to get going:
|
|
|
|
'''<p>
|
|
NOTE: All of these commands can be simplified by creating config files and
|
|
making use of them, however the commands here use all switches on the
|
|
command line to show exactly what is needed for each.
|
|
</p>'''
|
|
|
|
* Create a new simnet wallet (this will be called the first window):
|
|
$ dcrwallet --simnet --create
|
|
Enter the private passphrase for your new wallet:
|
|
Confirm passphrase:
|
|
Do you want to add an additional layer of encryption for public data? (n/no/y/yes) [no]:
|
|
Do you have an existing wallet seed you want to use? (n/no/y/yes) [no]:
|
|
Your wallet generation seed is:
|
|
<seed here>
|
|
Hex: <seed in hex here>
|
|
...
|
|
Once you have stored the seed in a safe and secure location, enter "OK" to continue: OK
|
|
Creating the wallet...
|
|
Mining address: S<rest of address here> <---- Note this address
|
|
The wallet has been created successfully.
|
|
|
|
* In a second window, start dcrd on simnet paying to the mining address from above:
|
|
$ dcrd --simnet --rpcuser=someuser --rpcpass=somepass --miningaddr=S<rest of address from above here>
|
|
|
|
* In a third window, instruct dcrd to generate enough initial blocks for the first coinbase to mature and to have enough funds for purchasing tickets:
|
|
$ dcrctl --simnet --rpcuser=someuser --rpcpass=somepass generate 32
|
|
|
|
* Back in the first window, start dcrwallet on simnet:
|
|
'''<p>
|
|
NOTE: It is important to perform this step AFTER the blocks have been mined
|
|
above or the wallet will believe it's on an old coin type and will not see the
|
|
balance properly.
|
|
</p>'''
|
|
|
|
$ dcrwallet --simnet --username=someuser --password=somepass
|
|
...
|
|
*** ATTENTION ***
|
|
Since this is your first time running we need to sync accounts. Please enter
|
|
the private wallet passphrase. This will complete syncing of the wallet
|
|
accounts and then leave your wallet unlocked. You may relock wallet after by
|
|
calling 'walletlock' through the RPC.
|
|
*****************
|
|
Enter private passphrase:
|
|
...
|
|
[INF] SYNC: Blockchain sync completed, wallet ready for general usage.
|
|
|
|
* Back in the third window, check the wallet balance to ensure spendable coins are available:
|
|
$ dcrctl --simnet --wallet --rpcuser=someuser --rpcpass=somepass getbalance
|
|
|
|
At this point, there is a fully functional private simnet with coins available
|
|
to send to other simnet addresses. Any time one or more transactions are sent,
|
|
a <code>generate 1</code> RPC must be issued to mine a new block with the
|
|
transactions included.
|