Links
Comment on page

Deploying a DA Node

Deploy a Mantle DA node to provide data availability services to Mantle network
All Mantle DA nodes are run by Mantle Core Contributor Team for the time being. Stay tuned for updates!
Data Availability, or DA nodes basically get rewards for storing the calldata that is traditionally published to Ethereum. There are multiple advantages to this solution, and you can read up more on why data availability is a major concern for optimistic rollups, and how Mantle addresses it by navigating to the Data Availability page.
The data storage process consists of two steps:
  1. 1.
    The DA Operator node receives data from the Disperser and stores it
  2. 2.
    It then sends a BLS signature to Disperser after performing data recovery verification
The minimum recommended specifications for a DA node are:
  • Quad core CPU or higher
  • 8GB+ RAM
  • 500GB+ disk space (HDD works, SSD recommended for future-proofing)
  • 10 Mbps+ download speed
Before getting started, make sure you have Docker installed in your environment and superuser access configured for your account.
Please make sure you have Foundry installed and configured in your local environment! You'll need it to use the cast tool to make RPC calls.

Whitelisting

You can get in touch with us via mail to with your wallet address, and we'll whitelist it so you can move ahead with the deployment process.

Downloading necessary scripts

You can start by cloning the GitHub repo.
git clone https://github.com/mantlenetworkio/networks
The downloaded directory contains the compose files to run both Mantle verifier/sequencer nodes, and DA nodes. The file is named docker-compose.da.yml and we'll be using it to spin up our DA node.
The ./da/scripts directory contains a binary that will automatically download all the necessary files and spin up a DA node. Let's see how to start up a DA node using the binary, as well as Docker.

Start up a node

Environment configuration

Before starting up a node you'll need to configure the node environment. You can do this by creating a .env file in the ./scripts directory.
The configuration is shown below. You can go ahead and use the same configuration to connect to Mantle testnet.
1
DL_NODE_CHAIN_ID: 5
2
DL_NODE_CHAIN_RPC: https://rpc.ankr.com/eth_goerli
3
DL_NODE_CHALLENGE_ORDER: 200000
4
DL_NODE_DB_PATH: /data/da-node
5
DL_NODE_DLSM_ADDRESS: 0x5d88885659dc1ba1C25d9e9a78ec4df313672d48
6
DL_NODE_FILE_LOG_LEVEL: trace
7
DL_NODE_G1_PATH: /data/kzg/g1.point
8
DL_NODE_G2_PATH: /data/kzg/g2.point
9
DL_NODE_GRAPH_PROVIDER: http://k8s-app-graphnod-30887b7825-5c5d19b37726120d.elb.ap-southeast-1.amazonaws.com:8000/subgraphs/name/datalayr
10
DL_NODE_GRPC_PORT: 32000
11
DL_NODE_HOSTNAME: ${publicip_of_da-node}
12
DL_NODE_LOG_PATH: /data/logs/da-node
13
DL_NODE_SRS_ORDER: 200000
14
DL_NODE_PRIVATE_BLS: '8332518314'
15
DL_NODE_SRS_TABLE_PATH: /data/kzg/SRSTables
16
DL_NODE_STD_LOG_LEVEL: debug
17
DL_NODE_TIMEOUT: 3000ms
18
DL_NODE_CACHE_PATH: data/kzg/SRSTables
19
DL_NODE_VERBOSE: true
20
DL_NODE_NUM_WORKERS: 8
21
DL_NODE_ENABLE_METRICS: true
22
DL_NODE_METRICS_PORT: 7001
23
DL_NODE_PRIVATE_KEY: ${danode-privatekey}
Here's a brief description of each setting.
Field name
Description
DL_NODE_CHAIN_ID
L1 chain ID
DL_NODE_CHAIN_RPC
L1 RPC provider URL
DL_NODE_CHALLENGE_ORDER
Challenge order, 3000 by default
DL_NODE_DB_PATH
DA node database directory
DL_NODE_DLSM_ADDRESS
DataLayrServiceManager contract address
DL_NODE_FILE_LOG_LEVEL
DA node log file level
DL_NODE_G1_PATH
G1 SRS path
DL_NODE_G2_PATH
G2 SRS path
DL_NODE_GRAPH_PROVIDER
GraphQL API endpoint for Graph node
DL_NODE_GRPC_PORT
Port at which node listens for gRPC calls
DL_NODE_HOSTNAME
DA Node host name
DL_NODE_LOG_PATH
DA Node log path
DL_NODE_SRS_ORDER
SRS order
DL_NODE_PRIVATE_BLS
BLS private key for node operator
DL_NODE_SRS_TABLE_PATH
SRS table path
DL_NODE_STD_LOG_LEVEL
DA Node STD Log level
DL_NODE_TIMEOUT
gRPC request timeout in ms
DL_NODE_CACHE_PATH
DA node cache directory
DL_NODE_VERBOSE
DA node verbose
DL_NODE_NUM_WORKERS
DA node workers
DL_NODE_ENABLE_METRICS
Enable/disable metrics for DA node
DL_NODE_METRICS_PORT
Metrics port
DL_NODE_PRIVATE_KEY
DA node operator wallet private key

Using Docker

After completing the Docker environment variable configuration in the docker-compose.da.yml file, use the following Docker command to spin up a DA node.
cd network
sudo docker compose -f docker-compose.da.yml up -d

Using Binary

Stay tuned!

