libp2p는 p2p 네트워크 관련된 모듈입니다. 네트워크는 오래된 기술인 만큼 많이 발전하여 통신을 위한 프로토콜이 정말 많습니다. IPFS를 개발할때 모든 머신들이 서로 통신을 해야하는데 노드마다 사용하는 통신이나 호환성등이 다르기 때문에 이를 위해 libp2p를 개발하였다고 합니다. libp2p는 이런 네트워킹 프로토콜들을 추상화해주느데 의미를 갖는다고 생각합니다. 또, p2p 방식의 네트워킹을 위한 라이브러리를 제공해줍니다. 아래는 공식 홈페이지입니다.
위의 go-libp2p 깃허브에 가면 libp2p를 사용한 chat이나 proxy server등 예시들이 있으니 참고해서 공부하시면 되리라 생각됩니다.
구현 할 것
일단 p2p 네트워크 구현의 첫번째 단계로, 기존의 네트워크를 libp2p를 사용하도록 바꾸도록 하겠습니다. 통신 내용 (HandleXXX, SendXXX)는 그대로 유지하고 실제로 네트워크 통신하는 코드만 수정합니다.
network/network.go
기존의 net을 사용하던 네트워크 코드를 삭제하고 (StartNode, SendData) 새로 LibP2P를 이용한 코드를 삽입합니다.
"send" 커맨드에서 사용할 SendTxOnce 함수도 추가로 구현합니다. (이전 코드와 호환을 위해 추가되었지만, 코드 미용상 문제가 있으니 조만간 없어질 것입니다.)
Global variable 부분과 import 부분도 수정해줍니다.
cli/cli.go
cli 에서 startnode커맨드를 삭제하고 startp2p 커맨드를 추가하겠습니다. 역시 Flag나 Cmd에 대한 코드는 생략하겠습니다.
send 함수에서 SendTx는 아직 host를 생성하지 않았기 때문에 사용하지 못하므로, SendTxOnce 함수를 사용합니다. 중앙 노드의 peerID가 "localhost:3000"처럼 고정되어 있지 않기 때문에 메세지를 보낼 대상인 targetPeer로 인자로 추가해야합니다. (아래 Cmd 인자 추가도 잊지 마세요.)
Test
먼저, 사용한 go-libp2p 모듈을 다운로드 받아야합니다.
동작은 커맨드가 살짝 다른 것 말고는 #10과 같습니다.
대신, 이번 파트에서는 같은 LAN (192.168.0.x)의 다른 컴퓨터끼리도 통신이 가능합니다.
간단하게 다시 진행해보겠습니다. 일단 3000번 노드에서 지갑과 블록체인을 만들고 초기 블록체인을 복사한 후 send를 진행합니다.
다음으로 3000번 노드의 서버를 구동하고, 하나의 터미널을 더 켜서 NODE_ID 3002를 부여하고 minter옵션을 주어 서버를 구동합니다.
3001번 노드에서 send 트랜잭션 두개를 발생시키면 다른 서버가 해당 트랜잭션을 받고 3002번 노드에서는 minting이 발생함을 볼 수 있다.