Replica Node
You can build a read-only replica node of Verse-Layer.
How synchronization works
There are two ways for synchronizing Verse-Layer's transaction data to the replica node.
Synchronize from Origin Node
Synchronization occurs from the Verse-Layer origin node. Synchronization is performed with low latency in milliseconds.
Specifically, the op-node services on the origin and replica nodes communicate P2P, and the new L2 blocks proposed by the op-node on the origin node are also published to the replica nodes.
Synchronize from Hub-Layer
Retrieve and synchronize L2 data that has been rolled up to the Hub-Layer. Synchronization occurs after the roll-up from the origin node is confirmed, resulting in a synchronization delay of tens of seconds to a minute or more.
Specifically, the op-node service retrieves roll-up data on the Hub-Layer and proposes it to the op-geth service as L2 blocks.
Which one should be choose?
If you are the origin node owner of the Verse-Layer and the purpose of creating a replica node is for RPC load balancing, we recommend synchronization from the Origin. Otherwise, synchronization from Hub-Layer is recommended.
How to setup replica node
1. Clone opstack repository
Clone the verse-layer-opstack repository on the replica node.
git clone https://github.com/oasysgames/verse-layer-opstack.git
cd verse-layer-opstack
2. Copy configuration files from origin node
Copy the .env
file and the assets
directory from the origin node.
Example of Using rsync:
rsync -av origin:/verse-layer-opstack/.env ./
rsync -av origin:/verse-layer-opstack/assets/ ./assets/
3. Initialize op-geth data directory
Initialize data/op-geth
directory. The initialization procedure differs depending on whether you are upgrading from legacy Optimism or not.
If you are not upgrading from legacy Optimism, the assets/genesis.json
file should exist, so run the command to create the genesis block (number = 0).
docker-compose run --rm --no-deps op-geth init /assets/genesis.json
If upgrading from Legacy Optimism, please stop the origin node's op-geth service and then copy the data/op-geth
directory. If it is difficult to stop the origin node, place the archive data that was backed up during the upgrade process.
# Note: Run on the replica node
mkdir data
rsync -av origin:/verse-layer-opstack/data/op-geth/ ./data/op-geth/
4. Create docker-compose.override.yml
Create a docker-compose.override.yml
file to override the service definition. In this configuration synchronizes from the Hub-Layer.
version: '3'
services:
op-node:
environment:
OP_NODE_SEQUENCER_ENABLED: 'false'
# Suppress startup of unnecessary services
op-batcher:
profiles: [disabled]
op-proposer:
profiles: [disabled]
message-relayer:
profiles: [disabled]
verse-verifier:
profiles: [disabled]
If you want to synchronize from the origin node, you need to add P2P static node configuration. First, check the PeerID of the origin node.
# Note: Run on the origin node
docker-compose exec op-node sh -c 'op-node p2p priv2id < /data/p2p_priv.txt'
# Output Example
16Uiu2HAmNfDjrE8y3mSojgRR3anDQ56mwwg8fm9YmZFrNYTTRrxu
Add the P2P address of the origin node to the replica node's docker-compose.override.yml as the environment variable OP_NODE_P2P_STATIC
. The P2P address is in the Multiaddr format, so it should be written as /ip4/<IP>/tcp/<Port>/p2p/<PeerID>
.
services:
op-node:
environment:
OP_NODE_SEQUENCER_ENABLED: 'false'
OP_NODE_P2P_STATIC: /ip4/192.168.0.1/tcp/9222/p2p/16Uiu2HAmNfDjrE8y3mSojgRR3anDQ56mwwg8fm9YmZFrNYTTRrxu # like this
If you want to use host names instead of IP addresses, replace ip4
with dns
. For example: /dns/origin.example.com/tcp/9222/p2p/16Uiu2HAmNfDjrE8y3mSojgRR3anDQ56mwwg8fm9YmZFrNYTTRrxu
5. Start services
Start op-geth and op-node services.
docker-compose up -d
6. Confirm synchronization
After setup the replica node, please confirm status of synchronization.
Confirm the Genesis Block
Compare hash and stateRoot of the Genesis Block(number=0) between the origin node and the replica node.
curl http://<address of the origin node and the replica node>:8545/ \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0", "method":"eth_getBlockByNumber", "params":["0x0", false], "id":1}' \
| jq '.result | { number, hash, stateRoot }'
# Output
{
"number": "0x0",
"hash": "0x...",
"stateRoot": "0x..."
}
Confirm the Latest Block
Compare the latest block of the replica node with the block of the same number from the origin node.
Get the latest block of the replica node.
curl http://<address of the replica node>:8545/ \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0", "method":"eth_getBlockByNumber", "params":["latest", false], "id":1}' \
| jq '.result | { number, hash, stateRoot }'
# Output
{
"number": "0x...",
"hash": "0x...",
"stateRoot": "0x..."
}
Get the same block of the origin node.
curl http://<address of the origin node>:8545/ \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0", "method":"eth_getBlockByNumber", "params":["<Latest block of the replica node>", false], "id":1}' \
| jq '.result | { number, hash, stateRoot }'
# Output
{
"number": "0x...",
"hash": "0x...",
"stateRoot": "0x..."
}
Promoting Replica node
The replica node can be promoted to new origin node.
1. Check status of nodes
First, check the following status of the old origin node and the replica node.
- Fully synchronized up to the latest block.
[!NOTE] When promoting a replica node, the replica node and the old origin node must be in fully synchronization to the latest block. Therefore, configure fast replication via P2P with the origin node.
- The contents of the
.env
file match. - Files in the
assets
directory match. - The contents of the
docker-compose.yml
file match.
2. Stop origin node
Stop all services on the origin node.
docker-compose down
[!CAUTION] Be sure to stop the old origin node. Problems may occur if multiple nodes are running at the same time.
3. Delete docker-compose.override.yml
Delete docker-compose.override.yml
on the replica node.
rm docker-compose.override.yml
4. Restart replica node
Restart the services on the replica node.
docker-compose down
docker-compose up -d