don't stop believing

테스트 네트워크 만들어보기 (by bootnode) 본문

Ethereum

테스트 네트워크 만들어보기 (by bootnode)

Tongchun 2018. 9. 27. 10:51

여러대로 연결된 테스트 네트워크를 만들어 보겠습니다.

테스트 네트워크(클러스터)를 만드는 방법은 3가지 입니다. bootnode(bootstrap)를 이용하는 방법과 geth에서 admin.addPeer() 명령을 사용하는 방법, 그리고 static-nodes.json 파일을 이용하는 방법입니다.


보통 소규모 테스트 네트워크에서는 admin.addPeer() 명령을 사용하지만 이번에는 bootnode를 사용해 보겠습니다.


순서는 아래와 같습니다.

1. 첫 번째 PC에서 새로운 node(테스트 넷)를 생성합니다.

2. 두 번째 PC에서 bootnode를 실행합니다.

3. 첫 번째 PC의 node가 bootnode에 연결합니다.

4. 세 번째 PC에서 bootnode에 연결합니다.

5. 네 번째 PC에서 bootnode에 연결합니다.


먼저 첫 번째 PC에서 새로운 node를 만들겠습니다.

새로운 네트워크를 생성하려면 genesis.json 파일부터 만들어야 합니다. 저는 아래와 같이 생성했습니다.

{
	"config": {
		"chainId": 12,
		"homesteadBlock": 0,
		"eip155Block": 0,
		"eip158Block": 0
	},
	"alloc"			: {},
	"coinbase"		: "0x0000000000000000000000000000000000000000",
	"difficulty"	: "0x20000",
	"extraData"		: "",
	"gasLimit"		: "0x2fefd8",
	"nonce"			: "0x0000000000000042",
	"mixhash"		: "0x0000000000000000000000000000000000000000000000000000000000000000",
	"parentHash"	: "0x0000000000000000000000000000000000000000000000000000000000000000",
	"timestamp"		: "0x00"
}

생성된 경로는 /Users/tongchunkim/Documents/Test_Ethereum/data_nglenet/genesis.json 입니다.


genesis.json 파일로 geth 초기화를 해줍니다.

geth --datadir /Users/tongchunkim/Documents/Test_Ethereum/data_nglenet init /Users/tongchunkim/Documents/Test_Ethereum/data_nglenet/genesis.json

$ geth --datadir /Users/tongchunkim/Documents/Test_Ethereum/data_nglenet init /Users/tongchunkim/Documents/Test_Ethereum/data_nglenet/genesis.json
INFO [09-27|10:30:45.049] Maximum peer count                       ETH=25 LES=0 total=25
INFO [09-27|10:30:45.058] Allocated cache and file handles         database=/Users/tongchunkim/Documents/Test_Ethereum/data_nglenet/geth/chaindata cache=16 handles=16
INFO [09-27|10:30:45.065] Writing custom genesis block 
INFO [09-27|10:30:45.066] Persisted trie from memory database      nodes=0 size=0.00B time=16.697µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [09-27|10:30:45.066] Successfully wrote genesis state         database=chaindata                                                              hash=5e1fc7…d790e0
INFO [09-27|10:30:45.066] Allocated cache and file handles         database=/Users/tongchunkim/Documents/Test_Ethereum/data_nglenet/geth/lightchaindata cache=16 handles=16
INFO [09-27|10:30:45.068] Writing custom genesis block 
INFO [09-27|10:30:45.068] Persisted trie from memory database      nodes=0 size=0.00B time=1.87µs   gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [09-27|10:30:45.069] Successfully wrote genesis state         database=lightchaindata                                                              hash=5e1fc7…d790e0


Geth를 초기화 했다면 실행할 차례입니다.


아래 명령으로 실행해 줍니다. 저는 포트를 30303으로 지정했습니다.

geth --networkid 12 --datadir /Users/tongchunkim/Documents/Test_Ethereum/data_nglenet --port 30303 console 2>> /Users/tongchunkim/Documents/Test_Ethereum/data_nglenet/geth.log

