Signet에서 복합 블록의 전파 및 검증 시간

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

저자: b10c

출처: https://b10c.me/observations/16-slow-block-propagation-validation-signet/

원문은 2026년 4월에 발표되었습니다.

지난주 " Signet Tough Block Demo " 행사에서 저는 IPv4와 Tor를 사용하는 모든 Signet 노드(약 190개)에 연결된 맞춤형 P2P 클라이언트를 실행했습니다. 제 목표는 블록이 네트워크를 통해 전파되는 속도각 노드가 블록을 검증하는 속도를 측정하는 것이었습니다.

이 기사는 원래 bnoc.xyz 에 게재되었습니다 .

측정 결과에 따르면, 노드들이 블록을 먼저 수신한 피어 노드들이 검증을 완료할 때까지 기다려야 했기 때문에 블록 전파 속도가 크게 저하되었습니다. 노드들은 blocktxn 응답 메시지와 누락된 트랜잭션을 로컬에서 수신한 후에야 블록 재구성, 검증 및 전송을 시작할 수 있었습니다. 최악의 시나리오 대면, 관찰 가능한 중간 피어 노드의 검증 속도는 약 160배 감소했습니다. 이 중간 노드는 어려운 블록을 검증하는 데 20초가 걸린 반면, Signet에서 일반 블록을 검증하는 데는 176밀리초(ms)밖에 걸리지 않았습니다.

(역자 주: "시그넷"은 전용 블록 서명자를 사용하는 비트코인 ​​테스트 네트워크입니다. "하드코어 블록"은 검증 속도가 특히 느린 블록을 의미합니다.)

방법론

블록 전파 및 검증 속도를 측정하는 데 있어 피어 노드로부터의 두 가지 유형의 공지 이벤트가 특히 중요합니다.

먼저, BIP-152 고대역폭 밀집 블록 알림에 대해 설명하겠습니다. sendcmpct(1) 메시지를 사용하여 피어에게 고대역폭 밀집 블록을 요청하면, 피어는 블록을 생성한 후 검증하기 전에 가능한 한 빨리 cmpctblock 메시지를 클라이언트에게 보냅니다. 클라이언트가 피어로부터 cmpctblock 메시지를 수신하면 getblocktxn 메시지를 전송하여 트랜잭션을 요청합니다. 피어가 블록을 검증하면 blocktxn 메시지로 응답합니다. cmpctblock 메시지와 blocktxn 메시지가 로컬에 도착한 타임스탬프를 기록함으로써 검증 시간을 추론할 수 있습니다. cmpctblock 의 타임스탬프는 검증 시간을 제외하고 블록 전파 속도도 나타냅니다.

둘째로, 저대역폭 밀집 블록 INV(또는 이와 유사한 BIP-130 블록 헤더) 알림에도 정보가 포함되어 있습니다. 이러한 알림은 노드가 블록을 검증한 후에 발생합니다.

저희 맞춤형 P2P 클라이언트는 각 노드의 비트코인 ​​프로토콜의 ping 왕복 시간(RTT)도 기록하므로, 공지 메시지의 타임스탬프 pong 네트워크 및 애플리케이션 계층 지연 시간에 맞춰 조정할 수 있습니다.

블록 전파 시간은 알림 메시지의 타임스탬프와 우리가 수신하는 블록의 첫 번째 알림 타임스탬프 간의 차이입니다. 두 타임스탬프는 RTT를 사용하여 조정되며, 조정 항은 $\frac{1}{2}$ RTT입니다. 즉, $\textit{ts_adjusted} = \textit{ts_raw} - \frac{1}{2} \textit{RTT}$입니다. RTT는 1 에 대해 대칭이라고 가정합니다.

