Interacting with a subnet: fund, release, checkpoint
This guide will walk you through the supported interactions between bitcoin and L2 subnets, specifically depositing BTC and withdrawing BTC back to the bitcoin network. Transferring tokens between L2 subnets is addressed in the Cross-chain token transfers.
We call "wrapped BTC" and "wrapped satoshi" the tokens used in a L2 subnet.
Prerequisites
Before starting, ensure that you have
deployed subnet with id
$SUBNET_ID
exported the IPC address of each validator as
$IPC_ADDRESS_OF_VALIDATOR_1
...$IPC_ADDRESS_OF_VALIDATOR_4
and of user 1 as$IPC_ADDRESS_OF_USER_1
created wallets and configuration files for user 1
funded the validators via
cross-msg fund
The previous steps should have covered all these prerequisites.
Moreover, the helper scripts described earlier will be useful for monitoring the balances in the subnet and mining bitcoin blocks on regtest. You can optionally run them in separate terminals/panels that you can easily watch.
Step 1: Start a relayer
Checkpoint messaging and relayers
In IPC a checkpoint message, also called a bottom-up message, contains:
release operations from the child (an L2 subnet) to the parent (Bitcoin L1)
transfer operations from the child to another subnet,
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)
Running a relayer
You can start a relayer using the following command:
ipc-cli --config-path ~/.ipc/validator1/config.toml checkpoint relayer --subnet $SUBNET_ID
You can use the same command, but pointing to a different validator's config, to start a second relayer.
Common problems and caveats:
Make sure the subnet is added to the config.toml file, otherwise the command returns the error that the subnet is not configured.
Make sure that you have funded all validators (as described in Subnet creation and initialisation), otherwise they will not be able to vote for and finalize checkpoint messages.
When the relayer starts, it tries to submit all previous checkpoints found in the subnet. When bitcoin is the parent subnet, this has the implication that the input UTXOs to an old checkpoint transaction might not be available anymore. Hence, because different checkpoints which are causally dependent may spend the same UTXO, instead of chained UTXOs, at least one relayer must be running for the subnet at all times.
Since in this guide we are starting the relayer much later than when the subnet was deployed, the relayer may initially print some warnings, as it may not be able to submit old checkpoints.
If the checkpoint period is lower than the block-generation parameter on bitcoin (which does not make sense in a real deployment, but may happen when testing on Regtest if you do not generate blocks soon enough and you do not run the
miner.sh
script), then the relayer will return warnings saying that "transaction is already in mempool". These messages can anyway be ignored, as the bitcoin has been submitted to bitcoin. The same will happen if you are running more than one relayers, as they will all by trying to submit the same transactions to bitcoin.
More commands and implementation details
You can use the following ipc-cli command to query the bottom-up messages finalized in $SUBNET_ID
between epochs <FROM-EPOCH>
and <TO-EPOCH>
(you can see current block height in child subnets using the script provided in the previous page).
ipc-cli checkpoint list-bottomup-bundle --subnet $SUBNET_ID --from-epoch <FROM-EPOCH> --to-epoch <TO-EPOCH>
Step 2: Fund a user
Let's fund the account of user 1 in the subnet $SUBNET-ID
with 1 wBTC:
ipc-cli --config-path ~/.ipc/user1/config.toml cross-msg fund --subnet=$SUBNET_ID btc --to $IPC_ADDRESS_OF_USER_1 100000000
Parameters:
--subnet
: The ID of the subnet where we are depositing BTC.--to
: The recipient IPC address within the subnet.The sender is the wallet used by the bitcoin provider of the user (defined in
~/.ipc/user1/.env
, which was given as argument when we run the bitcoin provider, in this case the wallet isuser1
).
Returns:
The bitcoin block height when the fund transaction was submitted to bitcoin (not the block in which it was included).
Make sure you mine a block (not needed if you are running the miner.sh
script).
bitcoin-cli generatetoaddress 1 "$(bitcoin-cli --rpcwallet=default getnewaddress)"
Caveat:
If the fund amount is too low, the transaction may not get accepted in the mempool. You can verify that it was indeed included in a block by checking the output of the monitor
after mining the blocks.
Verify the balance in the subnet
You can use the balancer helper script to check that the balance was updated in the subnet (described in Helper scripts):
./scripts/balancer.sh $SUBNET_ID
or use following command.
ipc-cli wallet balances --subnet $SUBNET_ID --wallet-type btc | grep $IPC_ADDRESS_OF_USER_1
Verify the balance on bitcoin
The following commands can be used to verify that the balance of user 1 on bitcoin was decreased:
bitcoin-cli --rpcwallet=user1 getbalance
cast balance $IPC_ADDRESS_OF_USER_1 --rpc-url http://localhost:8545/
More commands and implementation details
The
ipc-cli fund
command is implemented by a bitcoin transaction sending the funds to a multisig address.The multisig address is managed by the subnet's validators.
The deposit transaction includes metadata linking it to the user’s wallet within the subnet.
Validators monitor the Bitcoin network and confirm the transaction (through what is called "top-down messaging" in IPC).
Once confirmed, validators mint an equivalent amount of wrapped tokens in the subnet and transfer them to the user’s address.
You can see the top-down messages on bitcoin between blocks <FROM-BLOCK>
and <TO-BLOCK>
destined to subnet <SUBNET-ID>
using:
ipc-cli cross-msg list-topdown-msgs --subnet=$SUBNET_ID --from <FROM-BLOCK> --to <TO-BLOCK>
You can also see the latest block considered final for the subnet using:
ipc-cli cross-msg parent-finality --subnet=$SUBNET_ID
Step 3: Release BTC back to L1
We will perform a release for IPC_ADDRESS_OF_USER_1
, whose wallet on bitcoin is user1
.
Check the balances before performing the release for some address IPC_ADDRESS_OF_USER_1
in the L2 subnet:
# Balance on the L1
bitcoin-cli -rpcwallet=user1 getbalance
# Balance on the L2
ipc-cli wallet balances --subnet $SUBNET_ID --wallet-type btc | grep $IPC_ADDRESS_OF_USER_1
Perform the release:
ipc-cli cross-msg release --subnet $SUBNET_ID --from $IPC_ADDRESS_OF_USER_1 btc --to "$(bitcoin-cli --rpcwallet=user1 getnewaddress)" 50000000
Parameters:
--subnet
: The ID of the subnet where we are releasing from.--from
: The IPC address of an account in subnet<SUBNET-ID>
.--to
: The bitcoin address of the recipient.
You can use the same commands as above to check the balances after the release. Notice that the balance in the subnet is updated almost immediately, while the balance on bitcoin will be updated after the next checkpoint transaction is submitted. This may take a while, depending on the parameter --bottomup-check-period
chosen at subnet creation.
More information and implementation details
After submitting the release command, you can look at the output of any bitcoin monitor. You should see that it picked up the corresponding checkpoint transaction (IpcCheckpointSubnetMsg
), and that it contains the withdrawal we submitted. After this, the balance on bitcoin should reflect all performed withdrawals.
Last updated