==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": 80,
    "totallockedbytickets": 0.004596,
    "totalspendable": 75,
    "cumulativetotal": 164.9998846,
    "totalunconfirmed": 9.9952886,
    "totalvotingauthority": 0.004
  }

* 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>extending block X (height Y) would result in an unrecoverable chain due to ticket exhaustion</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.
