testnet-laconicd-stack/testnet-nitro-node.md

947 lines
30 KiB
Markdown

# testnet-nitro-node
## Prerequisites
* Local:
* Clone the `cerc-io/testnet-ops` repository:
```bash
git clone git@git.vdb.to:cerc-io/testnet-ops.git
```
* Ansible: see [installation](https://git.vdb.to/cerc-io/testnet-ops#installation)
* On deployment machine:
* User with passwordless sudo: see [setup](https://git.vdb.to/cerc-io/testnet-ops/src/branch/main/user-setup/README.md#user-setup)
* laconic-so: see [installation](https://git.vdb.to/cerc-io/testnet-ops/src/branch/main/stack-orchestrator-setup/README.md#setup-stack-orchestrator)
## Setup
* Move to `nitro-nodes-setup` :
```bash
cd testnet-ops/nitro-nodes-setup
```
* Fetch the required Nitro node config:
```bash
wget -O nitro-vars.yml https://git.vdb.to/cerc-io/testnet-laconicd-stack/raw/branch/main/ops/stage2/nitro-node-config.yml
```
* Fetch required asset addresses:
```bash
wget -O assets.json https://git.vdb.to/cerc-io/testnet-laconicd-stack/raw/branch/main/ops/stage2/assets.json
```
* Ask testnet operator to send L1 tokens and ETH to your chain address
* [README for transferring tokens](./ops/nitro-token-ops.md#transfer-deployed-tokens-to-given-address)
* [README for transferring ETH](./ops/nitro-token-ops.md#transfer-eth)
* Check balance of your tokens once they are transferred:
```bash
# Note: Account address should be with "0x"
export ACCOUNT_ADDRESS="<account-address>"
export GETH_CHAIN_ID="1212"
export GETH_CHAIN_URL="https://fixturenet-eth.laconic.com"
export ASSET_ADDRESS_1=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken.address' assets.json)
export ASSET_ADDRESS_2=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken2.address' assets.json)
# Check balance of eth account
curl -X POST $GETH_CHAIN_URL \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"method":"eth_getBalance",
"params":["'"$ACCOUNT_ADDRESS"'", "latest"],
"id":1
}'
# Check balance of first asset address
curl -X POST $GETH_CHAIN_URL \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"method":"eth_call",
"params":[{
"to": "'"$ASSET_ADDRESS_1"'",
"data": "0x70a08231000000000000000000000000'"$ACCOUNT_ADDRESS"'"
}, "latest"],
"id":1
}'
# Check balance of second asset address
curl -X POST $GETH_CHAIN_URL \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"method":"eth_call",
"params":[{
"to": "'"$ASSET_ADDRESS_2"'",
"data": "0x70a08231000000000000000000000000'"$ACCOUNT_ADDRESS"'"
}, "latest"],
"id":1
}'
```
* Edit `nitro-vars.yml` and add the following variables:
```bash
# Private key for your Nitro account (same as the one used in stage0 onboarding)
# Export the key from Laconic wallet (https://wallet.laconic.com)
nitro_sc_pk: ""
# Private key for a funded account on L1
# This account should have L1 tokens for funding your Nitro channels
nitro_chain_pk: ""
# Multiaddr with publically accessible IP address / DNS for your L1 nitro node
# Use port 3007
# Example: "/ip4/192.168.x.y/tcp/3007"
# Example: "/dns4/example.com/tcp/3007"
nitro_l1_ext_multiaddr: ""
# Multiaddr with publically accessible IP address / DNS for your L2 nitro node
# Use port 3009
# Example: "/ip4/192.168.x.y/tcp/3009"
# Example: "/dns4/example.com/tcp/3009"
nitro_l2_ext_multiaddr: ""
```
* Edit the `setup-vars.yml` to update the target directory:
```bash
# Set absolute path to desired deployments directory (under your user)
# Example: /home/dev/nitro-node-deployments
...
nitro_directory: <path-to-deployments-dir>
...
# Will create deployments at <path-to-deployments-dir>/l1-nitro-deployment and <path-to-deployments-dir>/l2-nitro-deployment
```
## Run Nitro Nodes
**NOTE**: When following this setup, Nitro nodes from two parties won't be able to communicate with each other if they are on the same network
Nitro nodes can be set up on a target machine using Ansible:
* In `testnet-ops/nitro-nodes-setup`, create a new `hosts.ini` file:
```bash
cp ../hosts.example.ini hosts.ini
```
* Edit the [`hosts.ini`](./hosts.ini) file to run the playbook on a remote machine:
```ini
[<deployment_host>]
<host_name> ansible_host=<target_ip> ansible_user=<ssh_user> ansible_ssh_common_args='-o ForwardAgent=yes'
```
* Replace `<deployment_host>` with `nitro_host`
* Replace `<host_name>` with the alias of your choice
* Replace `<target_ip>` with the IP address or hostname of the target machine
* Replace `<ssh_user>` with the username of the user that you set up on target machine (e.g. dev, ubuntu)
* Verify that you are able to connect to the host using the following command
```bash
ansible all -m ping -i hosts.ini
# If using password based authentication, enter the ssh password on prompt; otherwise, leave it blank
# Expected output:
# <host_name> | SUCCESS => {
# "ansible_facts": {
# "discovered_interpreter_python": "/usr/bin/python3.10"
# },
# "changed": false,
# "ping": "pong"
# }
```
* Execute the `run-nitro-nodes.yml` Ansible playbook to setup and run a Nitro node (L1+L2):
```bash
LANG=en_US.utf8 ansible-playbook -i hosts.ini run-nitro-nodes.yml --extra-vars='{ "target_host": "nitro_host"}' --user $USER
```
### Check Deployment Status
* Run the following commands on deployment machine:
```bash
cd <path-to-deployments-dir>
# Check the logs, ensure that the nodes are running
laconic-so deployment --dir l1-nitro-deployment logs nitro-node -f
laconic-so deployment --dir l2-nitro-deployment logs nitro-node -f
# Let L1 node sync up with the chain
# Expected logs after sync:
# nitro-node-1 | 2:04PM INF Initializing Http RPC transport...
# nitro-node-1 | 2:04PM INF Completed RPC server initialization url=127.0.0.1:4005/api/v1
```
* Get your Nitro node's info:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-node-info -p 4005 -h nitro-node"
# Expected output:
# {
# "SCAddress": "0xd0eA8b27591b1D070cCcD4D30b8D408fe794FDfc",
# "MessageServicePeerId": "16Uiu2HAmSHRjoxveaPmJipzmdq69U8zme8BMnFjSBPferj1E5XAd"
# }
# SCAddress -> nitro address, MessageServicePeerId -> libp2p peer id
```
## Create Channels
Create a ledger channel with the bridge on L1 which is mirrored on L2
* Run the following commands on deployment machine
* Set required variables:
```bash
cd <path-to-deployments-dir>
export BRIDGE_NITRO_ADDRESS=$(yq eval '.bridge_nitro_address' nitro-node-config.yml)
export GETH_CHAIN_ID="1212"
# Get asset addresses from assets.json file
export ASSET_ADDRESS_1=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken.address' assets.json)
export ASSET_ADDRESS_2=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken2.address' assets.json)
```
* Check that you have no existing channels on L1 or L2:
```bash
laconic-so deployment --dir l1-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node"
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node"
# Expected output:
# []
```
* Ensure that your account has enough balance of tokens from `assets.json`
* Create a ledger channel between your L1 Nitro node and Bridge with custom asset:
```bash
laconic-so deployment --dir l1-nitro-deployment exec nitro-rpc-client "nitro-rpc-client direct-fund $BRIDGE_NITRO_ADDRESS --asset "$ASSET_ADDRESS_1:1000,1000" --asset "$ASSET_ADDRESS_2:1000,1000" -p 4005 -h nitro-node"
# Follow your L1 Nitro node logs for progress
# Expected Output:
# Objective started DirectFunding-0x161d289a50222caa781db215bb82a3ede4f557217742245525b8e8cbff04ec21
# Channel Open 0x161d289a50222caa781db215bb82a3ede4f557217742245525b8e8cbff04ec21
# Set the resulting ledger channel id in a variable
export LEDGER_CHANNEL_ID=
```
* Check the [Troubleshooting](#troubleshooting) section if command to create a ledger channel fails or gets stuck
* Once direct-fund objective is complete, the bridge will create a mirrored channel on L2
* Check L2 Nitro node's logs to see that a bridged-fund objective completed:
```bash
laconic-so deployment --dir l2-nitro-deployment logs nitro-node -f --tail 30
# Expected Output:
# nitro-node-1 | 5:01AM INF INFO Objective cranked address=0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce objective-id=bridgedfunding-0x6a9f5ccf1fa802525d794f4a899897f947615f6acc7141e61e056a8bfca29179 waiting-for=WaitingForNothing
# nitro-node-1 | 5:01AM INF INFO Objective is complete & returned to API address=0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce objective-id=bridgedfunding-0x6a9f5ccf1fa802525d794f4a899897f947615f6acc7141e61e056a8bfca29179
```
* Check status of L1 ledger channel with the bridge using channel id:
```bash
laconic-so deployment --dir l1-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-ledger-channel $LEDGER_CHANNEL_ID -p 4005 -h nitro-node"
# Example output:
# {
# ID: '0xbb28acc2e1543f4b41eb1ab9eb2e354b18554aefe4e7f0fa5f20046869d8553f',
# Status: 'Open',
# Balances: [
# {
# AssetAddress: '0xa6b4b8b84576047a53255649b4994743d9c83a71',
# Me: '0xdaaa6ef3bc03f9c7dabc9a02847387d2c19107f5',
# Them: '0xf0e6a85c6d23aca9ff1b83477d426ed26f218185',
# MyBalance: 1000n,
# TheirBalance: 1000n
# },
# {
# AssetAddress: '0x0000000000000000000000000000000000000000',
# Me: '0xdaaa6ef3bc03f9c7dabc9a02847387d2c19107f5',
# Them: '0xf0e6a85c6d23aca9ff1b83477d426ed26f218185',
# MyBalance: 1000n,
# TheirBalance: 1000n
# }
# ],
# ChannelMode: 'Open'
# }
```
* Check status of the mirrored channel on L2:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node"
# Example output:
# [
# {
# "ID": "0xb34210b763d4fdd534190ba11886ad1daa1e411c87be6fd20cff74cd25077c46",
# "Status": "Open",
# "Balances": [
# {
# "AssetAddress": "0xa4351114dae1abeb2d552d441c9733c72682a45d",
# "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05",
# "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185",
# "MyBalance": 1000,
# "TheirBalance": 1000
# },
# {
# "AssetAddress": "0x314e43f9825b10961859c2a62c2de6a765c1c1f1",
# "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05",
# "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185",
# "MyBalance": 1000,
# "TheirBalance": 1000
# }
# ],
# "ChannelMode": "Open"
# }
# ]
```
## Payments On L2 Channel
Perform payments using a virtual payment channel created with another Nitro node over the mirrored L2 channel with bridge as an intermediary
* Prerequisite: Ledger channel is required to create a payment channel
* Note: Currently payment channel is created from first asset present in ledger channel
* Run the following commands on deployment machine
* Switch to the `nitro-node` directory:
```bash
cd <path-to-deployments-dir>
```
* Check status of the mirrored channel on L2:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node"
# Example output:
# [
# {
# "ID": "0xb34210b763d4fdd534190ba11886ad1daa1e411c87be6fd20cff74cd25077c46",
# "Status": "Open",
# "Balances": [
# {
# "AssetAddress": "0xa4351114dae1abeb2d552d441c9733c72682a45d",
# "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05",
# "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185",
# "MyBalance": 1000,
# "TheirBalance": 1000
# },
# {
# "AssetAddress": "0x314e43f9825b10961859c2a62c2de6a765c1c1f1",
# "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05",
# "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185",
# "MyBalance": 1000,
# "TheirBalance": 1000
# }
# ],
# "ChannelMode": "Open"
# }
# ]
```
* Set required variables:
```bash
export BRIDGE_NITRO_ADDRESS=$(yq eval '.bridge_nitro_address' nitro-node-config.yml)
# Mirrored channel on L2
export L2_CHANNEL_ID=<l2-channel-id>
# Amount to create the payment channel with
export PAYMENT_CHANNEL_AMOUNT=500
```
* Set counterparty address
```bash
export COUNTER_PARTY_ADDRESS=<counterparty-nitro-address>
```
* Get the nitro address of the counterparty's node with whom you want create payment channel
* To get the nitro address of the your node:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-node-info -p 4005 -h nitro-node"
# `SCAddress` -> nitro address
```
* Check for existing payment channels for the L2 channel:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-payment-channels-by-ledger $L2_CHANNEL_ID -p 4005 -h nitro-node"
```
* Create a virtual payment channel:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client virtual-fund $COUNTER_PARTY_ADDRESS $BRIDGE_NITRO_ADDRESS --amount $PAYMENT_CHANNEL_AMOUNT -p 4005 -h nitro-node"
# Follow your L2 Nitro node logs for progress
# Expected Output:
# Objective started VirtualFund-0x43db45a101658387263b36d613322cc952d8ce5b70de51e3a495513c256bef4d
# Channel Open 0x43db45a101658387263b36d613322cc952d8ce5b70de51e3a495513c256bef4d
# Set the resulting payment channel id in a variable
PAYMENT_CHANNEL_ID=<payment-channel-id>
```
Multiple virtual payment channels can be created at once
* Check the payment channel's status:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-payment-channel $PAYMENT_CHANNEL_ID -p 4005 -h nitro-node"
# Expected output:
# {
# ID: '0xb29aeb32c9495a793ebf7bd116232075d1e7bfe89fc82281c7d498e3ffd3e3bf',
# Status: 'Open',
# Balance: {
# AssetAddress: '0x0000000000000000000000000000000000000000',
# Payee: '<your-nitro-address>',
# Payer: '<counterparty-nitro-address>',
# PaidSoFar: 0n,
# RemainingFunds: <payment-channel-amount>n
# }
# }
```
* Send payments using the virtual payment channel:
```bash
export PAY_AMOUNT=200
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client pay $PAYMENT_CHANNEL_ID $PAY_AMOUNT -p 4005 -h nitro-node"
# Expected output
# {
# Amount: <pay-amount>,
# Channel: '<payment-channel-id>'
# }
# This can be done multiple times until the payment channel balance is exhausted
```
* Check payment channel's status again to view updated channel state
* Close the payment channel to settle on the L2 mirrored channel:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client virtual-defund $PAYMENT_CHANNEL_ID -p 4005 -h nitro-node"
# Expected output:
# Objective started VirtualDefund-0x43db45a101658387263b36d613322cc952d8ce5b70de51e3a495513c256bef4d
# Channel complete 0x43db45a101658387263b36d613322cc952d8ce5b70de51e3a495513c256bef4d
```
* Check L2 mirrored channel's status after the virtual payment channel is closed:
* This can be checked by both nodes
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node"
# Example output:
# [
# {
# "ID": "0xb34210b763d4fdd534190ba11886ad1daa1e411c87be6fd20cff74cd25077c46",
# "Status": "Open",
# "Balances": [
# {
# "AssetAddress": "0xa4351114dae1abeb2d552d441c9733c72682a45d",
# "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05",
# "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185",
# "MyBalance": <updated balance>,
# "TheirBalance": <updated balance>
# },
# {
# "AssetAddress": "0x314e43f9825b10961859c2a62c2de6a765c1c1f1",
# "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05",
# "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185",
# "MyBalance": <updated balance>,
# "TheirBalance": <updated balance>
# }
# ],
# "ChannelMode": "Open"
# }
# ]
```
Your balance on the L2 channel should be reduced by total payments done on the virtual payment channel
## Swaps on L2
Perform swaps using a swap channel created with another Nitro node over the mirrored L2 channel with bridge as an intermediary
* Prerequisite: Ledger channel is required to create a swap channel
* Run the following commands on deployment machine
* Switch to the `nitro-node` directory:
```bash
cd <path-to-deployments-dir>
```
* Check status of the mirrored channel on L2:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node"
# Example output:
# [
# {
# "ID": "0xb34210b763d4fdd534190ba11886ad1daa1e411c87be6fd20cff74cd25077c46",
# "Status": "Open",
# "Balances": [
# {
# "AssetAddress": "0xa4351114dae1abeb2d552d441c9733c72682a45d",
# "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05",
# "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185",
# "MyBalance": 1000,
# "TheirBalance": 1000
# },
# {
# "AssetAddress": "0x314e43f9825b10961859c2a62c2de6a765c1c1f1",
# "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05",
# "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185",
# "MyBalance": 1000,
# "TheirBalance": 1000
# }
# ],
# "ChannelMode": "Open"
# }
# ]
```
* Set required variables:
```bash
export BRIDGE_NITRO_ADDRESS=$(yq eval '.bridge_nitro_address' nitro-node-config.yml)
export GETH_CHAIN_ID="1212"
# Get asset addresses from assets.json file
export ASSET_ADDRESS_1=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken.address' assets.json)
export ASSET_ADDRESS_2=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken2.address' assets.json)
```
* Set counterparty address
```bash
export COUNTER_PARTY_ADDRESS=<counterparty-nitro-address>
```
* Get the nitro address of the counterparty's node with whom you want create swap channel
* To get the nitro address of the your node:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-node-info -p 4005 -h nitro-node"
# `SCAddress` -> nitro address
```
* Create swap channel:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client swap-fund $COUNTER_PARTY_ADDRESS $BRIDGE_NITRO_ADDRESS --asset "$ASSET_ADDRESS_1:100,100" --asset "$ASSET_ADDRESS_2:100,100" -p 4005 -h nitro-node"
# Expected output
# Objective started SwapFund-0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9
# Channel open 0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9
```
* Export swap channel ID:
```bash
export SWAP_CHANNEL_ID=
```
* Check swap channel:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-swap-channel $SWAP_CHANNEL_ID -p 4005 -h nitro-node"
# Expected output:
# {
# ID: '0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9',
# Status: 'Open',
# Balances: [
# {
# AssetAddress: '0xa4351114dae1abeb2d552d441c9733c72682a45d',
# Me: '0x075400039e303b3fb46c0cff0404c5fa61947c05',
# Them: '0xd0ea8b27591b1d070cccd4d30b8d408fe794fdfc',
# MyBalance: 100n,
# TheirBalance: 100n
# },
# {
# AssetAddress: '0x314e43f9825b10961859c2a62c2de6a765c1c1f1',
# Me: '0x075400039e303b3fb46c0cff0404c5fa61947c05',
# Them: '0xd0ea8b27591b1d070cccd4d30b8d408fe794fdfc',
# MyBalance: 100n,
# TheirBalance: 100n
# }
# ]
# }
```
### Performing swaps
* Ensure that environment variables for asset addresses are set (should be done by both parties):
```bash
export GETH_CHAIN_ID="1212"
# Get asset addresses from assets.json file
export ASSET_ADDRESS_1=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken.address' assets.json)
export ASSET_ADDRESS_2=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken2.address' assets.json)
```
* Get all active swap channels for a specific mirrored ledger channel (should be done by both parties)
* To get mirrored ledger channels:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node"
# Example output:
# [
# {
# "ID": "0xb34210b763d4fdd534190ba11886ad1daa1e411c87be6fd20cff74cd25077c46",
# "Status": "Open",
# "Balances": [
# {
# "AssetAddress": "0xa4351114dae1abeb2d552d441c9733c72682a45d",
# "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05",
# "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185",
# "MyBalance": 1000n,
# "TheirBalance": 1000n
# },
# {
# "AssetAddress": "0x314e43f9825b10961859c2a62c2de6a765c1c1f1",
# "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05",
# "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185",
# "MyBalance": 1000n,
# "TheirBalance": 1000n
# }
# ],
# "ChannelMode": "Open"
# }
# ]
```
* Export ledger channel ID:
```bash
export LEDGER_CHANNEL_ID=
```
* To get swap channels for a ledger channel:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-swap-channels-by-ledger $LEDGER_CHANNEL_ID -p 4005 -h nitro-node"
# Example Output:
# [
# {
# ID: '0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9',
# Status: 'Open',
# Balances: [
# {
# AssetAddress: '0xa4351114dae1abeb2d552d441c9733c72682a45d',
# Me: '0x075400039e303b3fb46c0cff0404c5fa61947c05',
# Them: '0xd0ea8b27591b1d070cccd4d30b8d408fe794fdfc',
# MyBalance: 100,
# TheirBalance: 100n
# },
# {
# AssetAddress: '0x314e43f9825b10961859c2a62c2de6a765c1c1f1',
# Me: '0x075400039e303b3fb46c0cff0404c5fa61947c05',
# Them: '0xd0ea8b27591b1d070cccd4d30b8d408fe794fdfc',
# MyBalance: 100,
# TheirBalance: 100
# }
# ]
# }
# ]
```
* Export swap channel ID:
```bash
export SWAP_CHANNEL_ID=
```
* One of the participants can initiate the swap and other one will either accept it or reject it
* For initiating the swap:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client swap-initiate $SWAP_CHANNEL_ID --AssetIn "$ASSET_ADDRESS_1:20" --AssetOut "$ASSET_ADDRESS_2:10" -p 4005 -h nitro-node"
# Expected output:
# {
# SwapAssetsData: {
# TokenIn: '0xa4351114dae1abeb2d552d441c9733c72682a45d',
# TokenOut: '0x314e43f9825b10961859c2a62c2de6a765c1c1f1',
# AmountIn: 20,
# AmountOut: 10
# },
# Channel: '0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9'
# }
```
OR
* For receiving the swap
* Get the pending swap:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-pending-swap $SWAP_CHANNEL_ID -p 4005 -h nitro-node"
# Expected output:
# {
# Id: '0x7d582020753335cfd2f2af14127c9b51c7ed7a5d547a674d9cb04fe62de6ddf3',
# ChannelId: '0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9',
# Exchange: {
# TokenIn: '0xa4351114dae1abeb2d552d441c9733c72682a45d',
# TokenOut: '0x314e43f9825b10961859c2a62c2de6a765c1c1f1',
# AmountIn: 20,
# AmountOut: 10
# },
# Sigs: {
# '0': '0x0a018de18a091f7bfb400d9bc64fe958d298882e569c1668c5b1c853b5493221576b2d72074ef6e1899b79e60eaa9934afac5c1e07b7000746bac5b3b1da93311b'
# },
# Nonce: 2840594896360394000
# }
```
* Export swap ID:
```bash
export SWAP_ID=
```
* Either accept or reject the swap
* To accept:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client swap-accept $SWAP_ID -p 4005 -h nitro-node"
# Expected output:
# Confirming Swap with accepted
# Objective complete Swap-0x7d582020753335cfd2f2af14127c9b51c7ed7a5d547a674d9cb04fe62de6ddf3
```
OR
* To reject:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client swap-reject $SWAP_ID -p 4005 -h nitro-node"
# Expected output:
# Confirming Swap with accepted
# Objective complete Swap-0x7d582020753335cfd2f2af14127c9b51c7ed7a5d547a674d9cb04fe62de6ddf3
```
* Check swap channel:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-swap-channel $SWAP_CHANNEL_ID -p 4005 -h nitro-node"
# Example output:
# {
# ID: '0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9',
# Status: 'Open',
# Balances: [
# {
# AssetAddress: '0xa4351114dae1abeb2d552d441c9733c72682a45d',
# Me: '0xd0ea8b27591b1d070cccd4d30b8d408fe794fdfc',
# Them: '0x075400039e303b3fb46c0cff0404c5fa61947c05',
# MyBalance: 120n,
# TheirBalance: 80n
# },
# {
# AssetAddress: '0x314e43f9825b10961859c2a62c2de6a765c1c1f1',
# Me: '0xd0ea8b27591b1d070cccd4d30b8d408fe794fdfc',
# Them: '0x075400039e303b3fb46c0cff0404c5fa61947c05',
# MyBalance: 90n,
# TheirBalance: 110n
# }
# ]
# }
```
* Close swap channel:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client swap-defund $SWAP_CHANNEL_ID -p 4005 -h nitro-node"
# Expected output:
# Objective started SwapDefund-0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9
# Objective complete SwapDefund-0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9
```
* Check L2 mirrored channel status:
```bash
laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node"
# Example output:
# [
# {
# "ID": "0xb34210b763d4fdd534190ba11886ad1daa1e411c87be6fd20cff74cd25077c46",
# "Status": "Open",
# "Balances": [
# {
# "AssetAddress": "0xa4351114dae1abeb2d552d441c9733c72682a45d",
# "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05",
# "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185",
# "MyBalance": <updated balance>,
# "TheirBalance": <updated balance>
# },
# {
# "AssetAddress": "0x314e43f9825b10961859c2a62c2de6a765c1c1f1",
# "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05",
# "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185",
# "MyBalance": <updated balance>,
# "TheirBalance": <updated balance>
# }
# ],
# "ChannelMode": "Open"
# }
# ]
```
## Update nitro nodes
* Switch to deployments dir:
```bash
cd $DEPLOYMENTS_DIR/nitro-node
```
* Rebuild containers:
```bash
laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/nitro-node build-containers --force-rebuild
```
* Restart the nodes
```bash
laconic-so deployment --dir l1-nitro-deployment stop
laconic-so deployment --dir l1-nitro-deployment start
laconic-so deployment --dir l2-nitro-deployment stop
laconic-so deployment --dir l2-nitro-deployment start
```
## Clean up
* Switch to deployments dir:
```bash
cd <path-to-deployments-dir>
```
* Stop all Nitro services running in the background:
```bash
laconic-so deployment --dir l1-nitro-deployment stop
laconic-so deployment --dir l2-nitro-deployment stop
```
* To stop all services and also delete data:
```bash
laconic-so deployment --dir l1-nitro-deployment stop --delete-volumes
laconic-so deployment --dir l2-nitro-deployment stop --delete-volumes
# Remove deployment directories (deployments will have to be recreated for a re-run)
sudo rm -r l1-nitro-deployment
sudo rm -r l2-nitro-deployment
```
## Troubleshooting
* Check the logs of nitro node to see if the objective is completed
```bash
# To check logs of L1 nitro-node
laconic-so deployment --dir l1-nitro-deployment logs nitro-node -f --tail 30
# To check logs of L2 nitro-node
laconic-so deployment --dir l2-nitro-deployment logs nitro-node -f --tail 30
```
* If the objective is completed, you can safely stop (`Ctrl+C`) the running CLI command and continue with the further instructions
* Stop (`Ctrl+C`) the direct-fund command if it is stuck
* Restart the L1 Nitro node:
* Stop the deployment:
```bash
cd <path-to-deployments-dir>
laconic-so deployment --dir l1-nitro-deployment stop
```
* Reset the node's durable store:
```bash
sudo rm -rf l1-nitro-deployment/data/nitro_node_data
mkdir l1-nitro-deployment/data/nitro_node_data
```
* Restart the deployment:
```bash
laconic-so deployment --dir l1-nitro-deployment start
```
* Retry the ledger channel creation command