Tổng Vốn Hóa Thị Trường:$00
API
VI
Tối

Tìm kiếmSSI/Mag7/Meme/ETF/Coin/Chỉ số/Biểu đồ/Nghiên cứu
00:00 / 00:00
Xem
    Thị trường
    Chỉ số
    Thông Tin
    TokenBar®
    Phân tích
    Vĩ mô
    Danh sách theo dõi
Chia sẻ

Ghi chú về 'DoS do tập hợp inv-to-send tăng quá lớn' từ tháng 5 năm 2023

#Bitcoin
0xB10C's Blog: German Bitcoin freelance developer on 0xB10C's Blog
2KTừ ngữ
23/06/2025

Vào tháng 10 năm 2024, dự án Bitcoin Core đã công bố một tấn công từ chối dịch vụ (Denial-of-Service) do các tập hợp inv-to-send tăng trưởng quá lớn, do tôi viết, dành cho các phiên bản Bitcoin Core trước v25.0. Tôi có một vài ghi chú và ảnh chụp màn hình từ cuộc điều tra của mình lúc đó mà tôi muốn lưu giữ ở đây. Vào đầu tháng 5 năm 2023, cơ sở hạ tầng giám sát của tôi đã nhận thấy lỗi này ảnh hưởng đến các node mainnet, điều này cho phép tôi xác định chính xác nguồn gốc của vấn đề. Công lao cho việc thực hiện một bản sửa lỗi thuộc về Anthony Towns.


Quan sát


Vào ngày 2 tháng 5 năm 2023, tôi nhận thấy rằng trên một trong các node giám sát của mình, số lượng kết nối inbound đã giảm từ khoảng 1901 xuống chỉ còn 35 trong khoảng hai ngày. Thông thường, một node sẽ giữ các slot inbound đã đầy của nó cho đến khi nó khởi động lại hoặc mất kết nối mạng.




Ảnh chụp màn hình bảng điều khiển Grafana của tôi để theo dõi số lượng kết nối in và outbound của node Bitcoin Core của tôi. Các thanh màu vàng hiển thị số lượng kết nối inbound. Chúng giảm dần ở cuối biểu đồ.

Kiểm tra với những người đóng góp khác, tôi nhận thấy node có mức sử dụng CPU là 100%. Điều này ảnh hưởng đến node đến mức nó không thể tiếp tục giao tiếp với các peer của nó, dẫn đến việc các kết nối inbound hết thời gian chờ và bị ngắt. Sử dụng perf top trên tiến trình node, tôi có thể thấy rằng rất nhiều thời gian CPU đã được sử dụng cho CTxMemPool::CompareDepthAndScore() trong luồng b-msghand. Tôi đã ghi lại flamegraph sau, cho thấy rằng make_heap(), gọi CompareDepthAndScore(), đã sử dụng hơn 45% thời gian CPU của tiến trình.




Một flame graph cho thấy thời gian CPU của tiến trình Bitcoin Core đang được sử dụng ở đâu. Mở trong một tab mới để tương tác với flame graph này.

Đồng thời, có một vấn đề sử dụng CPU 100% đang mở, không liên quan đến các bản dựng chế độ debug của Bitcoin Core. Điều này đã gây nhầm lẫn cho một số người đóng góp và người dùng không chạy các bản dựng chế độ debug nhưng nhận thấy mức sử dụng CPU cao trên các node của họ. Mặc dù vấn đề chế độ debug có thể chỉ ảnh hưởng đến một số nhà phát triển, nhưng vấn đề sử dụng CPU cao khác ảnh hưởng đến toàn bộ mạng. Điều này bao gồm, ví dụ: các mining pool như AntPool và những pool khác, những người đã báo cáo các vấn đề với hoạt động khai thác của họ vì các node của họ không xử lý các block đã nhận một cách kịp thời.


Ảnh hưởng


Việc quan sát thời gian ping trên toàn mạng cho thấy ảnh hưởng của cuộc tấn công Denial-of-Service này. Vì quá trình xử lý tin nhắn của Bitcoin Core là đơn luồng, nên chỉ có thể tạo hoặc xử lý một tin nhắn tại một thời điểm, có nghĩa là tất cả các peer khác phải đợi. Thời gian chờ đợi lâu hơn ảnh hưởng đến thời gian phản hồi cho một ping. Hệ thống giám sát Bitcoin KIT DSN có dữ liệu về các ping giao thức ICMP và Bitcoin. So sánh chúng cho phép chúng ta xác định khi nào phần mềm node gặp sự cố trong việc theo kịp quá trình xử lý tin nhắn. Dữ liệu cho thấy ping ICMP đến máy chủ không bị ảnh hưởng, tuy nhiên, ping trung bình đến phần mềm node Bitcoin gần như tăng gấp đôi từ khoảng 25ms lên hơn 50ms giữa cuối tháng 4 và đầu tháng 5. Ping Bitcoin trung bình đã tăng vọt lên 200ms vào ngày 8 tháng 5, trong khi ping ICMP vẫn không bị ảnh hưởng.




