P2P Networking
탈중앙화 네트워크에서 P2P 레이어는 노드 간 연결과 데이터 교환을 담당합니다.
Midnight 노드는 Polkadot SDK의 Rust LibP2P 구현을 기반으로 합니다. 주요 구성 요소는 다음과 같습니다.
Discovery Mechanisms
탈중앙화 네트워크에 참여하려면 노드가 피어를 발견하고 연결해야 합니다. Midnight은 여러 피어 디스커버리 전략을 지원합니다:
Bootstrap Nodes
노드를 부트스트랩 노드라는 사전 정의된 피어 목록으로 구성할 수 있습니다. 이들은 네트워크 구성에 하드코딩된 ID와 주소입니다. 시작 시 노드는 이 신뢰할 수 있는 피어에 연결하여 네트워크에 참여하고 다른 피어 정보를 습득합니다.
mDNS (Multicast DNS)
로컬 네트워크 디스커버리를 위해 mDNS는 UDP broadcast를 사용하여 동일 LAN 내 피어를 탐색합니다. 개발 환경, 테스트넷, 또는 피어가 근거리에 있는 네트워크에 유용합니다. mDNS는 네트워크 설정에서 활성화 또는 비활성화할 수 있습니다.
Kademlia DHT (Random Walk)
하나 이상의 피어에 연결되면, 노드는 구성된 각 체인의 분산 해시 테이블(DHT)에서 Kademlia 기반 random walk를 수행합니다. FIND_NODE 쿼리를 보내 추가 피어를 발견하며, 시간이 지남에 따라 네트워크에 대한 더 완전한 뷰를 구축하여 연결성과 복원력을 향상시킵니다.
Connection Establishment
Transport Layer
노드 A(Alice)가 노드 B(Bob)의 주소를 알고 있어 연결하려는 경우, 다음 전송 프로토콜 중 하나를 사용하여 연결을 시작합니다:
- TCP/IP: 일반적인 IPv4 또는 IPv6 소켓 연결.
- WebSocket: TCP 위에 구축되며, WebSocket 프레이밍을 통해 브라우저 호환 또는 프록시 호환 연결을 지원합니다.
- DNS: 도메인 이름을 노드 주소로 사용할 수 있으며, 연결 시 IP로 해석됩니다.
Encryption and Multiplexing
기반 전송이 확립되면, 협상된 프로토콜을 통해 연결이 업그레이드됩니다:
- 암호화는 Noise Protocol Framework를 사용하여 종단 간 기밀성과 무결성을 보장합니다.
- 스트림 멀티플렉싱은 보통 Yamux를 사용하며, 단일 물리적 연결에서 여러 논리적 스트림(서브스트림)을 동시에 운용할 수 있게 합니다.
이러한 업그레이드는 피어가 호환 가능한 암호화 및 멀티플렉싱 옵션을 선택할 수 있도록 하는 Multistream-Select 프로토콜로 협상됩니다.
Substream Protocols
연결이 멀티플렉싱되면, 피어는 특정 애플리케이션 레벨 프로토콜 전용의 서브스트림을 여러 개 엽니다:
- Ping: 활성 상태 확인 및 지연 시간 측정용.
- Request-Response: 구조화된 데이터 교환(예: 블록이나 트랜잭션 쿼리)용.
- Notification: 새로운 트랜잭션, 블록 공지, 최종성 업데이트, 경량 클라이언트 상태 동기화 등의 이벤트 브로드캐스트용.
Peer Identification
각 노드는 합의 메시지 서명용 키 쌍과는 별도의 고유 ed25519 공개 키로 자신을 식별합니다. 이 신원 키는 핸드셰이크 과정에서 교환되며, 세션 전반에 걸쳐 피어를 인증하는 데 사용됩니다.