블록 검증 시간은 피어 노드가 고대역폭의 밀집 블록 알림을 보내는 시점과 해당 blocktxn 응답 정보를 보내는 시점 사이의 시간 차이이며, 2 로 표시됩니다. 피어 노드가 메시지를 보내는 시점의 타임스탬프는 알 수 없지만, 메시지를 수신하는 시점의 타임스탬프와 왕복 시간(RTT)을 이용하여 계산할 수 있습니다. 전체 과정은 다음과 같은 타임라인을 따릅니다.

측정 중 시간 경과를 보여주는 순서도

이 사건 순서도는 우리가 측정한 시간 범위를 보여줍니다.

  • $t_0$: 피어 노드가 블록 재구성을 완료하고 고대역폭 고밀도 블록 알림을 전송했습니다.
  • $t_1$: 고대역폭 밀집 블록 알림($t_0$ 이후 $\frac{1}{2} RTT$)을 수신했습니다.
  • $t_2$: (즉시 응답한다고 가정하고) getblocktxn 요청을 보냅니다.
  • $t_3$: 피어 노드가 getblocktxn 요청($t_2$ 이후 $\frac{1}{2} RTT$)을 수신했습니다.
  • $t_4$: 피어 노드가 블록 검증을 완료하고 blocktxn 전송합니다(시간 불확실).
  • $t_5$: blocktxn ($t_4$ 다음에 $\frac{1}{2} RTT$)을 수신했습니다.

우리는 두 시점 $t_0$과 $t_4$ 사이의 시간 간격($= d$)을 측정하고자 합니다. 피어 노드 대면, $t_1$(및 $t_2$), $t_5$, 그리고 RTT(왕복 시간)를 알 수 있습니다. 하지만 $t_0$과 $t_4$ 사이에 완전한 메시지 왕복이 완료되어야 하므로, 블록 검증 시간이 RTT보다 짧을 경우 검증 시간의 상한값만 얻을 수 있습니다. 이 경우 $d ≈ RTT$가 됩니다.

$$
\begin{align}
t_0 &= t_1 - \frac{1}{2} \textit{RTT} \\
t_2 &= t_1 \\
t_3 &= t_1 + \frac{1}{2} \textit{RTT} \\
t_4 &= t_5 - \frac{1}{2} \textit{RTT} \\
d &= t_4 - t_0 \\
\textit{rtt보다 긴} &= d > \textit{RTT}
\end{align}
$$

RTT 자체에 대해서는 연결 활동 기간 동안 기록된 RTT의 중앙값을 사용합니다.

결과

블록 전파

블록 전파와 관련하여, 우리는 피어 노드가 고대역폭 밀집 블록을 사용하여 블록을 알리는 데 걸리는 시간과 INV 메시지를 통해 블록을 알리는 데 걸리는 시간을 관찰했습니다. 또한 일반 블록과 특별히 구성된 복합 블록을 구분했습니다.

정상 블록 및 검증 속도가 느린 블록에서 INV 및 CMPCTBLOCK을 사용한 블록 전파의 ECDF

- 일반 블록 및 특수 구조의 난해 블록의 INV 전파 속도, 그리고 밀집 블록의 ECDF 전파 속도 -

일반 블록과 특수하게 구성된 복합 블록 모두에서 고대역폭 밀집 블록 알림은 INV 알림보다 더 빠르게 전파됩니다. 이는 고대역폭 밀집 블록 알림은 블록 검증 전에 전송되는 반면, INV 알림은 블록 검증 후에만 전송되기 때문입니다.

시그넷(Signet)에서 일반 블록의 전파 시간(녹색선)과 고밀도 블록의 전파 시간(파란색선)은 유사합니다. 시그넷의 일반 블록 채널에는 많은 트랜잭션이 포함되어 있지 않으므로 빠르게 검증할 수 있습니다. 상위 25%에 해당하는 노드는 150ms 후에 블록을 알리고, 중간값 노드는 200ms를 약간 넘는 시간이 걸립니다. 상위 75% 노드는 300ms 후에 블록을 알리고, 600ms 후에는 피어 노드의 90%가 블록을 검증하고 알림을 보냅니다.

