RChain 节点运行(Docker)

From RChain Developer Resource

RChain节点的运行可以通过本地环境直接运行或通过Docker的方式运行,本文主要讲述Docker运行(推荐)的方式,客户端运行方式请参考:RChain 节点运行(客户端)

Docker安装与配置[edit | edit source]

Docker的安装与配置可以参考官方教程中文教程

RNode 版本说明[edit | edit source]

RNode的docker镜像可以在rchain/rnode找到,但无需手动下载,在运行时指定对应的版本,即可从docker仓库自行下载。

本文以RNode v0.12.4为例讲述RNode的运行。

命令格式[edit | edit source]

下面简单描述下docker运行RNode时的命令格式,以此命令为例:

docker run --name rnode0 --network rnode-net rchain/rnode:latest run -s

docker run --name rnode0 --network rnode-net这一部分是docker自身的命令,rchain/rnode:latest run -s这部分是RNode自己的命令,因此以后在添加新的参数时,也要将docker的命令放在rchain/rnode之前,RNode的命令放在rchain/rnode:latest run之后。

命令的参数将在下面逐一说明。

帮助信息[edit | edit source]

通过以下命令可以查看所有参数的帮助信息:

docker run --name rnode0 rchain/rnode:v0.12.4 --help

命令说明:

docker
调用docker主程序
run
运行一个docker容器
--name rnode0
给容器指定一个名称,此处为rnode0,名称之间不能相同,因此,如果您需要运行另一个节点,请命名为新的容器,比如rnode1
rchain/rnode:v0.12.4
镜像的名称和版本,之间用:分开
--help
rnode的帮助命令

说明:当第一次运行这个命令时,docker会将容器的状态保存起来,因此再运行相同命令时,会出现如下错误:

docker: Error response from daemon: Conflict. The container name "/rnode0" is already in use by container "0f80db510c2fc093a538bcfe7377c7e8bfcf8d83b2cbfb8037d138b083d326c9". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.

错误信息表示已经有相同rnode0名称的容器存在。解决办法是在运行前删除同名的容器

docker rm rnode0

但需要注意的是,如果你之前启动的容器已经是生产状态的容器,不推荐如此做,只需要通过以下命令来管理容器:

# 关闭容器
docker stop rnode0
# 启动容器
docker start rnode0

仅在本机运行一个节点[edit | edit source]

如果仅需要在本机运行一个节点,不连接网络,直接运行即可:

docker run --name rnode0 rchain/rnode:v0.12.4 run -s

其中:

-s
启动一个独立的节点

节点运行时默认是将数据放置在容器内部,如果容器被删除,数据会丢失,因此在生产环境下,建议将数据映射出来,例如以下命令将数据存放在$HOME/rnode_data:

docker run --name rnode0 -v $HOME/rnode_data:/var/lib/rnode rchain/rnode:v0.12.4 run -s

启动调试[edit | edit source]

建立网络[edit | edit source]

以下内容均需要开启2个以上的节点,docker容器内的节点之间通信需要在同一网络下,通过如下命令建立网络,并在启动节点时指定该网络:

docker network create rnode-net

rnode-net即为网络名(可以随意设定)。

开启第1个节点[edit | edit source]

docker run --name rnode0 --network rnode-net rchain/rnode:v0.12.4 run -s

其中:

--network rnode-net
为指定的网络名称,下面所有的命令中均会包含此参数

REPL交互式调试[edit | edit source]

开启第1个节点后,可以再开启一个REPL(Read–eval–print loop)窗口供交互式执行rholang代码:

docker run -it --rm --name rnode-repl --network rnode-net rchain/rnode:v0.12.4 --grpc-host rnode0 --grpc-port 40402 repl

其中:

-it
是docker的命令参数,指定以交互方式运行容器,这样可以直接运行rholang代码
--rm
是指在启动之前删除之前已经存在相同名称的容器。因为REPL窗口没有数据保存,而docker每次运行后都会保存状态,再次启动直接删除是没有问题,如果不删除直接启动会报错。
--name rnode-repl
指定该容器的名称为rnode-repl
--network rnode-net
进入网络rnode-net
--grpc-host rnode0
开放grpc API的容器的主机名,此处为第1个节点的名称rnode0即为指定的主机名
--grpc-port 40402
开放grpc API的容器的端口
repl
运行RNode repl

使用了上述命令后,你会看到以下命令提示符:

rholang $ 

输入new stdout(`rho:io:stdout`) in { stdout!("Hello RChain!") }后,可以当前窗口看到类似以下输出:

Deployment cost: Cost(314,)
Storage Contents:
@{42}!("Hello!") |
for( @{x0}, @{x1}, @{x2} <= @{Unforgeable(0x12)} ) {
  Nil
} |
for( @{x0}, @{x1} <= @{Unforgeable(0x06)} ) {
  Nil
} |
for( @{x0} <= @{Unforgeable(0x00)} ) {
  Nil
} |
for( @{x0}, @{x1} <= @{Unforgeable(0x01)} ) {
  Nil
} |
for( @{x0}, @{x1} <= @{Unforgeable(0x07)} ) {
  Nil
} |
for( @{x0}, @{x1}, @{x2}, @{x3} <= @{Unforgeable(0x08)} ) {
  Nil
} |
for( @{x0}, @{x1}, @{x2} <= @{Unforgeable(0x0c)} ) {
  Nil
} |
for( @{x0}, @{x1} <= @{Unforgeable(0x05)} ) {
  Nil
} |
for( @{x0} <= @{Unforgeable(0x0a)} ) {
  Nil
} |
for( @{x0} <= @{Unforgeable(0x0b)} ) {
  Nil
} |
for( @{x0} <= @{Unforgeable(0x02)} ) {
  Nil
} |
for( @{x0}, @{x1} <= @{Unforgeable(0x03)} ) {
  Nil
} |
for( @{x0}, @{x1}, @{x2}, @{x3} <= @{Unforgeable(0x04)} ) {
  Nil
} |
for( @{x0}, @{x1}, @{x2} <= @{Unforgeable(0x11)} ) {
  Nil
} |
for( @{x0}, @{x1}, @{x2} <= @{Unforgeable(0x0d)} ) {
  Nil
}

在另外打开的本地节点可以看到以下内容:

Evaluating:
new x0 in {
  x0!("Hello RChain!")
}
"Hello RChain!"

表明rholang代码执行成功。

执行rho文件[edit | edit source]

REPL窗口只能将代码写在一行,复杂一些的代码缩在一行不容易调试,可以将rholang代码写在文件中,通过以下命令执行:

docker run -it --rm --name rnode-repl --network rnode-net -v ~/rholang:/var/rholang rchain/rnode:v0.12.4 --grpc-host rnode0 --grpc-port 40402 eval /var/rholang/test.rho

执行同样的代码也会和REPL交互式调试的输出相同。

其中:

-v ~/rholang:/var/rholang
是将本地一个文件夹(~/rholang)映射至docker容器内部的文件夹(/var/rholang),这样在执行rho文件时,会在容器的文件夹内(/var/rhoalng)找相应的文件test.rho,实际上就是~/rholang/test.rho
eval /var/rholang/test.rho
执行rho文件

建立本地节点网络[edit | edit source]

启动多个节点,多点之间会互相发现以组成网络。

因为RNode在监听端口时,默认是会探测外网IP来进行通讯的,因此,在建立节点网络就需要将容器内的端口映射到宿主机,并确保端口之间不冲突,这样节点之间就能互相发现了。

启动第一个节点[edit | edit source]

首先,启动第1个节点:

docker run --name rnode0 -p 40400-40405:40400-40405/tcp -v $HOME/rnode_data:/var/lib/rnode rchain/rnode:v0.12.4 run -s

其中:

-p 40400-40405:40400-40405/tcp
表示映射容器内40400-40405的端口至宿主相相同的端口

第1个节点使用了数据文件夹$HOME/rnode_data,并相继使用了40400 ~ 40405这6个端口。

启动第2个节点[edit | edit source]

启动其他节点要避开已经使用的数据文件夹和端口

通过

--discovery-port 40410 --api-port-grpc-external 40411 --api-port-grpc-internal 40412 --api-port-http 40413 --protocol-port 40414 --api-port-admin-http 40415

依次修改端口40400 ~ 40405至使用40410 ~ 40415。

另外,因为要与第1个节点连接,因此要指定第1个节点的地址,通过--bootstrap "rnode://link"的方式指定节点1。通过第1个节点的输出,可以看到类似以下的内容:

11:56:34.965 [INFO ] [node-runner-27      ] [c.r.n.r.ServersInstances$    ] - Listening for traffic on rnode://b14565edf242cc3b28d97d83ee8e3258bc71616d@221.196.89.92?protocol=40400&discovery=40404.

其中rnode://b14565edf242cc3b28d97d83ee8e3258bc71616d@221.196.89.92?protocol=40400&discovery=40404即是第1个节点的地址。其中的221.196.89.92是客户端判断出的外网的ip。

