#12 Peer Discovery
Rendezvous를 이용해 P2P 네트워크 구축
이번 스텝에서는 Rendezvous(랑데부)를 사용해서 P2P 네트워크에서 peer 노드를 찾아 네트워크에 접속할 수 있도록 할 것입니다. 프로그램이 처음 네트워크에 접속하는 것을 bootstrapping이라고 부릅니다.
Bootstrap을 하기위해 네트워크에 참여하고 있는 peer node의 IP 주소를 알아와야합니다. 이를 Peer Discovery 라고 부릅니다. Peer Discovery를 위한 방법은 여러가지가 있습니다. 비트코인은 아주 초기에 IRC에 의존하여 Peer 정보를 공유하여 모든 노드가 공유된 Peer 노드에 접속했습니다. 지금의 비트코인 클라이언트는 DNS seed를 이용하여 peer discovory를 합니다. 자세한 내용은 네트워크 문서를 참고하길 바랍니다.
우리는 rendezvous 방법을 이용해 Peer Discovery를 구현할 것입니다. (참고로 이더리움에서 local network를 구축할 때 이 rendezvous 방법이 쓰입니다.)
구현 할 것
이 파트에서는 크게 두가지의 기능을 구현할 것입니다.
랑데뷰 방식 Peer discovery를 진행하여 P2P 네트워크에 접속할 수 있도록 합니다.
Peer의 정보를 영구적으로 저장하여 다음 bootstrapping 시에 peer discovery를 하지 않고도 네트워크에 접속할 수 있도록 합니다.
기타 코드 수정 내역은 아래와 같습니다.
Genesis 블록을 하드코딩하여 새로 참여하는 노드가 통신을 하지 않고도 Genesis 블록을 가질 수 있게 되었습니다.
Send를 호출하기 위해 유통되는 코인이 필요하므로 임시적으로 mint 함수를 구현하여 코인을 받을 수 있도록 하였습니다.
우선 구현해야할 Rendezvous 방식이 어떻게 동작하는 지와 노드가 시작할 때 어떤 플로우를 따라가는 지 살펴보고 구현을 시작하도록 하겠습니다.
network/network.go
먼저 network 코드의 가장 중심인 StartHost 함수부터 보도록 하겠습니다. StartHost는 P2P 호스트를 만들고 네트워크의 어떠한 한 Peer와 연결하는 것이 목적입니다. Peer 하나만 연결하면 해당 피어에서 주는 정보들로 더 많은 피어와 연결할 수 있습니다.
Peer DB에 저장되어 있는 Peer들에게 먼저 접속합니다. 만약 연결된다면 Peer Discovery는 진행하지 않습니다.
Peer DB의 Peer들에게 접속이 실패했다면 랑데뷰 방식으로 Peer Discovery 후 연결합니다.
StartHost 코드 마지막에 부르는 connectToKnownPeer 함수와 peerDiscovery 함수 구현을 살펴보겠습니다.
또한 이제 중앙 노드는 없기 때문에 HandleTx함수에서 중앙 노드관련 구문을 삭제해주세요.
이외에도 SendData 함수에서 연결되지않는 노드를 Peer DB에서 삭제하는 등의 수정사항이 있습니다. 자세한 수정사항은 12 branch에 가서 확인해주세요.
network/peers.go
Peer의 정보를 저장하는 Peer 데이터베이스 코드를 구현하겠습니다. 전반적인 구조는 blockchain과 거의 동일합니다. Peer ID를 key값으로 하고 AddrInfo를 벨류로 합니다.
cli/cli.go
크게 변한 코드는 없습니다. 임시로 mint 함수를 추가합니다.
실행
지갑을 만들고 rendezvous 문자열을 "tuto"로 하여 P2P 호스트를 실행하겠습니다.

다른 터미널을 열어서 NODE_ID를 3001로 하여 호스트를 실행해봅시다.
Bootstrap노드에 정보가 아직 전파 되지 않아 접속이 안될 수도 있습니다. 잠시 시간을 두고 다시 커맨드를 실행하면 접속이 될 것입니다.
접속이 된 것을 확인하면 3001번 노드의 접속을 끊고(ctrl-c) 블록을 추가한 후 다시 접속합니다.

새로 추가된 블록을 3000번 노드로 전송하는 것을 확인할 수 있습니다.
여기 까지의 구현은 https://github.com/siisee11/golang-blockchain 의 step12 브랜치에 있습니다 .
Last updated: May 21, 2021
Last updated
Was this helpful?