Important addresses

  • Mantle DA delegation contract: 0xe6394303385f50b22F8E6fDe7ddE3236794A62a6
  • Investment manager contract: 0x14dA377F5d37fa501E76D5208418714E3A26a2F0
  • $MNT token contract on Goerli: 0xc1dC2d65A2243c22344E725677A3E3BEBD26E604
  • Open node RPC: http://goerli.test

Register a DA operator node

You'll need to register your operator node to enable user staking and delegation via your wallet. You can do this by calling the registerAsOperator function of the EigenLayrDelegation contract. Here's an example.
cast send --from $FromAddress --private-key $PrivateKey --rpc-url $L1Rpc $DelegationAddress "registerAsOperator(address)" $OperatorAddress

Parameters

Parameter
Description
FromAddress
Operator wallet address
PrivateKey
Operator wallet private key
L1Rpc
Ethereum RPC URL
Mantle DA delegation contract address
OperatorAddress
Operator EOA address

Node de-registeration

To withdraw a node from the DA network, the first step is to fetch the public key and index for your node from the staker subgraph, like so:
query MyQuery {
operators(orderBy: id, where: {status: 0}) {
status
id
pubkeys {
id
pubkeyG1
}
indexHistory {
index
}
}
}
Next, you can call the deregisterOperator method which is a part of the BLSRegistryWithBomb contract. The method takes the following parameters:
deregisterOperator(uint256[4], uint32, bytes32):(pubKey,index,0x0)
Here's a sample request:
cast send --from $FromAddress --private-key $PrivateKey --rpc-url $L1Rpc $DlReg "deregisterOperator( (uint256,uint256), uint32 )" '($pubkeyG1-01,$pubkeyG1-02)' $Index

Parameters

Parameter
Description
FromAddress
Operator wallet address
PrivateKey
Operator wallet private key
L1Rpc
Ethereum RPC URL
DlReg
Mantle DA BLSRegistry contract address
Index
Activity index queried from the staker subgraph
pubkeyG1-01, pubkeyG1-02
pubkeyG1 queried from the subgraph above

Node staking

Node staking is optional!
The staking process consists of the following steps:

1. $MNT Approval

To stake $MNT to a DA node, it first needs to be approved to the InvestmentManager contract. It is no different from a standard ERC-20 approval action. Here's a sample request.
cast send --from $FromAddress --private-key $PrivateKey --rpc-url $L1Rpc $MantleTokenAddress "approve(address,uint256)" $InvestmentManagerAddress $Amount

Parameters

Parameter
Description
FromAddress
Staker wallet address
PrivateKey
Staker wallet private key
L1Rpc
Ethereum RPC URL
$MNT token contract address
Amount
Stake amount
InvestmentManager contract address

2. $MNT Deposit

To delegate the approved tokens to the operator, it needs to be deposited into the investment strategy using the investment strategy contract. We do this by calling the depositIntoStrategy function. Here's a sample request.
cast send --from $FromAddress --private-key $PrivateKey --rpc-url $L1Rpc InvestmentManagerAddress "depositIntoStrategy(address, address, uint256)" $StrategyAddress $MantleTokenAddress $Amount

Parameters

Parameter
Description
FromAddress
Staker wallet address
PrivateKey
Staker wallet private key
L1Rpc
Ethereum RPC URL
Strategy contract address
$MNT token contract address
Amount
Staking amount

3. $MNT Delegation

After approving and depositing the $MNT tokens, we can now invoke the delegateTo function of the EigenLayrDelegation contract to stake your tokens to the operator. Here's a sample request.
cast send --from $FromAddress --private-key $PrivateKey --rpc-url $L1Rpc $DelegationAddress "delegateTo(address)" $OperatorAddress

Parameters

Parameter
Description
FromAddress
Staker wallet address
PrivateKey
Staker private key
L1Rpc
Ethereum RPC URL
Delegation contract address
OperatorAddress
Operator address to be delegated to

4. Fetch $MNT Deposit Info

You can fetch details on the amount of $MNT deposited into the investment manager contract by a wallet address by invoking the getDeposits() function. Here's an sample request.
cast call --rpc-url $L1Rpc $InvestmentManagerAddress "getDeposits(address)(address[],uint256[])" $StakerAddress

Parameters

Parameter
Description
L1Rpc
Ethereum RPC URL
Investment manager contract address
StakerAddress
Staker wallet address

5. $MNT Stake Withdrawal

You can withdraw the delegated $MNT from a wallet address by invoking the delegatorWithdraw() function. Here's a sample request.
cast send --from $FromAddress --private-key $PrivateKey --rpc-url $L1Rpc $InvestmentManagerAddress "delegatorWithdraw(uint256[], address[], address[], uint256[], bool)" "$StrategyIndexList" "$StrategyList" "$TokenList" "$AmountList" $IsUndelegate
delegatorWithdraw() arguments
function delegatorWithdraw(
uint256[] calldata strategyIndexes,
IInvestmentStrategy[] calldata strategies,
IERC20[] calldata tokens,
uint256[] calldata shares,
bool undelegateIfPossible
)

Parameters

Parameter
Description
FromAddress
Staker wallet address
PrivateKey
Staker wallet private key
L1Rpc
Etherem RPC URL
Investment manager contract address
StrategyIndexList
Strategy index list
StrategyList
Strategy list, only Mantle strategy supported
TokenList
Strategy token list, only Mantle token supported
AmountList
Staking amount list
IsUndelegate
Undelegate action boolean