我们启动第2个节点:

docker run --name rnode1 -p 40410-40415:40410-40415/tcp -v $HOME/rnode_data1:/var/lib/rnode rchain/rnode:v0.12.4 run  --discovery-port 40410 --api-port-grpc-external 40411 --api-port-grpc-internal 40412 --api-port-http 40413 --protocol-port 40414 --api-port-admin-http 40415 --bootstrap "rnode://b14565edf242cc3b28d97d83ee8e3258bc71616d@221.196.89.92?protocol=40400&discovery=40404"

启动后,在两个节点的日志输出出都可以看到如下内容,表示已经连接上:

14:52:50.604 [INFO ] [node-runner-26      ] [coop.rchain.comm.rp.Connect$ ] - Peers: 1

在运行REPL或eval时,可以选择不同的节点,下面即是选择在第2个节点执行rholang代码:

docker run -it --rm --name rnode-repl rchain/rnode:v0.12.4 --grpc-host 221.196.89.92 --grpc-port 40412 repl

启动更多节点[edit | edit source]

与上述相同原理,可以启动更多节点,启动时--bootstrap只需要使用第1个节点的链接即可,它们是可以互相发现的。

注意更改数据目录和端口:

docker run --name rnode2 -p 40420-40425:40420-40425/tcp -v $HOME/rnode_data2:/var/lib/rnode rchain/rnode:v0.12.4 run  --discovery-port 40420 --api-port-grpc-external 40421 --api-port-grpc-internal 40422 --api-port-http 40423 --protocol-port 40424 --api-port-admin-http 40425 --bootstrap "rnode://b14565edf242cc3b28d97d83ee8e3258bc71616d@221.196.89.92?protocol=40400&discovery=40404"

会看到peers变成了2.

启动更多节点以此类推。

连接公共网络[edit | edit source]

Warning icon blue.png : RChain还未开放外部验证节点,此处现在只讨论只读节点的建立

Warning icon.png : 节点之间需要互通,因此确保你有公网ip,且该电脑已经被映射至公网或连接的路由器支持UPNP功能。

本处描述连接testnet的方法,其他公共网络的方式与此类似。

连接公共网络至少要提供以下几个参数

  • --bootstrap:连接网络时需要连接至的启动节点,连接上启动节点后,其余的节点可以会自动发现。
  • --network-id: 网络的id

寻找bootstrap[edit | edit source]

连接公共网络需要知道网络中一个节点的链接,现阶段,可以在RNode client testing page找到。打开上述链接,在RChain Network selector下面的下拉框中,选择网络,现在(20222-01-18)可以看到有以下几组网络:

  • Local Network:表示本地网络,该页面是一个具有转账、执行rholang代码功能的页面,连接本地网络可以在本地网络执行上述功能。
  • RChain testing network (leaderless block-merge):无领导块合并的测试网络,此分组可能在块合并上线后被移除
  • RChain testing network (block-merge):有领导块合并的测试网络,此分组可能在块合并上线后被移除
  • RChain testing network:公共测试网络
  • RChain MAIN network:主网

选择RChain testing network下的任意一个节点,比如node0.testnet.rchain.coop,然后点击该下拉框紧拉status连接,会打开新页面并显示以下内容:

{"address":"rnode://f601833bb379882668d2aa7093162aa11deb3e22@node0.testnet.rchain.coop?protocol=40400&discovery=40404","version":"RChain Node 0.12.4 (f9ebcbd93ef308ca1175ccff7aeaca8a81da34cc)","peers":9,"nodes":46}

其中的rnode://f601833bb379882668d2aa7093162aa11deb3e22@node0.testnet.rchain.coop?protocol=40400&discovery=40404即是该节点的链接。

寻找network id[edit | edit source]

网络id是某一网络的标识,必须提供,最简单寻找你要连接的网络的id的方法是直接运行命令,比如

docker run -it --rm --name rnode-testnet -v ~/rnode-testnet:/var/lib/rnode -p 40400-40405:40400-40405/tcp rchain/rnode:v0.12.4 run --bootstrap "rnode://f601833bb379882668d2aa7093162aa11deb3e22@node0.testnet.rchain.coop?protocol=40400&discovery=40404"

在最后一行日志输出中可以看到类似内容:

Can't connect to peer rnode://f601833bb379882668d2aa7093162aa11deb3e22@node0.testnet.rchain.coop?protocol=40400&discovery=40404. Wrong network id 'testnet'. This node runs on network 'testnet210604'