$ geth --networkid 12 --datadir /Users/tongchunkim/Documents/Test_Ethereum/data_nglenet --port 30303 console 2>> /Users/tongchunkim/Documents/Test_Ethereum/data_nglenet/geth.log
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.14-stable/darwin-amd64/go1.10.3
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> 

node를 실행했다면 account를 만들어 줍니다. (비번을 'ngle'로 해줬습니다.)

> personal.newAccount()
Passphrase: 
Repeat passphrase: 
"0x2a15ea92c53b856ac952408f30d3d08760b84b8a"

모든 node에는 개별 node에 대한 식별자가 있습니다. enode URL인데요, admin.nodeInfo.enode 명령으로 확인할 수 있습니다.

> admin.nodeInfo.enode
"enode://abd98c3cc43618faa96d4902d786348c07e548b3050a14afc780a3e39821cc4b7f9cf9d5886ff2053923c5d74e547e65850dbb624f73a4c1df442a6eefce5b68@59.13.192.250:30303"

테스트 네트워크에 연결된 peer가 있는지도 확인해 보겠습니다.

> net.peerCount
0
> admin.peers
[]

현재 연결된 peer는 없습니다.


geth가 사용하는 네트워크 정보도 한번 확인하고 갑니다. geth가 실행된 상태에서 터미널 창을 새로 열고 netstat로 geth가 사용하는 포트와 프로토콜을 확인합니다.

macOS라면 아래 명령으로 열려있는 네트워크 포트 정보를 확인할 수 있습니다.

$ sudo lsof -PiTCP -sTCP:LISTEN | grep geth
geth      2072 tongchunkim   21u  IPv6 0x567434b33741e1ab      0t0  TCP *:30303 (LISTEN)

TPC로 30303이 열려 있는 것을 확인할 수 있습니다.


이제 두 번째 PC에서 bootnode를 실행하겠습니다.

bootnode를 실행시키기 위해 key 파일을 생성해야 합니다. 아래와 같이 생성하고 키 파일을 확인해 보겠습니다.

$ bootnode -genkey bootnode.key
$ cat bootnode.key 
c5b38cb53251e8e6c1d4f01354f2114aa224375da59ff6fed8fbc54fbe01e703

생성한 key 파일을 이용해 bootnode를 실행합니다. 실행할 때 자세한 로그를 확인하고 싶다면 -verbosity 옵션을 줄 수 있습니다.

$ bootnode -nodekey bootnode.key -verbosity 9 -addr 10.10.1.168:30301
INFO [09-27|04:30:03.270] UDP listener up                          self=enode://7f84e8658db54f1448d69f4b29e91f2764290f527496361775f411d4e99d61c865fc9c5b7706440ab8d848ccf8d2e66c97ac754944799915e6d3c4b07f88600b@10.10.1.168:30301

내부 네트워크에서 연결하기 위해 -addr 플래그에 IP와 기본 bootnode port인 30301을 지정했습니다.

bootnode도 enode가 있습니다. geth를 실행할 때 bootnode에 연결하려면 bootnode의 enode를 알아야 합니다.

enode://7f84e8658db54f1448d69f4b29e91f2764290f527496361775f411d4e99d61c865fc9c5b7706440ab8d848ccf8d2e66c97ac754944799915e6d3c4b07f88600b@10.10.1.168:30301


bootnode가 사용하는 네트워크 포트와 프로토콜을 확인해 보겠습니다.

Linux(CentOS)라면 아래 명령을 확인할 수 있습니다.

$ sudo netstat -anp | grep bootnode
udp        0      0 10.10.1.168:30301       0.0.0.0:*                           9278/bootnode

udp 프로토콜로 30301이 열려있는 것을 확인할 수 있습니다.


이제 다시 첫 번째 PC에서 geth를 다시 실행 시킵니다. 이때 bootnode와 연결하기 위해 --bootnodes 플래그를 주고 값으로는 아래와 같이 설정합니다.