블록 전파의 ECDF(검증 속도가 느린 블록만 해당) - (어려운 블록만 해당) 블록 전파 ECDF-

처리하기 어려운 블록의 전파 속도는 노드마다 크게 다릅니다. 고대역폭 밀집 블록 알림 메시지(노란색 선)는 INV ​​알림 메시지보다 먼저 도착하지만, 하위 25% 노드는 고대역폭 밀집 블록 알림을 약 14초 후에 전송하고, INV 메시지는 27.5초 후에 도착합니다. 중간 노드는 밀집 블록 알림을 약 26초 후에 전송하고, INV 메시지는 31.7초 후에 전송합니다. 상위 75% 노드는 밀집 블록 알림을 31.7초 후에, INV 메시지를 55초 후에 전송합니다. 상위 90% 피어 노드는 처리하기 어려운 블록을 밀집 블록으로 58초 후에 알리고, INV 메시지를 통해 114초 후에 알립니다.

이는 블록 전파 속도가 검증 성능에 따라 달라진다는 것을 나타냅니다. 검증하기 쉬운 블록은 더 빠르게 전파되고, 검증하기 어려운 블록은 더 느리게 전파됩니다. 노드가 블록을 전파하기 전에 검증해야 하므로 이는 당연한 결과입니다. 그러나 이러한 속도 저하는 노드가 getblocktxn 사용하여 트랜잭션을 요청해야 할 때만 발생한다는 점에 유의해야 합니다. 노드가 트랜잭션을 요청할 필요가 없는 경우, 예를 들어 트랜잭션 풀에 블록에 포함된 모든 트랜잭션이 이미 있는 경우, cmpctblock 메시지를 수신한 후 즉시 블록을 재구성하고 검증을 시작할 수 있습니다. 느린 블록에 포함된 어려운 트랜잭션은 비표준 트랜잭션이므로 getblocktxn 사용하여 요청해야 합니다. 이 글에서 언급된 것처럼 "밀집 블록 사전 채우기" 기법을 구현하면 어려운 블록의 전파 속도도 빨라질 수 있습니다. 이 예시에서는 이러한 어려운 블록들이 모두 999kvB 크기의 어려운 트랜잭션 하나만을 포함하고 있었습니다. 이 트랜잭션은 너무 크기 때문에 사전 채우기를 해도 속도 향상에 도움이 되지 않을 수 있습니다.

블록 검증

블록 검증 시간을 측정하기 위해, 우리는 높은 대역폭을 가진 밀집된 블록 공지 및 blocktxn 응답만을 관찰합니다. 구체적으로, 지속 시간 dd = t4 - t0 (앞서 언급한 바와 같이)으로 정의됩니다. 실제 검증 시간이 왕복 시간(RTT)보다 짧을 경우, 우리가 측정한 값은 실제 검증 시간의 상한값이 됩니다. 이는 실제 검증 시간이 우리가 측정한 값보다 짧을 수 있음을 의미합니다.

정상 블록과 검증 속도가 느린 블록에 대해 측정된 검증 기간의 분포

- 일반 블록과 어려운 블록에 대한 검증 시간 배분 -

위 그래프는 일반 블록과 특수하게 구성된 복잡한 블록의 검증 시간을 보여줍니다. 일부 일반 블록의 경우, 상한값만 측정했으며 실제 검증 시간은 더 넓을 수 있습니다.

Signet에서 정상 블록의 검증 시간은 10ms에서 2초 사이이며, 문제가 있는 블록의 검증 시간은 2.5초에서 5분 사이입니다.

측정된 블록 검증 기간의 ECDF

- 블록 검증 기간에 대한 ECDF -

