# Deploy the validators

First connect to the `bitcoin-ipc` container (if not already done so) running:

```bash
docker exec -it bitcoin-ipc bash
```

Then run:

```bash
# from inside the container
/usr/local/bin/spin_up_subnet_a_from_container.sh $SUBNET_ID
```

where `SUBNET_ID` indicates the subnet for which you deploy validators (the script of the [subnet-creation](https://bitcoin-scaling-labs-docs.gitbook.io/ipc-btc-scaling-docs/user-guide-for-using-subnets/subnet-creation "mention")outputs it).

This is the `/scripts/spin_up_subnet_a_from_container.sh` script from the `bitcoin-ipc` repo, which has been mounted in the container for convenience. Even though it is run inside the container, the command is handled by the docker daemon on your host machine.

It does the following:

1. It starts twelve Docker containers (three for each validator: `fendermint`, `cometbft` , and `ethapi`) on your host.
2. It starts a Relayer for each validator, with log files stored in  `/root/logs/` in the container. See [optional-helper-scripts](https://bitcoin-scaling-labs-docs.gitbook.io/ipc-btc-scaling-docs/user-guide-for-using-subnets/optional-helper-scripts "mention") for more information on the log files.

{% hint style="info" %}
If you have created a subnet using the `bootstrap_subnet_from_container.sh` script in the previous step, it will have also been added in `/root/.ipc/config.toml` inside the `bitcoin-ipc` container.
{% endhint %}

{% hint style="info" %}
**About the Relayer and Checkpoint messaging**

In IPC a *checkpoint message,* also called a *bottom-up message*, contains:

1. release operations from the child (an L2 subnet) to the parent (Bitcoin L1)
2. transfer operations from the child to another subnet,
3. the actual checkpoint hash.

IPC requires a *relayer* for the bottom-up messaging. A relayer is a binary that is run locally by one or more validators. It connects

* to the local Fendermint node of the validator, so as to obtain any finalized checkpoints,
* to the parent network (in case of bitcoin, to the RPC exposed by the `provider` we started in the previous guides), so as to submit the finalized checkpoint messages.

The fees for submitting the checkpoints to bitcoin are paid by the multisig that controls the subnet.

By default, the relayer binary checks for checkpoints every 15 seconds. This parameter (which is different than the checkpoint generation period that we set during subnet creation) can be changed using the `--checkpoint_interval_sec` option of the relayer binary.

Multiple relayers can be run for an L2 subnet. A validator and any other party can be a relayer. If multiple relayers are running, only one of them will successfully submit it (as we rely on Bitcoin UTXOs to this end)
{% endhint %}

***

## Alternative: Install on the host machine

If in page [installation](https://bitcoin-scaling-labs-docs.gitbook.io/ipc-btc-scaling-docs/user-guide-for-using-subnets/installation "mention") you chose the alternative deployment — hence `bitcoin-core` , the monitors and providers, and `ipc-cli` are running on your host machine — then you **must** also use this alternative approach here to deploy the validators.

Even if you used the default Docker-based deployment, you still have the option to use this alternative approach here to deploy the validators. In that case, you need to run all following commands from inside the `bitcoin-ipc` container — the `ipc` and `bitcoin-ipc` repos can be found in the `/root/workspace` directory.

Please make sure you have successfully run all steps in the previous page [subnet-creation](https://bitcoin-scaling-labs-docs.gitbook.io/ipc-btc-scaling-docs/user-guide-for-using-subnets/subnet-creation "mention"). In particular, make sure that sufficiently many validators have submitted the join and fund commands for the newly created subnet.

### **Step 1: Spin-up docker containers**

We have provided a script that automates spinning up the subnets. The script assumes that you have used the ports, wallet names, and authentication tokens as described in these docs, and that you have already created and joined a subnet with four validators, and that the monitor and provider binaries for those validators are running.&#x20;

Make sure **docker is running** on your machine.

The only input to the script is the subnet id. **From the bitcoin-ipc repo**, run

```bash
./scripts/spin_up_subnet_a.sh $SUBNET_ID
```

{% hint style="warning" %}
**Attention:**\
The scripts outputs a `CometBFT ID` and a `Resolver Address` . This looks like:

```bash
CometBFT ID: 1938b373fb77b24215320bc31dbf7f33469d980e
Resolver Address: 16Uiu2HAmURvM8XziBhzB57YBMQ2fiT8RvUkGpACeCzn1rV8zQQVv
```

We will need this information later when we start a fifth validator for the subnet. Please **note them down and/or create the following environment variables**:

```bash
export CometBftID=<The CometBFT ID>
export ResolverAddress=<The Resolver Address>
```

{% endhint %}

Verify on docker that the containers are up and running — for each validator there should be three containers: `validatorX-fendermint` , `validatorX-cometbft` , and `validatorX-ethapi` .

### Step 2: Check the status of the subnet

You can now use the the scripts provided in [optional-helper-scripts](https://bitcoin-scaling-labs-docs.gitbook.io/ipc-btc-scaling-docs/user-guide-for-using-subnets/optional-helper-scripts "mention") to check the status of the subnet.

In particular, you can verify that the subnet is producing blocks:

```bash
./scripts/l2_block_checker.sh $SUBNET_ID
```

and check the balances in the subnet

```bash
./scripts/balancer.sh $SUBNET_ID
```

```bash
ipc-cli wallet balances --wallet-type btc --subnet $SUBNET_ID
```

## Optional: Deploy validators manually

### Step 1: Deploy the infrastructure

Let's start our first validator which the rest of the validators will bootstrap from. Make sure you have docker running before running this command.

```sh
cargo make --makefile infra/fendermint/Makefile.toml \
    -e NODE_NAME=validator-1 \
    -e SUBNET_ID=<SUBNET_ID> \
    -e PRIVATE_KEY_PATH=$HOME/.ipc/validator1/validator.sk \
    -e CMT_P2P_HOST_PORT=26656 \
    -e CMT_RPC_HOST_PORT=26657 \
    -e ETHAPI_HOST_PORT=8545 \
    -e RESOLVER_HOST_PORT=26655 \
    -e PARENT_ENDPOINT="http://host.docker.internal:3030/api" \
    -e PARENT_AUTH_TOKEN="validator1_auth_token" \
    -e TOPDOWN_CHAIN_HEAD_DELAY=0 \
    -e TOPDOWN_PROPOSAL_DELAY=0 \
    -e FM_PULL_SKIP=1 \
    child-validator
```

{% hint style="success" %}
`TOPDOWN_CHAIN_HEAD_DELAY` specifies  "the number of blocks to delay before reporting a height as final on the parent chain". `TOPDOWN_PROPOSAL_DELAY` specifies "the number of blocks on top of `TOPDOWN_CHAIN_HEAD_DELAY` to wait before proposing a height as final on the parent chain". These parameters are used by standard IPC, but when the parent chain is bitcoin the finalization period is handled by the bitcoin monitor (by default, 0 blocks for bitcoin regtest and 6 for bitcoin mainnet, but these values can be configured). Hence, we do not need to specify additional delay on the fendermint level.
{% endhint %}

Once the first validator is up and running, it will print out the relative information for this validator.

This is shown in [this video guide](https://drive.google.com/file/d/1AKVxciZBd111KK2auZTlMEn2CkRW_SZ4/view?usp=drive_link).

```
#################################
#                               #
# Subnet node ready! 🚀         #
#                               #
#################################

Subnet ID:
	/b4/t410f6b2qto756ox3qfoonq4ii6pdrylxwyretgpixuy

Eth API:
	http://0.0.0.0:8545

Chain ID:
	3684170297508395

Fendermint API:
	http://localhost:26658

CometBFT API:
	http://0.0.0.0:26657

CometBFT node ID:
	ca644ac3194d39a2834f5d98e141d682772c149b

CometBFT P2P:
	http://0.0.0.0:26656

IPLD Resolver Multiaddress:
	/ip4/0.0.0.0/tcp/26655/p2p/16Uiu2HAkwhrWn9hYFQMR2QmW5Ky7HJKSGVkT8xKnQr1oUGCkqWms

```

You'll need the final component of the `IPLD Resolver Multiaddress` (the `peer ID`) and the `CometBFT node ID` for the next nodes to start.

* ***BOOTSTRAPS***: \<CometBFT node ID for validator1>@validator-1-cometbft:26656

  ```
  // An example
  ca644ac3194d39a2834f5d98e141d682772c149b@validator-1-cometbft:26656
  ```
* ***RESOLVER\_BOOTSTRAPS***: /dns/validator-1-fendermint/tcp/26655/p2p/\<Peer ID in IPLD Resolver Multiaddress>, where \<PeerID> is the last part of the IPLD Resolver Multiaddress

  <pre><code>// An example
  <strong>/dns/validator-1-fendermint/tcp/26655/p2p/16Uiu2HAkwhrWn9hYFQMR2QmW5Ky7HJKSGVkT8xKnQr1oUGCkqWms
  </strong></code></pre>

{% hint style="warning" %}
**Attention:**

We will need this information later when we start a fifth validator for the subnet. Please **note them down and/or create the following environment variables**:

```bash
export CometBftID=<The CometBFT ID>
export ResolverAddress=<The Resolver Address>
```

{% endhint %}

Now, let's start the rest of the validators:

```sh
# Run second validator
cargo make --makefile infra/fendermint/Makefile.toml \
	-e NODE_NAME=validator-2 \
	-e SUBNET_ID=<SUBNET_ID> \
	-e PRIVATE_KEY_PATH=$HOME/.ipc/validator2/validator.sk \
	-e CMT_P2P_HOST_PORT=26756 \
	-e CMT_RPC_HOST_PORT=26757 \
	-e ETHAPI_HOST_PORT=8645 \
	-e RESOLVER_HOST_PORT=26755 \
	-e BOOTSTRAPS=<BOOTSTRAPS> \
	-e RESOLVER_BOOTSTRAPS=<RESOLVER_BOOTSTRAPS> \
	-e PARENT_ENDPOINT="http://host.docker.internal:3031/api" \
	-e PARENT_AUTH_TOKEN="validator2_auth_token" \
	-e TOPDOWN_CHAIN_HEAD_DELAY=0 \
    	-e TOPDOWN_PROPOSAL_DELAY=0 \
	-e FM_PULL_SKIP=1 \
	child-validator

# Run third validator
cargo make --makefile infra/fendermint/Makefile.toml \
	-e NODE_NAME=validator-3 \
	-e SUBNET_ID=<SUBNET_ID> \
	-e PRIVATE_KEY_PATH=$HOME/.ipc/validator3/validator.sk \
	-e CMT_P2P_HOST_PORT=26856 \
	-e CMT_RPC_HOST_PORT=26857 \
	-e ETHAPI_HOST_PORT=8745 \
	-e RESOLVER_HOST_PORT=26855 \
	-e BOOTSTRAPS=<BOOTSTRAPS> \
	-e RESOLVER_BOOTSTRAPS=<RESOLVER_BOOTSTRAPS> \
	-e PARENT_ENDPOINT="http://host.docker.internal:3032/api" \
	-e PARENT_AUTH_TOKEN="validator3_auth_token" \
	-e TOPDOWN_CHAIN_HEAD_DELAY=0 \
	-e TOPDOWN_PROPOSAL_DELAY=0 \
	-e FM_PULL_SKIP=1 \
	child-validator

# Run fourth validator
cargo make --makefile infra/fendermint/Makefile.toml \
	-e NODE_NAME=validator-4 \
	-e SUBNET_ID=<SUBNET_ID> \
	-e PRIVATE_KEY_PATH=$HOME/.ipc/validator4/validator.sk \
	-e CMT_P2P_HOST_PORT=26956 \
	-e CMT_RPC_HOST_PORT=26957 \
	-e ETHAPI_HOST_PORT=8845 \
	-e RESOLVER_HOST_PORT=26955 \
	-e BOOTSTRAPS=<BOOTSTRAPS> \
	-e RESOLVER_BOOTSTRAPS=<RESOLVER_BOOTSTRAPS> \
	-e PARENT_ENDPOINT="http://host.docker.internal:3033/api" \
	-e PARENT_AUTH_TOKEN="validator4_auth_token" \
	-e TOPDOWN_CHAIN_HEAD_DELAY=0 \
	-e TOPDOWN_PROPOSAL_DELAY=0 \
	-e FM_PULL_SKIP=1 \
	child-validator
```