--bootnodes <bootnode의 enode>@<bootnode ip>:<연결하려는 node의 tcp port>?discport=<bootnode의 udp port>


그래서 geth 실행 플래그는 아래와 같습니다.

geth --networkid 12 --bootnodes "enode://7f84e8658db54f1448d69f4b29e91f2764290f527496361775f411d4e99d61c865fc9c5b7706440ab8d848ccf8d2e66c97ac754944799915e6d3c4b07f88600b@10.10.1.168:30303?discport=30301" --datadir /Users/tongchunkim/Documents/Test_Ethereum/data_nglenet --port 30303 --verbosity 6 console 2>> /Users/tongchunkim/Documents/Test_Ethereum/data_nglenet/geth.log


위와 같이 geth를 실행 시키고 bootnode가 실행된 창을 확인합니다.

아래와 같이 ping pong이 실행되는 것을 확인할 수 있습니다. bootnode가 연결된 node가 살아 있는지 지속적으로 ping, pong으로 확인하게 됩니다.

TRACE[09-27|05:24:26.751] >> PING/v4                               addr=10.10.0.145:30303    err=nil
TRACE[09-27|05:24:26.755] << PONG/v4                               addr=10.10.0.145:30303    err=nil
DEBUG[09-27|05:24:26.755] Revalidated node                         b=16 id=567503d1eaabdf4c
TRACE[09-27|05:24:35.862] >> PING/v4                               addr=165.227.10.121:30391 err=nil
TRACE[09-27|05:24:36.019] << PONG/v4                               addr=165.227.10.121:30391 err=nil
DEBUG[09-27|05:24:36.019] Revalidated node                         b=6  id=ae847b91e091ba6d


연결된 node에서 net.peerCount와 admin.peers를 확인해 보면 아래와 같이 아직 추가된 peer가 없는 것을 확인할 수 있습니다.

> net.peerCount
0
> admin.peers
[]


이제 세 번째 PC에서 geth를 실행해 보겠습니다. 세 번째 PC는 windows 입니다.

genesis.json 파일을 동일하게 생성하고 초기화 해줍니다.


geth --datadir D:\Test_Ethereum\data_nglenet init D:\Test_Ethereum\data_nglenet\genesis.json


geth를 실행해 봅니다.

geth --networkid 12 --datadir D:\Test_Ethereum\data_nglenet --port 30304 console 2>> D:\Test_Ethereum\data_nglenet\geth.log

C:\Users\tongchun>geth --networkid 12 --datadir D:\Test_Ethereum\data_nglenet --port 30304 console 2>> D:\Test_Ethereum\data_nglenet\geth.log
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.16-stable-477eb093/windows-amd64/go1.11
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

>

geth가 잘 실행되네요. 종료하고 --bootnodes 플래그를 추가하고 다시 실행해 봅니다.

geth --networkid 12 --bootnodes "enode://7f84e8658db54f1448d69f4b29e91f2764290f527496361775f411d4e99d61c865fc9c5b7706440ab8d848ccf8d2e66c97ac754944799915e6d3c4b07f88600b@10.10.1.168:30304?discport=30301" --datadir D:\Test_Ethereum\data_nglenet --port 30304 --verbosity 6 console 2>> D:\Test_Ethereum\data_nglenet\geth.log


연결이 되었다면 bootnode 창을 확인합니다.

TRACE[09-27|05:43:00.136] >> NEIGHBORS/v4                          addr=10.10.0.129:30304     err=nil
TRACE[09-27|05:43:00.137] >> NEIGHBORS/v4                          addr=10.10.0.129:30304     err=nil
TRACE[09-27|05:43:00.137] << FINDNODE/v4                           addr=10.10.0.129:30304     err=nil

이미 연결되어 배포가 되고 있습니다.

첫 번째 PC에서 net.peerCount와 admin.peers를 다시 확인해 보겠습니다.