일반 블록(검증 시간의 상한값만 측정된 블록 포함)의 경우, 블록 검증 시간의 25번째 백분위수는 37ms, 50번째 백분위수는 176ms, 75번째 백분위수는 447ms, 90번째 백분위수는 740ms입니다. 시그넷 네트워크의 대다수 수신 노드는 1초 이내에 일반 블록을 검증할 수 있습니다.

난이도가 높은 블록의 경우, 25번째 백분위수는 8.2초, 50번째 백분위수는 19.7초, 75번째 백분위수는 32초, 90번째 백분위수는 78.3초입니다.

검증 속도를 시각적으로 파악하기 위해, 피어 노드 전체에서 일반 블록의 검증 시간 중앙값을 벤치마크로 사용할 수 있습니다. 그런 다음, 해당 노드의 어려운 블록 검증 시간 중앙값과 비교하여 승수를 계산합니다.

검증 속도가 느린 블록에 대한 중앙값 검증 속도 저하의 ECDF

- 복잡한 블록(ECDF)의 검증 시간 지연 -

제 동료들 사이에서 하위 10%는 13.5배, 하위 25%는 31배, 하위 50%는 159.4배, 하위 75%는 793배, 그리고 하위 90%는 1156배 더 느렸습니다. 이처럼 복잡한 블록을 검증할 때 Signet 네트워크의 수신 노드 간에 성능 차이가 상당히 큰 것으로 보입니다.

이 데이터를 해석할 때, 이것들은 앙투안이 공개하기로 선택한 어려운 블록일 뿐이며, 검증하기 위해 구성될 수 있는 가장 어려운 블록과는 거리가 멀다는 점을 명심해야 합니다.

이 측정 방법의 정확도

측정 방법의 정확성을 검증하기 위해, -debug=bench -debug=validation -debug=net -logtimemicros=1 시작 탭에서 Bitcoin Core 의 debug.log 파일을 살펴보고 실제 검증 시간과 측정된 검증 시간을 비교하면 됩니다.

