Gossipsub의 부분 메시지 확장 및 셀 수준 전파

이 기사는 기계로 번역되었습니다
원문 표시

Gossipsub의 부분 메시지 확장 및 셀 수준 전파

또는 블롭 전파를 더 빠르고 효율적으로 만드는 방법

초안에 대한 피드백을 주신 Raúl Kripalani, Alex Stokes, Csaba Kiraly에게 감사드립니다.

개요

Gossipsub의 새로운 부분 메시지 확장 기능을 통해 노드는 하드 포크(Fork) 없이 셀 수준 전송으로 업그레이드할 수 있습니다. 로컬 메모리 풀(getBlobs)의 데이터 유용성이 향상됩니다.

합의 클라이언트가 부분 메시지 확장을 어떻게 활용하는지 명시한 초안 PR이 여기에 있습니다: MarcoPolo의 부분 메시지 사양을 통한 셀 전파 추가 · 풀 리퀘스트 #4558 · ethereum/consensus-specs · GitHub .

소개

Fusaka는 이더리움 개선 제안(EIP)-7594를 통해 PeerDAS를 소개합니다. 이더리움 개선 제안(EIP) 에서 설명한 대로, 삭제된 블롭은 셀 열 형태로 배포됩니다. 열은 DataColumnSidecar 로 유형화됩니다. 이러한 열은 gossipsub를 통해 네트워크로 전파됩니다. 노드가 로컬 메모리 풀의 열에 참조되는 모든 블롭을 이미 가지고 있는 경우, Gossipsub 전파를 기다리지 않고 DataColumnSidecar를 직접 파생시킬 수 있습니다. 그런 다음 빠른 전파를 위해 열을 전파합니다. Gossipsub의 IDONTWANT 메시지는 이미 IDONTWANT 메시지를 가지고 있는 피어의 이러한 푸시를 억제하는 역할을 합니다.

블록 의 모든 참조된 블롭이 대다수 노드의 메모리 풀에 나타나는 경우, 보관 요건을 빠르게 충족할 수 있습니다. 데이터는 이미 로컬에 있습니다. 그러나 블롭이 하나라도 누락되면 노드는 보관 요건을 충족하기 전에 전체 열이 네트워크를 통해 전파될 때까지 기다려야 합니다.

이상적으로는 주어진 행에서 누락된 셀만 배포하는 것이 좋습니다. 이를 통해 노드가 로컬에 이미 있는 데이터를 활용할 수 있습니다. Gossipsub의 Partial Message Extension이 바로 이러한 기능을 제공합니다.

부분 메시지 확장(Partial Message Extension)을 통해 노드는 셀을 간결하게 전송, 요청 및 광고할 수 있습니다. 이는 네트워크 계층의 변경 사항으로, 합의 변경이 필요하지 않고, 이전 버전과 호환되는 방식으로 배포 가능하며, 하드 포크(Fork) 필요하지 않습니다.

부분 메시지 확장, 개요

전체 초안 사양은 libp2p/specs 에서 확인할 수 있습니다.

부분 메시지는 일반적인 Gossipsub 메시지와 유사하게 동작합니다. 주요 차이점은 해시 대신 그룹 ID로 참조된다는 것입니다. 그룹 ID는 애플리케이션에서 정의되며, 전체 메시지가 없어도 도출할 수 있어야 합니다. 그룹 ID와 비트맵을 사용하면 노드는 누락된 부분과 제공할 수 있는 부분을 효율적으로 지정할 수 있습니다.

PeerDAS의 경우, 그룹 ID는 블록 루트입니다. 토픽별로 고유합니다. 전체 열은 완전한 메시지를 의미하며, 셀은 가장 작은 부분 메시지를 의미합니다. 셀은 서브넷 토픽(열 인덱스), 그룹 ID(블록 루트), 그리고 비트맵 내 위치로 고유하고 간결하게 식별됩니다. 노드는 블록 수신하는 즉시 셀을 알리고 요청할 수 있습니다. 블록 포함된 블롭을 선언하기 때문에 가능한 가장 빠른 시간 내에 시작할 수 있습니다.

일반적인 가십구독 메시지를 이용한 셀 수준 전파는 아무리 좋게 봐도 까다롭습니다. 각 셀은 전체 메시지 ID(20바이트)로 참조되어야 하며, 노드는 누락된 셀을 사전에 요청할 수 없습니다. 먼저 셀이 해당 메시지 ID에 어떻게 매핑되는지 알아야 합니다. 반면, 부분 메시지의 경우, 노드는 비트맵의 비트(Bit) 사용하여 각 셀을 참조하고, 부분 IHAVE 및 부분 IWANT 를 통해 제공할 수 있는 정보와 필요한 정보를 교환할 수 있습니다.