> net.peerCount
1
> admin.peers
[{
    caps: ["eth/63"],
    id: "d540f7d54e1c10b31aed0756d062cdbc88f7b98dfbda0a19ea92460b1cefd02d7a6e7881b0028a92ed2afcb922ab81a18c616aff28ccde8f8084c7df169aa4f6",
    name: "Geth/v1.8.16-stable-477eb093/windows-amd64/go1.11",
    network: {
      inbound: true,
      localAddress: "10.10.0.145:30303",
      remoteAddress: "10.10.0.129:52560",
      static: false,
      trusted: false
    },
    protocols: {
      eth: {
        difficulty: 131072,
        head: "0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0",
        version: 63
      }
    }
}]

연결이 잘 되고 있습니다.


여기까지해서 bootnode를 이용한 테스트 네트워크 정리를 마치려고 했으나....

bootnode가 계속 실행되고 있는 상태에서 첫 번째와 두 번째 PC의 node를 종료했다 다시 연결하려고 하니 잘 되지 않고 있습니다.


그리고 bootnode에도 첫 번째, 세 번째 PC가 아닌 이상한 ip들과 ping/pong 하고 있습니다.

TRACE[09-27|05:51:35.323] >> PING/v4                               addr=51.15.110.3:30303     err=nil
TRACE[09-27|05:51:35.606] << PONG/v4                               addr=51.15.110.3:30303     err=nil
DEBUG[09-27|05:51:35.606] Revalidated node                         b=16 id=22123fc0050998c2
TRACE[09-27|05:51:42.587] >> PING/v4                               addr=35.158.140.180:30303  err=nil
TRACE[09-27|05:51:42.886] << PONG/v4                               addr=35.158.140.180:30303  err=nil
DEBUG[09-27|05:51:42.886] Revalidated node                         b=10 id=ad3d303cfeb5a2cf
TRACE[09-27|05:51:50.836] >> PING/v4                               addr=45.32.206.68:30303    err=nil
TRACE[09-27|05:51:51.008] << PONG/v4                               addr=45.32.206.68:30303    err=nil
DEBUG[09-27|05:51:51.009] Revalidated node                         b=9  id=af079abb6b63574f
TRACE[09-27|05:51:59.940] >> PING/v4                               addr=45.32.206.68:30303    err=nil
TRACE[09-27|05:52:00.114] << PONG/v4                               addr=45.32.206.68:30303    err=nil
DEBUG[09-27|05:52:00.114] Revalidated node                         b=9  id=af079abb6b63574f
TRACE[09-27|05:52:01.923] >> PING/v4                               addr=178.128.222.4:21212   err=nil
TRACE[09-27|05:52:02.019] << PONG/v4                               addr=178.128.222.4:21212   err=nil
DEBUG[09-27|05:52:02.019] Revalidated node                         b=6  id=ae90f38a443c11f6

첫 번째와 세 번째 PC에서 admin.peers 명령을 확인하면 서로 연결하지 못하고 이상한 IP들이 간혹 handshake까지 하고 끊어지고 있습니다.

> admin.peers
[]
> admin.peers
[]
> admin.peers
[]
> admin.peers
[]
> admin.peers
[{
    caps: ["eth/62", "eth/63"],
    id: "903bd41ae59132dc18e87cbbb13fa1950102128b09a674ee2cc3318619ebf6727ca1a6ae6f075d92cd8cf26f436be0caebea42d96aef271d0d6d0d06c30e0a79",
    name: "Geth/v1.5.9-stable-a07539fb/linux/go1.7.4",
    network: {
      inbound: false,
      localAddress: "10.10.0.145:62855",
      remoteAddress: "13.69.129.93:30303",
      static: false,
      trusted: false
    },
    protocols: {
      eth: "handshake"
    }
}]

이건 어떤 현상인지.. 제대로 bootnode와의 연결 설정이 된 것인지 확인 후에 추가 posting 해야 할 것 같습니다.

첫 번째, 세 번째 PC를 다시 초기화 하고 연결하면 잘 됩니다. 그러나 종료 후 다시 연결하려면 동일한 증상을 보이네요..


일단은 여기까지 하겠습니다.

Comments