IPFS 프로토콜 교환 계층 분석 - Provide Blocks
IPFS 데이터 교환 계층-Provide Blocks
GetBlocks 인터페이스가 동작하면서 Keys 요청을 받은 후 각 모듈에 KEYS에 대한 요청을 캐시하고 라우팅 계층을 통해 해당 데이터를 찾기 시작합니다. KEYS를 WantManager에 등록함과 동시에 WantManager는 이미 설정된 링크의 노드 정보를 Map에 저장하고 GetBlocks 요청이 수신되면 WantManager는 요청을 설정된 노드로 보냅니다. 다음 그림은 노드 정보의 Map 데이터 구조 입니다.
각 노드의 PeerID가 Message Queue에 해당하는 것을 확인할 수 있습니다. Message Queue는 Want List와 Out Queue의 두 부분으로 구성됩니다. Out Queue는 또 다른 Want List와 Block List가 있으며 Want List는 해당 키에 대한 요청을 저장하고 Block List는 Key에 해당하는 데이터를 저장합니다.
위 그림에서 각 메시지 대기열의 자체 run loop 를 활용하여 신규 검색 명령어가 오면 run loop 는 msgSender 객체를 통해 검색명령을 실행합니다. 이미 Peers MAP을 사용하고 있기 때문에 알고 있는 수신자 peerID를 Message sender 객체에 전달하여 네트워크 레이어를 통해 링크를 설정하고 검색명령을 수신자에게 전달할 수 있습니다.
이러한 내용은 노드와 링크를 설정한 노드의 검색명령을 수신하는 로직에 대한 내용입니다. 각 캐시는 명령어를 검색하는 방법과 각 캐시 자체의 run loop 가 데이터 쿼리 명령을 단계적으로 실행하는 방법이 저장됩니다.
다음은 이러한 쿼리 명령을 받은 후 쿼리된 노드가 어떻게 반응하는지 살펴보겠습니다.
Want Manager 가 다른 노드 정보를 관리하지 않는 경우 GetBlocks 는 쿼리 개체의 KEY 배열의 첫번째 KEY에서 findkeys() 를 호출할 수 있습니다. 위 그림에서 링크 요청을 수신한 수 다른 노드의 동작을 추가하는 것을 볼 수 있습니다. 먼저 다은 노드가 해당 노드와 데이터 링크를 설정하고 IPFS의 프로토콜 계층은 다른 노드 정보를 Want Manager 의 다른 노드 목록에 추가하여 관리하게 됩니다. 위 그림은 프로토콜의 각 계층에 대한 키 처리를 보여줍니다.
다른 노드 정보를 얻은 후 Send Message 요청을 시작하는 Run loop 가 존재하고 있음을 알게되며 해당 노드는 데이터를 찾는데 필요한 KEY 값을 사용 가능한 다른 모든 노드로 보냅니다. 데이터 쿼리 요청을 수신한 다른 노드는 네트워크 계층을 통해 데이터를 수락하고 데이터 교환 계층이 사용하는 BitSwapMessage 형식으로 수락한 데이터를 결합하고 이를 PeerRequestQueue 엔진 모듈의 큐에 배치합니다.
위 그림은 Engine.peerRequestQueue 의 데이터 구조로 특정 데이터의 목록을 유지하는 것을 보여줍니다. TaskMap 은 요청 작업을 관리하는데 사용되며 허용된 각 데이터는 하나의 작업으로 캡슐화됩니다. 요청을 보내는 피어 정보를 저장하기 위한 두가지 맵도 존재합니다. 하나는 partners Map 이고 다른 하나는 frozon partners Map (고정 파트너 맵) 입니다. IPFS 데이터 교환 프로토콜에서 Engine 은 노드 및 기타 내용을 관리합니다. 악의적인 공격을 막기위한 노드의 데이터 교환노드가 데이터만 수집하고 데이터를 제공하지 않으면 이 노드는 다른 노드에 의해 고정된 목록으로 추가될 수 있습니다.
데이터 요청 큐에는 task 가 있는지 여부를 지속적으로 확인하고 큐 헤더의 순서대로 pop 하고 요청한 task 를 가지고 온 다음 task 에 저장된 데이터를 로컬 데이터 저장소에 조회하여 저장하는 run loop 가 있습니다. 데이터 요청 키가 검색되고 키에 해당하는 특정 데이터 블록을 찾고 데이터를 가지고 오면 Send Manager 의 sendBlock 인터페이스가 호출되어 데이터를 네트워크로 전송합니다.