Ping giao thức Bitcoin trung bình và ping ICMP. Dựa trên dữ liệu từ DSN KIT (https://www.dsn.kastel.kit.edu/bitcoin/)

Ảnh hưởng cũng có thể được nhìn thấy bằng cách xem dữ liệu độ trễ lan truyền block được thu thập bởi hệ thống giám sát Bitcoin KIT DSN. Khoảng ngày 8 tháng 5 năm 2023, một sự tăng đột biến về độ trễ lan truyền block có thể nhìn thấy được. Thời gian để 50% các node có thể truy cập thông báo block cho các node giám sát của họ đã tăng từ dưới một giây lên hơn năm giây. Tương tự, phép đo 90% đã tăng vọt từ khoảng hai giây lên hơn 20 giây.




Độ trễ lan truyền block: thời gian trung bình cho đến khi 50% và 90% mạng thông báo một block. Dựa trên dữ liệu của DSN KIT (https://www.dsn.kastel.kit.edu/bitcoin/)

Việc lan truyền block kém cũng gây ra nhiều stale block hơn khi các mining pool khai thác trên các block lỗi thời của họ lâu hơn, trong khi một block mới mà họ chưa thấy đã tồn tại trong mạng. Dựa trên dữ liệu từ tập dữ liệu stale-blocks của tôi, mười stale block đã được quan sát trong tuần từ ngày 3 tháng 5 (bắt đầu với stale block 788016) và ngày 10 tháng 5 (và kết thúc với block 789147). Đó là tỷ lệ khoảng 8,84 stale block trên 1000 block. So sánh, giữa các block 800000 và 900000 (khoảng hai năm), 73 stale block đã được quan sát. Đây là tỷ lệ 0,73 stale block trên 1000 block. Sự gia tăng gấp 10 lần về tỷ lệ stale-block này có khả năng là do việc lan truyền block bị ảnh hưởng đáng kể.


Nguyên nhân


Tại sao hàm CTxMemPool::CompareDepthAndScore() làm chậm node đến mức nó gặp khó khăn trong việc xử lý các tin nhắn P2P? Trong Bitcoin Core, luồng b-msghand xử lý các tin nhắn P2P. Ví dụ: chuyển các block mới nhận được để xác thực, phản hồi các ping, thông báo các giao dịch cho các peer khác và nhiều hơn nữa.


Hàm CTxMemPool::CompareDepthAndScore() được sử dụng khi quyết định giao dịch nào sẽ thông báo cho một peer tiếp theo. Trong giao thức Bitcoin P2P, các giao dịch được thông báo qua các tin nhắn inv (inventory). Một thông báo giao dịch Bitcoin Core cho một peer thường chứa tối đa 35 mục wtxid. Để theo dõi các giao dịch nào sẽ thông báo cho một peer tiếp theo, có một tập hợp m_tx_inventory_to_send trên mỗi peer. Nó chứa các giao dịch mà node nghĩ rằng peer chưa thấy. Khi xây dựng một tin nhắn inventory cho một peer, tập hợp được sắp xếp theo các phụ thuộc giao dịch và feerate để ưu tiên các giao dịch feerate cao và tránh tiết lộ thứ tự mà node đã tìm hiểu về các giao dịch. Đối với điều này, hàm so sánh CTxMemPool::CompareDepthAndScore() được sử dụng.


Vào đầu tháng 5 năm 2023, một lượng lớn các giao dịch liên quan đến token BRC-20 đã được phát sóng. Điều này có nghĩa là các tập hợp m_tx_inventory_to_send tăng trưởng nhanh hơn bình thường và lớn hơn bình thường. Do đó, việc sắp xếp các tập hợp mất nhiều thời gian hơn. Vào buổi tối ngày 7 tháng 5 (UTC), việc mint token VMPX BRC-20 bắt đầu, dẫn đến hơn 300k giao dịch được phát sóng trong 6 giờ bên cạnh các mint token BRC-20 đang diễn ra khác. Điều này gây ra sự tăng đột biến về thời gian ping trung bình và thời gian lan truyền block được quan sát vào ngày 8 tháng 5.


Ảnh hưởng được khuếch đại bởi cái gọi là spy node, chỉ nghe các tin nhắn inv và không bao giờ tự thông báo các giao dịch. Khi một peer thông báo một giao dịch cho một node,
node có thể xóa nó khỏi tập hợp m_tx_inventory_to_send của họ vì nó đã được peer biết và không cần phải thông báo nữa. Điều này có nghĩa là các tập hợp cho spy node thậm chí còn lớn hơn và mất nhiều thời gian hơn để sắp xếp vì chúng bị rút cạn chậm hơn. Spy node, ví dụ: LinkingLion và những node khác, là phổ biến và thường có nhiều kết nối mở song song với một node. Đôi khi, tôi đếm được nhiều spy node được giả định hơn là các kết nối node không phải spy node đến các node của tôi.


Lượng giao dịch khổng lồ được phát sóng, kết hợp với sự khuếch đại bởi spy node và việc sắp xếp không tối ưu các tập hợp m_tx_inventory_to_send lớn bởi CTxMemPool::CompareDepthAndScore() đã khiến các node dành nhiều thời gian để tạo mới
các tin nhắn inventory cho việc chuyển tiếp giao dịch. Vì việc xử lý tin nhắn là đơn luồng, nên việc giao tiếp với các peer khác đã bị chậm lại đáng kể. Điều này đạt đến một điểm mà các block không được xử lý một cách kịp thời và một số kết nối đã hết thời gian chờ.


Sửa lỗi


Bản sửa lỗi có hai phần. Đầu tiên, tất cả các giao dịch sắp được thông báo đã được khai thác hoặc vì một số lý do khác không còn trong mempool nữa, đã bị xóa trước khi tập hợp m_tx_inventory_to_send được sắp xếp. Trước đây, các giao dịch này chỉ bị xóa sau khi tập hợp được sắp xếp. Điều này tránh mất thời gian sắp xếp các mục giao dịch sẽ không bao giờ được thông báo và giảm kích thước của tập hợp sắp được sắp xếp. Thứ hai, khi các tập hợp m_tx_inventory_to_send lớn, số lượng mục cần rút cạn khỏi tập hợp sẽ tăng lên động dựa trên kích thước tập hợp. Điều này có nghĩa là khi nhiều giao dịch được phát sóng, một node sẽ thông báo nhiều giao dịch hơn cho các peer của nó cho đến khi các tập hợp nhỏ hơn trở lại. Bản sửa lỗi đã được backport kịp thời cho bản phát hành v25.0 vào cuối tháng 5 năm 2023.


Suy ngẫm


Mặc dù một nhóm những người đóng góp thường xuyên biết rằng điều này đang xảy ra, nhưng vấn đề này không được công khai cho công chúng. Vấn đề sử dụng CPU 100% với chế độ debug được thảo luận cùng lúc đã gây ra sự nhầm lẫn, ngay cả giữa những người đóng góp Bitcoin Core thường xuyên. Vào thời điểm đó, tôi có cảm giác rằng điều này có thể và có lẽ nên được sửa chữa một cách lặng lẽ và không cần nhiều công khai trong thời gian hiện tại. Nhìn lại, có lẽ việc công khai và minh bạch hơn với vấn đề này cũng có thể hiệu quả. Số lượng lớn các chương trình phát sóng BRC-20 chỉ kéo dài khoảng một tuần (nhưng điều này đã không được biết trước) và việc khởi động lại node sẽ giúp ích trong một thời gian. Để giảm thiểu vấn đề này, ví dụ: đối với các mining pool không thể nâng cấp lên phiên bản có bản sửa lỗi ngay lập tức (do chạy với các bản vá tùy chỉnh), một danh sách cấm các spy node đã được chuẩn bị, nhưng tôi không biết liệu nó đã từng được sử dụng hay chưa.


Mặc dù không có kênh liên lạc chuyên dụng cho sự kiện này, nhưng một kênh IRC không được liệt kê với những người đóng góp P2P đã được sử dụng và những người đóng góp quan tâm đã được mời hoặc thông báo về các sự kiện thông qua tin nhắn trực tiếp. Theo như tôi biết, không có kênh ứng phó sự cố và tôi không biết liệu một kênh có hữu ích hay không do tính chất đặc biệt và phi tập trung của quá trình phát triển Bitcoin. Không có người đóng góp nào chịu trách nhiệm ứng phó sự cố, nhưng mọi người đều có thể giúp đỡ.


Cá nhân tôi, tôi rất vui vì hệ thống giám sát của mình đã chứng tỏ hữu ích cho việc này. Mặc dù tôi không thiết lập cảnh báo cho các kết nối bị ngắt vào thời điểm đó và chỉ nhận thấy nó bằng cách nhìn vào bảng điều khiển, nhưng nó rất hữu ích. Để xác định chính xác vấn đề, việc có một vài node để thử nghiệm và chạy, ví dụ: perf top trên đó rất hữu ích. Việc giám sát trong tương lai nên bao gồm thời gian ping và cảnh báo về các kết nối bị ngắt.






  1. Tôi đã tăng số lượng kết nối từ 125 kết nối mặc định lên 200. ↩︎




10s Hiểu rõ thị trường crypto
Điều khoảnChính Sách Bảo Mật của chúng tôiSách trắngXác minh chính thứcCookieBlog
sha512-gmb+mMXJiXiv+eWvJ2SAkPYdcx2jn05V/UFSemmQN07Xzi5pn0QhnS09TkRj2IZm/UnUmYV4tRTVwvHiHwY2BQ==
sha512-kYWj302xPe4RCV/dCeCy7bQu1jhBWhkeFeDJid4V8+5qSzhayXq80dsq8c+0s7YFQKiUUIWvHNzduvFJAPANWA==