피어가 일부 메시지를 요청할 때까지 기다리지 않고 일부 메시지를 피어에게 즉시 푸시하거나, 요청 시 제공할 수 있습니다.

가십서브 부분 메시지는 애플리케이션이 메시지의 구성 및 분할 방식을 알고 있으므로 애플리케이션의 협조가 필요합니다. 애플리케이션은 다음과 같은 작업을 담당합니다. - 사용 가능한 부분과 누락된 부분(예: 비트맵) 인코딩 - 부분 요청 디코딩 및 인코딩된 부분 메시지 응답 - 인코딩된 부분 메시지 검증 - 인코딩된 부분 메시지 병합

가상 예시 흐름

부분 메시지의 실제 작동 방식에 대한 직관을 기르기 위해 다음 두 가지 예를 살펴보겠습니다. 첫 번째 예는 지연 시간을 줄이기 위해 즉시 푸시(eager push)를 사용하고, 두 번째 예는 피어 요청을 기다리는데, 이는 지연 시간을 희생하는 대신 중복을 줄일 수 있습니다(이 예에서는 RTT가 1/2입니다).

두 예 모두 다음과 같이 가정합니다.

  • 피어 P는 블록 을 제안하는 사람입니다. 블록 의 모든 블롭에 대해 알고 있습니다.
  • 피어 A와 B는 검증자입니다.
  • 블록 의 첫 번째 블롭은 사전에 A와 B에게 공개적으로 공유되지 않았으므로 두 사람 모두 로컬 메모리 풀에서 이 단일 블롭을 놓치고 있습니다.
  • P는 A에 연결되고 A는 B에 연결됩니다. P <=> A <=> B

열렬히 밀어붙이다

┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐│ P │ │ A │ │ B │└──────────────────┘ └──────────────────┘ └──────────────────┘┌────────────────┐ │ ││Proposes Block B│ │ │└───────┬────────┘ │ ││ ┌──────────────┐ │ │├───│Forwards block│──▶│ ┌──────────────┐ ││ └──────────────┘ ├───│Forwards block│──▶││ ┌──────────────┐ │ └──────────────┘ ││ │ Eager push │ │ ┌──────────────┐ │├───│cell at idx=0 │──▶│ │ Eager push │ ││ └──────────────┘ ├──│cell at idx=0 │──▶ ││ │ └──────────────┘ ││ │ ││ │ ││ │ │▼ ▼ ▼

요청/응답

┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐│ P │ │ A │ │ B │└──────────────────┘ └──────────────────┘ └──────────────────┘│ │ │┌───────┴────────┐ │ ││Proposes Block B│ │ │└───────┬────────┘ │ ││ ┌──────────────┐ │ │├───│Forwards block│──▶│ ┌──────────────┐ ││ └──────────────┘ ├───│Forwards block│──▶││ ┌──────────────┐ │ └──────────────┘ ││ │ IWANT │ │ ┌──────────────┐ ││◀──│ idx=0 │───│ │ IWANT │ ││ └──────────────┘ │◀──│ idx=0 │───││ ┌──────────────┐ │ └──────────────┘ ││ │ Respond with │ │ ┌──────────────┐ │├───│ cell@idx=0 │──▶│ │ Respond with │ ││ └──────────────┘ ├───│ cell@idx=0 │──▶││ │ └──────────────┘ │▼ ▼ ▼

피어는 피어가 무엇을 가지고 있는지 알기 전에 데이터를 요청합니다. 요청은 피어의 IWANT 비트맵의 일부이며, IHAVE 비트맵과 함께 전송됩니다. 즉, 피어가 데이터를 제공할 수 있으면 단일 RTT(Remote Time To Turn)로 데이터를 수신할 수 있습니다. 반면, 알림, 요청, 응답 흐름에는 1.5 RTT가 필요합니다.

출판 전략

열성적인 푸싱은 요청/응답보다 빠르지만 중복된 정보를 보낼 위험이 있습니다.

따라서 출판 전략은 다음과 같아야 합니다.

이것이 부분적인 메시지의 첫 번째 전달일 것이라는 확신이 있을 때 열렬히 밀어붙입니다.

개인 블롭이 있는 시나리오에서 노드가 개인 블롭을 수신하면 즉시 푸시를 전달하는 것은 합리적입니다.

분할된 메모리 풀이 있는 시나리오에서 노드가 자신의 분할 전략으로 인해 피어가 갖지 못할 셀을 적극적으로 푸시하는 것은 합리적입니다.

복원력의 한 형태로 일부 중복 정보는 예상되고 요구됩니다. 중복의 양은 적극적인 푸싱(eager push) 확률과 피어에게 요청할 확률을 조정하여 조절할 수 있습니다.