아래 debug.log 스크린샷은 제 워치 노드가 경험한 데모 첫 번째 라운드의 첫 번째 하드 블록을 보여줍니다(자세한 내용은 delvingbitcoin.org를 참조하세요). 또한 네 개의 태그( [m1] [m2] [m3] [m4] )를 추가했습니다.

 2026-04-08T14:05:12.292703Z [msghand] [cmpctblock] Successfully reconstructed block 0000000eb552c9f26e712d546c71297fd0623890299b40e7ada81d2dc32f5d0b with 1 txn prefilled, 0 txn from mempool (incl at least 0 from extra pool) and 1 txn (999557 bytes) requested2026-04-08T14:05:12.292795Z [msghand] [cmpctblock] Reconstructed block 0000000eb552c9f26e712d546c71297fd0623890299b40e7ada81d2dc32f5d0b required tx 1b44e7f59d39e4d53b4c4a77a650561de1871fe962fe6a17d1a302b877b2cb48[m1] 2026-04-08T14:05:12.422939Z [msghand] [validation] NewPoWValidBlock: block hash=0000000eb552c9f26e712d546c71297fd0623890299b40e7ada81d2dc32f5d0b2026-04-08T14:05:12.423680Z [msghand] [net] PeerManager::NewPoWValidBlock sending header-and-ids 0000000eb552c9f26e712d546c71297fd0623890299b40e7ada81d2dc32f5d0b to peer=52026-04-08T14:05:12.423794Z [msghand] [net] sending cmpctblock (358 bytes) peer=52026-04-08T14:05:12.543864Z [msghand] [bench] - Using cached block2026-04-08T14:05:12.543926Z [msghand] [bench] - Load block from disk: 0.07ms2026-04-08T14:05:12.543962Z [msghand] [bench] - Sanity checks: 0.01ms [0.00s (0.01ms/blk)]2026-04-08T14:05:14.166485Z [msghand] [bench] - Fork checks: 1622.48ms [1.96s (93.29ms/blk)]2026-04-08T14:05:14.643331Z [msghand] [bench] - Connect 2 transactions: 476.84ms (238.419ms/tx, 1.189ms/txin) [0.69s (32.64ms/blk)]2026-04-08T14:06:33.383188Z [msghand] [bench] - Verify 401 txins: 79216.70ms (197.548ms/txin) [79.43s (3782.32ms/blk)]2026-04-08T14:06:33.385563Z [msghand] [bench] - Write undo data: 2.39ms [0.07s (3.19ms/blk)]2026-04-08T14:06:33.385643Z [msghand] [bench] - Index writing: 0.11ms [0.00s (0.08ms/blk)]2026-04-08T14:06:33.385754Z [msghand] [validation] BlockChecked: block hash=0000000eb552c9f26e712d546c71297fd0623890299b40e7ada81d2dc32f5d0b state=Valid2026-04-08T14:06:33.385862Z [msghand] [bench] - Connect total: 80841.94ms [81.46s (3879.22ms/blk)]2026-04-08T14:06:33.832999Z [msghand] [bench] - Flush: 447.07ms [0.51s (24.52ms/blk)]2026-04-08T14:06:33.833198Z [msghand] [bench] - Writing chainstate: 0.27ms [0.00s (0.19ms/blk)]2026-04-08T14:06:33.833668Z [msghand] [validation] Enqueuing MempoolTransactionsRemovedForBlock: block height=299177 txs removed=02026-04-08T14:06:33.833839Z [msghand] UpdateTip: new best=0000000eb552c9f26e712d546c71297fd0623890299b40e7ada81d2dc32f5d0b height=299177 version=0x20000000 log2_work=43.630312 tx=29147716 date='2026-04-08T14:03:39Z' progress=1.000000 cache=15.3MiB(114240txo)2026-04-08T14:06:33.833856Z [msghand] [bench] - Connect postprocess: 0.66ms [1.57s (74.55ms/blk)][m2] 2026-04-08T14:06:33.833868Z [msghand] [bench] - Connect block: 81290.01ms [83.55s (3978.55ms/blk)]2026-04-08T14:06:33.833926Z [msghand] [validation] Enqueuing BlockConnected: block hash=0000000eb552c9f26e712d546c71297fd0623890299b40e7ada81d2dc32f5d0b block height=2991772026-04-08T14:06:33.833962Z [msghand] [validation] Enqueuing UpdatedBlockTip: new block hash=0000000eb552c9f26e712d546c71297fd0623890299b40e7ada81d2dc32f5d0b fork block hash=0000000bc5d91380fa9188acfabd6a59244e8e6e744b0a0ef07064968027e256 (in IBD=false)2026-04-08T14:06:33.834043Z [msghand] [validation] ActiveTipChange: new block hash=0000000eb552c9f26e712d546c71297fd0623890299b40e7ada81d2dc32f5d0b block height=299177[m3] 2026-04-08T14:06:33.834887Z [msghand] [net] received: headers (82 bytes) peer=102026-04-08T14:06:33.835052Z [msghand] [net] sending ping (8 bytes) peer=102026-04-08T14:06:34.062891Z [scheduler] [validation] MempoolTransactionsRemovedForBlock: block height=299177 txs removed=02026-04-08T14:06:34.063548Z [scheduler] [validation] BlockConnected: block hash=0000000eb552c9f26e712d546c71297fd0623890299b40e7ada81d2dc32f5d0b block height=2991772026-04-08T14:06:34.063728Z [scheduler] [validation] UpdatedBlockTip: new block hash=0000000eb552c9f26e712d546c71297fd0623890299b40e7ada81d2dc32f5d0b fork block hash=0000000bc5d91380fa9188acfabd6a59244e8e6e744b0a0ef07064968027e256 (in IBD=false)[m4] 2026-04-08T14:06:34.461329Z [msghand] [net] received: headers (82 bytes) peer=42026-04-08T14:06:34.461786Z [msghand] [net] sending ping (8 bytes) peer=11... -> p2p communication continues
  • [m1] : 2026-04-08T14:05:12.422939NewPoWValidBlock 이 블록의 유효성 검증 시작을 나타냅니다.
  • [m2] : 2026-04-08T14:06:33.833868 에 분기 로그에 Connect block: 81290.01ms
  • [m3] : 2026-04-08T14:06:33.834887 에 P2P 통신이 기본적으로 복구되었습니다.
  • [m4] : 2026-04-08T14:06:34.461329UpdatedBlockTip (블록체인 상단 업데이트)이 종료되었고 P2P 통신이 완전히 복원되었습니다.

