Data Availability Node
While there are various approaches to running a DA (Data Availability) node, this guide outlines our recommended method and the necessary hardware specifications. DA Nodes perform the core functions of verifying, signing, and storing encoded blob data.
To operate effectively, your DA signer needs to run a DA node to verify encoded blob data, sign it, and store it for future farming and rewards. Currently, to run a DA Node on Testnet, users must stake 10 OG tokens. These can be obtained through our faucet or via rewards from running Storage Nodes or Validator Nodes. You can also reach out to our technical moderators on Discord.
Hardware Requirements
Section titled “Hardware Requirements”Component | DA Node |
---|---|
Memory | 16 GB RAM |
CPU | 8 cores |
Disk | 1 TB NVMe SSD |
Bandwidth | 100 MBps for Download / Upload |
Standing up a DA Node and DA Signer
Section titled “Standing up a DA Node and DA Signer”1. Clone the DA Node Repo:
Section titled “1. Clone the DA Node Repo:”git clone https://github.com/0glabs/0g-da-node.gitcd 0g-da-node
2. Generate BLS Private Key (if needed):
Section titled “2. Generate BLS Private Key (if needed):”If you don’t have a BLS private key, generate one:
cargo run --bin key-gen
Keep the generated BLS private key secure.
3. Set up config.toml:
Section titled “3. Set up config.toml:”-
Create a configuration file named config.toml in the project root directory.
-
Add the following content to the file, adjusting values as needed:
log_level = "info"
data_path = "/data"
# path to downloaded params folderencoder_params_dir = "/params"
# grpc server listen addressgrpc_listen_address = "0.0.0.0:34000"# chain eth rpc endpointeth_rpc_endpoint = "https://evmrpc-testnet.0g.ai"# public grpc service socket address to register in DA contract# ip:34000 (keep same port as the grpc listen address)# or if you have dns, fill your dnssocket_address = "<public_ip/dns>:34000"
# data availability contract to interact withda_entrance_address = "0x857C0A28A8634614BB2C96039Cf4a20AFF709Aa9" # testnet config# deployed block number of da entrance contractstart_block_number = 940000 # testnet config
# signer BLS private keysigner_bls_private_key = ""# signer eth account private keysigner_eth_private_key = ""# miner eth account private key, (could be the same as `signer_eth_private_key`, but not recommended)miner_eth_private_key = ""
# whether to enable data availability samplingenable_das = "true"
Make sure to fill in the signer_bls_private_key
, signer_eth_private_key
, and miner_eth_private_key
fields with your actual private keys.
4. Build and Start the Docker Container:
Section titled “4. Build and Start the Docker Container:”docker build -t 0g-da-node .docker run -d --name 0g-da-node 0g-da-node
5. Verify the Node is Running
Section titled “5. Verify the Node is Running”On the first run, the DA node will register the signer information in the DA contract. You can monitor the console output to ensure the node is running correctly and has successfully registered.
Node Operations
Section titled “Node Operations”As a DA node operator, your node will perform the following tasks:
- Encoded blob data verification
- Signing of verified data
- Storing blob data for further farming
- Receiving rewards for these operations
Troubleshooting
Section titled “Troubleshooting”- If you encounter any issues, check the console output for error messages.
- Ensure that the ports specified in your
config.toml
file are not being used by other applications. - Verify that you have the latest stable version of Rust installed.
- Make sure your system meets the minimum hardware requirements.
Conclusion
Section titled “Conclusion”You have now successfully set up and run a 0g DA node as a DA Signer. For more advanced configuration options and usage instructions, please refer to the Official GitHub repository.
Remember to keep your private keys secure and regularly update your node software to ensure optimal performance and security.
Step 1: Clone and Build the Repository
Section titled “Step 1: Clone and Build the Repository”- Install dependencies:
sudo apt-get update && sudo apt-get install clang cmake build-essential pkg-config libssl-dev protobuf-compiler llvm llvm-dev
- Clone the repository and checkout the specific version:
git clone https://github.com/0glabs/0g-da-node.gitcd 0g-da-node
- Build the project:
cargo build --release
- Download necessary parameters:
./dev_support/download_params.sh
Step 2: Generate BLS Private Key (if needed)
Section titled “Step 2: Generate BLS Private Key (if needed)”If you don’t have a BLS private key, generate one:
cargo run --bin key-gen
Keep the generated BLS private key secure.
Step 3: Configure the Node
Section titled “Step 3: Configure the Node”-
Create a configuration file named
config.toml
in the project root directory. -
Add the following content to the file, adjusting values as needed:
log_level = "info"
data_path = "./db/"
# path to downloaded params folderencoder_params_dir = "params/"
# grpc server listen addressgrpc_listen_address = "0.0.0.0:34000"# chain eth rpc endpointeth_rpc_endpoint = "https://evmrpc-testnet.0g.ai"# public grpc service socket address to register in DA contract# ip:34000 (keep same port as the grpc listen address)# or if you have dns, fill your dnssocket_address = "<public_ip/dns>:34000"
# data availability contract to interact withda_entrance_address = "0x857C0A28A8634614BB2C96039Cf4a20AFF709Aa9" # testnet config and see testnet page for the latest info
# deployed block number of da entrance contractstart_block_number = 940000 # testnet config
# signer BLS private keysigner_bls_private_key = ""# signer eth account private keysigner_eth_private_key = ""# miner eth account private key, (could be the same as `signer_eth_private_key`, but not recommended)miner_eth_private_key = ""
# whether to enable data availability samplingenable_das = "true"
Make sure to fill in the signer_bls_private_key
, signer_eth_private_key
, and miner_eth_private_key
fields with your actual private keys.
Step 4: Run the Node
Section titled “Step 4: Run the Node”Start the 0g DA node using the following command:
./target/release/server --config config.toml
This will start the node using the configuration file you created.
Step 5: Verify the Node is Running
Section titled “Step 5: Verify the Node is Running”On the first run, the DA node will register the signer information in the DA contract. You can monitor the console output to ensure the node is running correctly and has successfully registered.
Node Operations
Section titled “Node Operations”As a DA node operator, your node will perform the following tasks:
- Encoded blob data verification
- Signing of verified data
- Storing blob data for further farming
- Receiving rewards for these operations
Troubleshooting
Section titled “Troubleshooting”- If you encounter any issues, check the console output for error messages.
- Ensure that the ports specified in your config.toml file are not being used by other applications.
- Verify that you have the latest stable version of Rust installed.
- Make sure your system meets the minimum hardware requirements.
Conclusion
Section titled “Conclusion”You have now successfully set up and run a 0g DA node as a DA Signer. For more advanced configuration options and usage instructions, please refer to the Official GitHub repository.
Remember to keep your private keys secure and regularly update your node software to ensure optimal performance and security.
Overview
Section titled “Overview”The DASigners contract is an interface through which Solidity contracts can interact with the 0G chain module DASigners. It is registered as a precompiled contract, similar to other precompiled EVM extensions.
Becoming a DA Signer
Section titled “Becoming a DA Signer”To become a DA signer, you must meet the following requirements:
-
Delegation Requirement: To become a signer, an address must receive enough delegations, equivalent to at least the
TokensPerVote
amount of OG tokens (30 tokens per vote in the testnet), registered in theDASigners
module. -
Node Operation: Each signer needs to run a DA (Data Availability) node that verifies blob encoding and generates BLS signatures for signed blobs.
-
Registration: Signers must register their information using the
registerSigner
function. This includes providing their address, node socket address, BLS public key, and a signature signed by their BLS private key. -
Epoch Participation: Signers must submit a registration message (using the
registerNextEpoch
function) with a signature for each epoch they wish to participate in. This is necessary for joining quorums in the next epoch. -
Voting Power: Each signer’s voting power is determined by the number of tokens delegated to them.
-
Quorum Responsibilities: Each signer in a quorum is responsible for validating, signing, and storing a specific row of encoded blob data during an epoch.
Prerequisites
Section titled “Prerequisites”Ensure you have the following installed on your system:
- Git
- Rust (latest stable version)
- Cargo (comes with Rust)
Contract Details
Section titled “Contract Details”Address: 0x0000000000000000000000000000000000001000
Contract Params (Testnet)
Section titled “Contract Params (Testnet)”TokensPerVote = 30MaxVotesPerSigner = 1024MaxQuorums = 10EpochBlocks = 5760EncodedSlices = 3072
Terminology
Section titled “Terminology”Signer
Section titled “Signer”A Signer is an address with sufficient delegations (at least TokensPerVote
OG) registered in the DASigners module. Each signer should run a DA node to verify DA blob encoding and generate BLS signatures for signed blobs. The BLS curve used is BN254, and the public keys of signers are registered in the contract.
Note: For accounts with delegations to more than 10 validators, only 10 of these delegations are counted and accumulated.
The consecutive blocks in the 0g chain are divided into groups of EpochBlocks
, and each group is an epoch.
Quorum
Section titled “Quorum”In an epoch, there can be up to MaxQuorums
quorums. Each quorum is a list of signer addresses with size EncodedSlices
. The i-th signer in the quorum is responsible for validating, signing, and storing the i-th row of the encoded blob data assigned to this quorum.
Signers can submit their signatures on a registration message to request joining the quorums in the next epoch. At the start of each epoch, the DASigners module calculates the voting power for registered signers based on their delegated token amounts. Each delegated TokensPerVote
OG counts as one vote, and each signer can have up to MaxVotesPerSigner
votes. All votes are then randomly ordered and distributed into quorums.
Transactions
Section titled “Transactions”registerSigner
Section titled “registerSigner”Register signer’s information, including signer address, DA node service socket address, signer BLS public key on G1 and G2 group, and a signature signed by the BLS private key of the following message:
Keccak256(signerAddress, chainID, "0G_BN254_Pubkey_Registration")
Here chainID
is left-padded to 32 bytes by zeros.
function registerSigner( SignerDetail memory _signer, BN254.G1Point memory _signature) external;
updateSocket
Section titled “updateSocket”Update signer’s socket address.
function updateSocket(string memory _socket) external;
registerNextEpoch
Section titled “registerNextEpoch”Register to join the quorums in the next epoch. The signer needs to submit a signature signed by their BLS private key:
Keccak256(signerAddress, epoch, chainID)
Here chainID
is left-padded to 32 bytes by zeros and epoch is an unsigned 64-bit number in big-endian format.
function registerNextEpoch(BN254.G1Point memory _signature) external;
Queries
Section titled “Queries”epochNumber
Section titled “epochNumber”Get the current epoch number.
function epochNumber() external view returns (uint);
quorumCount
Section titled “quorumCount”Get the number of quorums for a given epoch.
function quorumCount(uint _epoch) external view returns (uint);
isSigner
Section titled “isSigner”Check if a given address is a registered signer.
function isSigner(address _account) external view returns (bool);
getSigner
Section titled “getSigner”Get the information of given signers.
function getSigner(address[] memory _account) external view returns (SignerDetail[] memory);
getQuorum
Section titled “getQuorum”Get the signer list of a given epoch and quorum id.
function getQuorum(uint _epoch, uint _quorumId) external view returns (address[] memory);
getQuorumRow
Section titled “getQuorumRow”Get the signer of a specific row in a given epoch and quorum id.
function getQuorumRow(uint _epoch, uint _quorumId, uint32 _rowIndex) external view returns (address);
registeredEpoch
Section titled “registeredEpoch”Check if a given address is registered to join the given epoch.
function registeredEpoch(address _account, uint _epoch) external view returns (bool);
getAggPkG1
Section titled “getAggPkG1”Get the aggregated G1 public key for a given signers set. The signers set is specified by the epoch, quorum id, and a bitmap. The bitmap has EncodedSlices bits, and each bit denotes whether the row is chosen or not.
function getAggPkG1( uint _epoch, uint _quorumId, bytes memory _quorumBitmap) external view returns (BN254.G1Point memory aggPkG1, uint total, uint hit);