하지만, mempool의 로컬 데이터를 활용함으로써 단순하고 순진한 전략조차도 현재의 전체 열 방식보다 훨씬 뛰어난 성능을 보일 것입니다. 중복된 부분 메시지는 전체 열이 중복되는 대신 셀이 중복되는 결과를 초래합니다.

Devnet 개념 증명

부분 메시지 확장(Partial Message Extension)의 Go 구현이 진행 중입니다. 부분 메시지를 사용하는 Prysm 패치 도 있습니다.

개념 증명을 위해 패치된 Prysm 클라이언트를 패치된 geth 클라이언트에 연결하여 Kurtosis Devnet을 구축했습니다(getBlobs 호출에서 부분 블롭을 반환하기 위해). 일부 노드는 "프라이빗" 블롭으로 블록을 빌드합니다. 이 경우 다른 노드는 누락된 "프라이빗" 셀만 요청하고 나머지 열은 로컬 메모리 풀의 블롭으로 채웁니다.

대역폭 절감 효과를 대략적으로 파악하기 위해 두 개의 "슈퍼" 노드로 구성된 더 작은 첨도 네트워크를 만들었습니다. 이 두 노드는 모든 열을 수신하고 전송하는 노드입니다. 노드 중 하나는 프라이빗 블롭을 제안합니다. 즉, 앞서 언급한 노드가 제안할 때 getBlobs 함수는 다른 노드에 대한 전체 열을 반환하지 못합니다.

DataColumnSidecar 메시지로 전송된 데이터를 Partial Messages를 사용한 경우와 사용하지 않은 경우로 나누어 측정했습니다. 그 결과, Partial Messages를 사용하는 경우 노드가 전송하는 데이터가 10배 더 적었습니다. 그 이유는 두 가지입니다.

  1. 현재 Prysm의 Partial Messages 구현은 적극적으로 푸시하지 않습니다. 노드는 요청을 수신한 후 데이터로 응답합니다.
  2. 요청된 부분만 전송됩니다. 열에 개인 Blob이 하나만 있는 경우 해당 Blob 하나만 전송합니다.

이러한 저지연 환경(Kurtosis를 사용하여 로컬로 실행)에서는 IDONTWANT가 효과적이지 않습니다. 따라서 단순히 데이터를 적극적으로 푸시하지 않는 것이 큰 이점이 있습니다.

그러나 개인 블롭이 있는 경우 IDONTWANT를 적용할 수 없으므로 이러한 성능 이점은 여전히 ​​더 높은 지연 시간이 있는 보다 현실적인 환경을 나타냅니다.

그래프:

스크린샷 2025-08-22 오후 10시 42분 38초 690x448
스크린샷 2025-08-22 오후 10시 42분 38초 690x448 3248×2112 474KB
스크린샷 2025-08-22 오후 10시 42분 49초 690x448
스크린샷 2025-08-22 오후 10시 42분 49초 690x448 3248×2112 471KB

이 실험은 두 개의 피어만 사용하는 것이지만, 더 많은 피어가 있는 메시에서 각 쌍별 상호작용은 동일하게 동작해야 합니다. 는 데이터 열을 배포하는 데 사용되는 대역폭입니다.

Mempool 샤딩

메모리풀 샤딩의 향후 방향으로는 노드에서 일부 셀이 누락될 가능성이 더 높아지고, 따라서 셀 수준의 전파가 필요할 것입니다.

"행" 기반 배포

노드가 한 열의 특정 인덱스에서 셀이 누락된 경우, 다른 모든 열의 동일 위치에 있는 셀도 누락될 가능성이 높습니다. 향후 개선 사항 중 하나는 노드가 전체 행을 메시 피어에게 알릴 수 있도록 하는 것입니다. 이 기능의 장점은 노드가 한 행의 누락된 모든 셀을 한 번에 채울 수 있다는 것입니다. 단점은 더 큰 중복 메시지가 발생할 위험이 있다는 것입니다.

다음 단계

  • 부분 블롭 반환을 지원하는 getBlobs V3 API를 지정합니다.
  • Rust libp2p에서 부분 메시지 확장을 구현합니다. (진행 중)
  • DataColumnSidecar의 부분 메시지 인코딩을 지정합니다. 진행 중
  • CL 클라이언트에 통합합니다.
  • 테스트넷에 배포
  • 메인넷에 배포
  • 스케일 블롭 카운트 :rocket::rocket::rocket:

출처
면책조항: 상기 내용은 작자의 개인적인 의견입니다. 따라서 이는 Followin의 입장과 무관하며 Followin과 관련된 어떠한 투자 제안도 구성하지 않습니다.
라이크
1
즐겨찾기에 추가
1
코멘트