该提示表示你要连接的网络是testnet210604,此处即是需要的network id

运行[edit | edit source]

使用以下命令运行:

docker run -it --rm --name rnode-testnet -v ~/rnode-testnet:/var/lib/rnode -p 40400-40405:40400-40405/tcp rchain/rnode:v0.12.4 run --bootstrap "rnode://f601833bb379882668d2aa7093162aa11deb3e22@node0.testnet.rchain.coop?protocol=40400&discovery=40404" --network-id testnet210604

如果不断出现以下内容,即正在下载历史块,表示连接正常:

08:29:06.072 [INFO ] [node-runner-24      ] [r.c.e.LfsTupleSpaceRequester$] - Sending StoreItemsRequest to bootstrap
08:29:12.475 [INFO ] [node-runner-23      ] [c.r.c.engine.Initializing    ] - Received StoreItems(history: 20000, data: 15459, start: [01:46e3c0fd e0:1c563b29 f2:e1d92572 69:7b85c305 --:c51df869], last: [02:46e3c0fd 0c:1d49420b d8:43101b42 d0:e3717bf7 --:2da339d8]) from rnode://f601833bb379882668d2aa7093162aa11deb3e22@node0.testnet.rchain.coop?protocol=40400&discovery=40404.
08:29:12.477 [INFO ] [node-runner-25      ] [r.c.e.LfsTupleSpaceRequester$] - Sending StoreItemsRequest to bootstrap
08:29:12.611 [INFO ] [node-runner-25      ] [r.c.e.LfsTupleSpaceRequester$] - Import history items [128.528612 ms]
08:29:12.655 [INFO ] [node-runner-28      ] [r.c.e.LfsTupleSpaceRequester$] - Import data items [172.758512 ms]
08:29:15.985 [INFO ] [node-runner-22      ] [c.r.c.engine.Initializing    ] - Received StoreItems(history: 20000, data: 15459, start: [01:46e3c0fd e0:1c563b29 f2:e1d92572 69:7b85c305 --:c51df869], last: [02:46e3c0fd 0c:1d49420b d8:43101b42 d0:e3717bf7 --:2da339d8]) from rnode://f601833bb379882668d2aa7093162aa11deb3e22@node0.testnet.rchain.coop?protocol=40400&discovery=40404.
08:29:16.512 [INFO ] [node-runner-27      ] [r.c.e.LfsTupleSpaceRequester$] - Validate received state items [4.029306493 sec]
08:29:43.650 [INFO ] [node-runner-24      ] [c.r.c.engine.Initializing    ] - Received StoreItems(history: 20000, data: 15430, start: [02:46e3c0fd 0c:1d49420b d8:43101b42 d0:e3717bf7 --:2da339d8], last: [02:46e3c0fd 38:1d49420b 7b:47462690 fc:f05d6046 --:f0baeee6]) from rnode://f601833bb379882668d2aa7093162aa11deb3e22@node0.testnet.rchain.coop?protocol=40400&discovery=40404.
08:29:43.651 [INFO ] [node-runner-24      ] [r.c.e.LfsTupleSpaceRequester$] - Sending StoreItemsRequest to bootstrap
08:29:44.149 [INFO ] [node-runner-25      ] [r.c.e.LfsTupleSpaceRequester$] - Import history items [489.11972 ms]
08:29:44.477 [INFO ] [node-runner-23      ] [r.c.e.LfsTupleSpaceRequester$] - Import data items [817.048447 ms]

测试[edit | edit source]

查看本地节点状态[edit | edit source]

打开[1],选择localhost:40403,然后点击下面的status,打开新页面后会显示:

{"address":"rnode://c678d707bafe382c29aa333be2f5325511bc25c5@221.196.89.92?protocol=40400&discovery=40404","version":"RChain Node 0.12.4 (f9ebcbd93ef308ca1175ccff7aeaca8a81da34cc)","peers":10,"nodes":45}

可以看到已经有很多小伙伴了。

可以通过RNode Client查看更多使用方法。

领取测试币[edit | edit source]

打开[2],选择node0.testnet.rchain.coop,然后点击上面的faucet,打开新页面后输入您的钱包地址,点击submit,等待一段时间后,在https://tgrospic.github.io/rnode-client-js-dev-test即可查询到余额。

通过本地节点查看余额[edit | edit source]

在本地节点下载完历史数据后,即可通过localhost:40403来查看余额。

如果点击check balance后,出现以下错误

Error: Could not execute exploratory deploy, casper instance was not available yet.

表示节点还未下载完历史数据,请等待