[m1][m4] 의 차이는 82038ms인 반면, 우리가 측정한 값은 82049ms로 불과 11ms 차이입니다. 첫 번째 라운드를 되돌아보면 두 값의 차이가 항상 이렇게 작지는 않았습니다.

측정을 통해 얻은 값 실제 값(로그에서 확인) 차이점 편차율 차단하다
82049ms 82038ms 11ms 0.013% 0000000eb552c9f26e712d546c71297f..
82478ms 81814ms 664ms 0.81% 000000002b3a132836666c18f5e1a9d9..
76937ms 76368ms 569ms 0.74% 00000006d34037534a517f9e5809a347..
79382ms 78667ms 715ms 0.90% 00000014a4cae4501f98539b45c76059..
79894ms 78571ms 1323ms 1.68% 00000003220437cb8b5a2edef6be828c..
93556ms 93541ms 15ms 0.016% 000000143c97bf0134c5cf0881dfd4ef..

측정 오차가 중간 블록에서 더 크게 나타나는데, 이는 피어 노드들이 getblocktxn 메시지에 응답하거나 다음 밀집 블록을 알리기 전에 처리해야 할 P2P 메시지가 대량 쌓여 있기 때문일 수 있습니다. 이 경우 1%의 오차율은 허용 가능합니다. 또한, 이는 모든 피어 노드에 대한 측정값이 정확하다는 것을 의미하지는 않습니다.

결론적으로

본 연구에서는 Signet 네트워크 상의 수신 노드들 간에 고대역폭의 고밀도 블록과 INV 선언의 전파 속도를 성공적으로 측정했습니다. 처리하기 어려운 블록이 나타날 경우, 해당 블록들이 동시에 브로드캐스트되기 때문에 전파 속도가 현저히 저하되는 것을 확인했습니다.

또한 블록 검증 시간도 측정했습니다. 일반적인 Signet 네트워크 환경에서는 블록 검증이 노드 간 왕복 통신 시간보다 빠를 수 있습니다. 이러한 경우 검증 시간의 최대값만 측정할 수 있습니다. 어려운 블록의 경우, (이 데모에 나온 어려운 블록을 사용하여) 50번째 백분위 노드에서 검증 시간이 160배 단축되는 것을 측정했습니다. 어려운 블록은 검증하는 데 20초 이상이 소요됩니다.

향후 연구에서는 메인넷에서의 블록 전파 및 검증 시간을 살펴보는 것을 포함할 수 있습니다.

---

이 차트를 만드는 데 사용한 Jupyter Notebook을 여기에 게시했습니다. 이 연구에 대한 수정 및 확장은 언제든지 환영합니다.

---

1. Tor 환경에서는 이 내용이 적용되지 않을 수 있습니다.

2. 때때로, 특히 여러 개의 복잡한 블록에서 중요한 블록들이 피어 노드에 도착하여 검증 대기열에 추가될 때, 대기 중인 모든 블록의 검증이 완료된 후에야 getblocktxn 메시지를 수신하는 경우가 있습니다. 이 경우, 저는 다음 블록 검증이 시작되기 전에 전송되는 다음 밀집 블록 발표 시간을 사용합니다.

(위에)

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