-
Notifications
You must be signed in to change notification settings - Fork 12
Building Running and Testing a Wallet Node
This guide assumes that you have clones of the cardano-sl
and cardano-wallet
repositories within a common parent directory:
$ git clone https://github.com/input-output-hk/cardano-sl
$ git clone https://github.com/input-output-hk/cardano-wallet
$ cd cardano-sl
# Linux:
$ stack build cardano-sl-tools
# macOS:
$ stack build cardano-sl-tools --ghc-options=-optl-Wl,-dead_strip_dylibs
mkdir -p ../cardano-wallet/state-staging/tls/{client,server}
stack exec cardano-x509-certificates -- \
--server-out-dir ../cardano-wallet/state-staging/tls/server \
--clients-out-dir ../cardano-wallet/state-staging/tls/client \
-k default -c lib/configuration.yaml
cd ../cardano-wallet
# Linux:
$ stack build cardano-wallet:cardano-wallet-server
# macOS:
$ stack build cardano-wallet:cardano-wallet-server --ghc-options=-optl-Wl,-dead_strip_dylibs
This step can take some time, especially if you've never built the wallet before.
If the above steps completed successfully, we should now be ready to run a node!
Issue the following command (from within the cardano-wallet
directory):
stack exec -- cardano-wallet-server \
--configuration-key mainnet_dryrun_full \
--configuration-file ../cardano-sl/lib/configuration.yaml \
--db-path ./state-staging/db \
--wallet-db-path ./state-staging/wallet-db \
--tls-ca-cert ./state-staging/tls/server/ca.crt \
--tls-node-client-cert ./state-staging/tls/client/client.crt \
--tls-node-client-key ./state-staging/tls/client/client.key \
--tls-wallet-server-cert ./state-staging/tls/server/server.crt \
--tls-wallet-server-key ./state-staging/tls/server/server.key \
--topology ./topology-examples/testnet.yaml \
--system-start $(($(date +%s) +10)) \
--node-id wallet-node \
--node-api-address 127.0.0.1:8080 \
--wallet-api-address 127.0.0.1:8090 \
--wallet-doc-address 127.0.0.1:8100 \
--rebuild-db \
--wallet-rebuild-db
Notes:
-
When running for the first time, we ask the server to build both the node and wallet databases (with the
--rebuild-db
and--wallet-rebuild-db
options respectively). These options can be omitted on further runs, in which case the existing databases will be reused. -
With the above command, the node API, wallet API and wallet documentation servers will listen on
localhost
(127.0.0.1
) only. If instead you want to connect from another machine, change127.0.0.1
to0.0.0.0
. -
In the above example, we connect to the staging main net (
configuration-key
is set tomainnet_dryrun_full
) -
The
--db-path
and--wallet-db-path
options can actually point to any directory of choice. By specifying them, we have required that both node and wallet DBs will use persistent storage.
If all is well, we should now be able to query the wallet API:
$ curl https://127.0.0.1:8090/api/v1/wallets --cert ./state-staging/tls/edge/client.pem --cacert ./state-staging/tls/edge/ca.crt
Mnemonics (needed for example when creating wallet) can be generated using :
$ cd cardano-sl
# Linux:
$ stack build cardano-sl-tools
# macOS:
$ stack build cardano-sl-tools --ghc-options=-optl-Wl,-dead_strip_dylibs
$ stack exec cardano-generate-mnemonic
Starting wallet and node attached to mainnet can be realized by calling :
$ cd cardano-wallet
$ stack exec -- cardano-wallet-server \
--configuration-file ../cardano-sl/lib/configuration.yaml \
--configuration-key mainnet_dryrun_full \
--db-path ../state-mainnet/db \
--node-id wallet-node \
--node-tls-ca-cert ./state-staging/tls/edge/ca.crt \
--node-tls-client-cert ./state-staging/tls/edge/server.crt \
--node-tls-key ./state-staging/tls/edge/server.key \
--system-start $(($(date +%s) +10)) \
--topology ./topology-examples/testnet.yaml \
--wallet-address 127.0.0.1:8090 \
--wallet-db-path ../state-mainnet/wallet-db \
--wallet-node-api-address 127.0.0.1:8080 \
--tlsca ./state-staging/tls/edge/ca.crt \
--tlskey ./state-staging/tls/edge/server.key \
--tlscert ./state-staging/tls/edge/server.crt \
--rebuild-db \
--wallet-rebuild-db
Both node and wallet dbs are empty and the node starts from scratch to sync with mainnet (see Fig 1).
Fig. 1. The situation when the new node and wallet start from scratch
The node starts to build its database (persisted in directory indicated in --db-path
and denoted here with cylinder symbol with block header range that represent the blocks consumed), wallet persists in directory pinpointed by --wallet-db-path
and presented like for the node - although wallet does not store blocks but its state with sql db and respective checkpoints). In push mechanism, the node holds responsibility for block syncing to a wallet. The wallet subscribes for block syncing to the node. Hence, when the node downloads the batch of blocks the same batch is pushed to the wallet (Fig. 2).
Fig. 2. The first batch of blocks accommodated by the node and pushed to the wallet
When the wallet-node pair is stopped and then restarted (notice the absence of --rebuild-db
and --wallet-rebuild-db
flags):
$ cd cardano-wallet
$ stack exec -- cardano-wallet-server \
--configuration-file ../cardano-sl/lib/configuration.yaml \
--configuration-key mainnet_dryrun_full \
--db-path ../state-mainnet/db \
--node-id wallet-node \
--node-tls-ca-cert ./state-staging/tls/edge/ca.crt \
--node-tls-client-cert ./state-staging/tls/edge/server.crt \
--node-tls-key ./state-staging/tls/edge/server.key \
--system-start $(($(date +%s) +10)) \
--topology ./topology-examples/testnet.yaml \
--wallet-address 127.0.0.1:8090 \
--wallet-db-path ../state-mainnet/wallet-db \
--wallet-node-api-address 127.0.0.1:8080 \
--tlsca ./state-staging/tls/edge/ca.crt \
--tlskey ./state-staging/tls/edge/server.key \
--tlscert ./state-staging/tls/edge/server.crt
the node resumes downloading blocks from what it has in db. The Fig. 3 shows restarting result at time t2. db
before restart had h1-h5
state (the wallet likewise) and restarted on top of that, ie., downloading the block with h6
header and as a consequence persisting h1-h6
state. The h6
block was also pushed to the wallet.
Fig. 3. The restart of the node without databases rebuilding
The node db persistence is closely connected with block listener capability and how push mechanism works. If we stop wallet-node pair and replace the node db with h1-h5
db with wallet db intact and restart wallet-node the node will resume operation as before. It will accomodate h6
block, persist h1-h6
state and push h6
block once again to the wallet. If the wallet is idempotent to apply blocks then this is ok, although superfluous.
The another behavior takes place when the contrary happens. The node has h1-h6
state persisted and the wallet has, for example, h1-h3
state persisted - and the wallet-node pair is restarted (Fig. 4).
Fig. 4. The states of the node and wallet before restart with backfilling
In that case the node retrieves h6
block and pushes it to the block listener (ie., the wallet). The wallet tries to accommodate the block but detects discontinuity when looking at its persisted state (as the wallet does not persists the blocks, but checkpoints and metadata one has to make sure h1-h3
refers to other checkpoint than the checkpoint of h1-h5
to make it happen). The wallet starts-up backfilling which downloads backward blocks needed to recreate missing checkpoints (the one it would have when it was synchronized with the node persisted state), then resolves h6
block and continue operation.
Fig. 5. Restart with backfilling