MỚI: Helius mua lại Light Protocol
Ảnh bìa về các sự cố ngừng hoạt động của Solana
Blog/Nghiên cứu

Toàn bộ lịch sử sự cố ngừng hoạt động của Solana: Nguyên nhân, cách khắc phục và bài học kinh nghiệm

Nhà nghiên cứuLostin trên X
Đọc trong 24 phút

Bíp, bíp, bíp. Bíp, bíp, bíp.

Giấc ngủ của Steven bị phá tan bởi tiếng chuông điện thoại chói tai, kéo anh bật khỏi giấc mơ. Trong bóng tối, màn hình sáng rực và rung liên hồi trên bàn cạnh giường. Bíp, bíp, bíp. Anh rên lên, ngái ngủ dụi mắt rồi với lấy thiết bị. Nheo mắt đọc tin nhắn, anh thấy tim mình chùng xuống—node đã ngừng hoạt động. Không chút do dự, anh bật dậy khỏi giường khi còn chưa mặc xong quần áo, luống cuống mở khóa điện thoại trong lúc thêm nhiều tin nhắn liên tục đổ về. Rồi anh chợt nhận ra—toàn bộ cluster đã ngừng hoạt động.

Đúng vào khoảnh khắc đó, tại nhiều thành phố và múi giờ rải rác trên khắp thế giới, hàng trăm đơn vị vận hành node đang nhìn vào điện thoại và cùng nhận ra một điều: Khoảnh khắc họ lo sợ đã đến—một sự cố ngừng hoạt động.

Giới thiệu

Giống như mọi hệ thống phân tán, Solana phải đối mặt với thực tế rằng chỉ một lỗi triển khai hoặc một trường hợp biên khó phát hiện cũng có thể khiến toàn mạng gặp sự cố. Dù gây gián đoạn, sự cố ngừng hoạt động là điều khó tránh khỏi khi duy trì cơ sở hạ tầng phân tán phức tạp—dù đó là blockchain phi tập trung, sàn giao dịch tập trung hay thậm chí các nhà cung cấp dịch vụ đám mây lớn như Amazon hoặc Microsoft.

Vấn đề không phải là liệu sự cố có xảy ra hay không, mà là khi nào—và mạng sẽ phát triển ra sao để thích ứng và tăng khả năng chống chịu trước các sự cố trong tương lai. Dù đã kiểm thử mô phỏng nghiêm ngặt, vận hành testnet có thưởng và triển khai chương trình săn lỗi tích cực, không hệ thống nào—bất kể được thiết kế tốt đến đâu—có thể dự đoán mọi dạng lỗi có thể xảy ra. Những bài học giá trị nhất đến từ quá trình vận hành thực tế.

Trong năm năm qua, Solana đã trải qua bảy sự cố ngừng hoạt động riêng biệt, trong đó năm sự cố do lỗi client và hai sự cố do mạng không thể xử lý lượng lớn transaction rác. Các phiên bản Solana đầu tiên thiếu những cơ chế quản lý tắc nghẽn quan trọng như phí ưu tiên và thị trường phí cục bộ, vốn về sau được chứng minh là thiết yếu để giảm áp lực lên mạng. Việc thiếu các cơ chế này đã dẫn đến những giai đoạn dài suy giảm hiệu suất và tắc nghẽn trong suốt năm 2022, khi mạng về cơ bản tạo động lực cho hành vi gửi rác.

Bài viết này sẽ phân tích chi tiết từng sự cố ngừng hoạt động của Solana, xem xét nguyên nhân gốc rễ, sự kiện kích hoạt và các biện pháp được áp dụng để khắc phục. Ngoài ra, chúng ta sẽ thảo luận về những khía cạnh chính của việc khởi động lại mạng, báo cáo lỗi cùng các khái niệm nền tảng về lỗi tính sống và tính an toàn. Dù tốt nhất nên đọc các phần theo thứ tự, mỗi phần đều có nội dung độc lập để người đọc có thể chuyển thẳng đến chủ đề hoặc sự cố mà họ quan tâm nhất.

Tính sống và tính an toàn

Theo định lý CAP, còn gọi là Định lý Brewer, một hệ thống phân tán chỉ có thể đạt được hai trong ba thuộc tính sau:

  • Tính nhất quán - Mỗi lần đọc đều thấy mọi lần ghi trước đó.
  • Tính sẵn sàng - Mọi yêu cầu đều nhận được phản hồi.
  • Khả năng chịu phân vùng - Hệ thống tiếp tục hoạt động bất chấp việc mạng bị phân vùng.

Đối với blockchain, khả năng chịu phân vùng là thiết yếu—gián đoạn mạng là điều không thể tránh khỏi. Điều này buộc hệ thống phải lựa chọn giữa AP (Tính sẵn sàng + Khả năng chịu phân vùng) và CP (Tính nhất quán + Khả năng chịu phân vùng). Giống phần lớn chuỗi PoS có tính chung cuộc nhanh, Solana ưu tiên tính nhất quán hơn tính sẵn sàng, nên đây là một hệ thống CP. Mạng sẽ dừng khi xảy ra lỗi nghiêm trọng thay vì cung cấp dữ liệu cũ hoặc cho phép các thao tác ghi không an toàn. Dù điều này đồng nghĩa phần mềm node có thể rơi vào trạng thái không thể tự phục hồi và cần can thiệp thủ công, nó bảo đảm tiền của người dùng vẫn an toàn.

Lỗi tính sống: xảy ra khi blockchain ngừng tiến triển, khiến transaction không thể được xác nhận và block không thể được tạo do validator ngừng hoạt động, mạng bị phân vùng hoặc đồng thuận đình trệ. Trong bối cảnh định lý CAP, điều này tương ứng với việc mất tính sẵn sàng.

Lỗi tính an toàn: xảy ra khi trạng thái đã hoàn tất của blockchain bị thay đổi hoặc phân nhánh không đúng cách. Điều này có thể dẫn đến lịch sử xung đột hoặc chi tiêu hai lần, thường do lỗi đồng thuận hoặc cuộc tấn công độc hại gây ra. Trong bối cảnh định lý CAP, điều này tương ứng với việc mất tính nhất quán. 

Solana ưu tiên tính an toàn hơn tính sống. Vì vậy, mạng sẽ dừng trong trường hợp chịu áp lực cực lớn hoặc đồng thuận thất bại thay vì chấp nhận nguy cơ trạng thái bị hỏng. Dù sự cố ngừng hoạt động gây gián đoạn và có thể ảnh hưởng đến ứng dụng, người dùng và validator, hậu quả này vẫn ít nghiêm trọng hơn thảm họa từ một sổ cái không nhất quán hoặc bị hỏng.

Khởi động lại mạng

Để khởi động lại mạng Solana, cần xác định slot block được xác nhận lạc quan gần nhất và khởi động lại các node từ snapshot trạng thái cục bộ đáng tin cậy của slot đó. Vì slot khởi động lại không được xác định on-chain, các đơn vị vận hành validator phải đạt đồng thuận off-chain về một điểm rollback an toàn. Quá trình phối hợp này diễn ra công khai trong kênh #mb-validators trên Solana Tech Discord, nơi các đơn vị vận hành validator chuyên nghiệp trao đổi theo thời gian thực. Phần lớn đơn vị vận hành có hệ thống cảnh báo tự động để thông báo ngay khi quá trình sản xuất block dừng lại, bảo đảm phản ứng nhanh chóng.

Sau khi đạt đồng thuận về slot khởi động lại chính xác, các đơn vị vận hành sử dụng công cụ ledger để tạo snapshot cục bộ mới, khởi động lại validator và chờ ít nhất 80% tổng stake hoạt động trở lại. Chỉ khi đó mạng mới tiếp tục sản xuất và xác thực block. Việc xác minh rằng tối đa chỉ 20% stake ngoại tuyến khi cluster khởi động lại sẽ bảo đảm biên an toàn đủ lớn để mạng tiếp tục hoạt động trong trường hợp các node phân nhánh hoặc lại ngoại tuyến ngay sau khi khởi động lại.

Báo cáo lỗi

Các chương trình săn lỗi thưởng cho nhà nghiên cứu bảo mật khi họ phát hiện và báo cáo lỗ hổng phần mềm. Đây là một tuyến phòng thủ thiết yếu vì chủ động tạo động lực phát hiện lỗi trước khi chúng bị khai thác. Các nhà nghiên cứu bảo mật và nhà phát triển phát hiện lỗ hổng tiềm ẩn trong client Agave được khuyến khích báo cáo qua các kênh bảo mật phù hợp. Hướng dẫn công bố chi tiết có trong kho lưu trữ GitHub của Agave. 

Các báo cáo hợp lệ về lỗ hổng nghiêm trọng sẽ được trao thưởng, với mức thưởng dựa trên độ nghiêm trọng:

  • Mất tiền: Tối đa 25.000 SOL
  • Vi phạm đồng thuận hoặc tính an toàn: Tối đa 12.500 SOL
  • Lỗi tính sống hoặc mất tính sẵn sàng: Tối đa 5.000 SOL

Ngoài ra, client FireDancer có một chương trình săn lỗi riêng được tổ chức thông qua Immunefi, với phần thưởng tối đa 500.000 USDC cho các phát hiện nghiêm trọng.

Các sự cố ngừng hoạt động

Các phần sau cung cấp phân tích chi tiết theo trình tự thời gian về những sự cố ngừng hoạt động và giai đoạn suy giảm hiệu suất của Solana, bắt đầu từ khi Mainnet Beta ra mắt vào ngày 16 tháng 3 năm 2020. Phân tích này sẽ nêu bật các sự cố chính, nguyên nhân gốc rễ và những cải tiến tiếp theo của mạng, qua đó cho thấy Solana đã phát triển ra sao để tăng cường độ ổn định và khả năng phục hồi theo thời gian.

Lỗi Turbine: Tháng 12 năm 2020

Thời gian ngừng hoạt động: Khoảng sáu giờ

Vấn đề gốc rễ: Lỗi truyền block

Cách khắc phục: 

  • Theo dõi block bằng hash thay vì số slot
  • Khắc phục các vị trí trong Turbine nơi có thể phát hiện lỗi sớm hơn
  • Truyền lỗi đầu tiên được phát hiện đến mọi validator qua gossip

Sự cố này bắt nguồn từ một vấn đề đã được biết đến trước đó về sửa chữa block và xử lý mã do một lỗi chưa xác định trong Turbine, cơ chế truyền block của Solana kích hoạt. Lỗi xảy ra khi một validator truyền hai block khác nhau cho cùng một slot và gửi chúng đến hai phân vùng riêng biệt (A và B), trong khi phân vùng thứ ba độc lập phát hiện sự không nhất quán.

Vì mỗi phân vùng chỉ nắm giữ thiểu số stake, không phân vùng nào có thể đạt đồng thuận siêu đa số để chuỗi tiếp tục tiến triển. Vấn đề nền tảng bắt nguồn từ cách cấu trúc dữ liệu nội bộ của Solana theo dõi block và trạng thái được tính toán của chúng. Hệ thống dùng số slot Proof of History (PoH) (một mã định danh u64) để tham chiếu trạng thái và block tại slot đó. Khi mạng bị chia thành các phân vùng, các node hiểu nhầm block A và B là giống nhau, khiến việc sửa chữa và đồng bộ block không thể diễn ra đúng cách.

Mỗi phân vùng đều cho rằng phân vùng kia có cùng một block, dẫn đến xung đột căn bản:

  • Các node giữ block A từ chối những fork bắt nguồn từ block B
  • Các node giữ block B từ chối những fork bắt nguồn từ block A

Do chuyển đổi trạng thái giữa các phân vùng khác nhau, validator không thể sửa chữa hoặc dung hòa các fork, khiến mạng không thể đạt tính chung cuộc.

Biện pháp khắc phục là cho phép các dịch vụ theo dõi block bằng hash thay vì số slot. Nếu có bất kỳ số lượng block nào cho cùng một slot tạo ra các phân vùng, chúng sẽ được xử lý giống như các phân vùng có block nằm ở những slot khác nhau. Các node sẽ có thể sửa chữa mọi fork khả dĩ và cơ chế đồng thuận sẽ có thể giải quyết các phân vùng.

Dù lỗi là nguyên nhân ban đầu của sự cố, phần lớn thời gian ngừng hoạt động là do phải chờ đủ trọng số stake hoạt động trở lại, vì Solana yêu cầu ít nhất 80% stake tham gia để tiếp tục sản xuất block.

IDO của Grape Protocol: Tháng 9 năm 2021

Thời gian ngừng hoạt động: Mười bảy giờ 

Vấn đề gốc rễ: Tràn bộ nhớ do transaction của bot

Cách khắc phục: 

  • Bỏ qua khóa ghi trên các program
  • Giới hạn tốc độ chuyển tiếp transaction
  • Cho phép cấu hình hành vi thử lại của RPC
  • Ưu tiên transaction bỏ phiếu TPU

Ngày 14 tháng 9 năm 2021, Solana gặp tình trạng đình trệ mạng nghiêm trọng sau khi Grape Protocol ra mắt đợt chào bán DEX ban đầu (IDO) on-chain trên nền tảng gọi vốn cộng đồng Raydium AcceleRaytor. Trong vòng 12 phút kể từ khi IDO bắt đầu, mạng bị quá tải bởi lượng transaction chưa từng có do bot tạo ra và ngừng sản xuất slot gốc. Trên thực tế, các bot này đã thực hiện một cuộc tấn công từ chối dịch vụ phân tán (DDoS), đẩy tải transaction vượt quá khả năng của mạng.

Tại thời điểm tắc nghẽn cao nhất:

  • Một số validator nhận được hơn 300.000 transaction mỗi giây.
  • Dữ liệu transaction thô vượt quá 1 Gbps, với 120.000 gói tin mỗi giây.
  • Lưu lượng đôi khi vượt quá giới hạn vật lý của giao diện mạng, gây mất gói tin tại cổng switch trước cả khi đến validator.

Một trong các bot đã cấu trúc transaction để khóa ghi 18 account quan trọng, bao gồm program token SPL toàn cục và program Serum DEX hiện đã ngừng hoạt động. Điều này chặn mọi transaction tương tác với các account đó, làm giảm nghiêm trọng khả năng xử lý song song của Solana. Thay vì thực thi transaction độc lập, mạng gặp nút thắt cổ chai và phải xử lý tuần tự—khiến tình trạng tắc nghẽn trầm trọng hơn.

Một bản sửa lỗi bỏ qua khóa ghi trên các program đã được phát triển và lên lịch phát hành. Sau đó, quá trình khởi động lại mạng đã kích hoạt bản nâng cấp này, loại bỏ vĩnh viễn hướng tấn công đó.

Trong sự kiện IDO, các validator nhận được lượng lớn transaction do bot tạo ra rồi chuyển tiếp transaction dư thừa đến leader tiếp theo, làm khuếch đại tình trạng tắc nghẽn. Lần khởi động lại mạng đã bổ sung giới hạn tốc độ chuyển tiếp transaction nhằm ngăn các cơn bão transaction trong tương lai làm leader quá tải.

Các node RPC của Solana tự động thử lại transaction thất bại, một tính năng được thiết kế để tăng độ tin cậy. Tuy nhiên, trong điều kiện tắc nghẽn cực độ, cơ chế thử lại này khiến lượng transaction tăng mạnh hơn vì giữ các transaction cũ tiếp tục lưu thông thay vì cho phép mạng phục hồi. Solana 1.8 bổ sung khả năng cấu hình hành vi thử lại của RPC, cho phép ứng dụng tối ưu việc thử lại bằng thời gian hết hạn ngắn hơn và chiến lược backoff theo cấp số nhân.

Khi tắc nghẽn nghiêm trọng, các leader Solana không thể đưa vào những transaction bỏ phiếu vốn rất quan trọng để duy trì đồng thuận. Vì vậy, việc thiếu phiếu bầu đã xác nhận khiến đồng thuận đình trệ và ngừng sản xuất block gốc mới. Các phiên bản client Solana sau đó đã bổ sung cơ chế ưu tiên transaction bỏ phiếu, ngăn chúng bị transaction thông thường lấn át trong những sự kiện tương lai.

Lỗi thứ hai: Tràn số nguyên

Trong quá trình khởi động lại mạng, một vấn đề thứ hai xuất hiện. Các validator báo cáo lượng stake đang hoạt động dao động dữ dội. Vấn đề bắt nguồn từ một lỗi khiến tỷ lệ phần trăm stake bị nhân sai với 100, vượt quá giá trị tối đa có thể biểu diễn. Cơ chế lạm phát đã tạo ra quá nhiều token SOL mới đến mức làm tràn số nguyên không dấu 64 bit. Lỗi nhanh chóng được xác định và vá trước lần khởi động lại thứ hai.

Tắc nghẽn nghiêm trọng: Tháng 1 năm 2022

Thời gian ngừng hoạt động: Không có

Nguyên nhân gốc rễ: Quá nhiều transaction trùng lặp Khắc phục một phần:

  • Các bản phát hành Solana 1.8.12 và 1.8.14
  • Tối ưu cơ chế loại bỏ trùng lặp của SigVerify
  • Cải thiện hiệu suất cache của executor

Từ ngày 6 đến ngày 12 tháng 1 năm 2022, mainnet Solana bị tắc nghẽn nghiêm trọng, dẫn đến suy giảm hiệu suất và gián đoạn một phần. Nguyên nhân là các bot gửi quá nhiều transaction trùng lặp, làm giảm đáng kể công suất mạng. Quá trình xử lý block kéo dài hơn dự kiến, khiến leader tiếp theo phân nhánh và tiếp tục làm giảm thông lượng. Ở thời điểm nghiêm trọng nhất, tỷ lệ transaction thành công giảm tới 70%. Client gặp khó khăn khi xử lý các transaction ngày càng phức tạp và đòi hỏi nhiều tài nguyên tính toán, qua đó bộc lộ hạn chế trong khả năng đáp ứng nhu cầu.

Tình trạng bất ổn tiếp tục xảy ra từ ngày 21 đến ngày 23 tháng 1, cùng với tắc nghẽn kéo dài. Ngày 22 tháng 1, endpoint RPC công khai (https://api.mainnet-beta.solana.com) ngừng hoạt động do bị lạm dụng khi hàng loạt lệnh gọi RPC theo batch làm hệ thống quá tải.

Để giải quyết các vấn đề này, bản phát hành Solana 1.8.12 tập trung riêng vào tình trạng cạn kiệt cache program, còn phiên bản 1.8.14 bổ sung các cải tiến cho cache Sysvar, cơ chế loại bỏ của SigVerify và cơ chế loại bỏ trùng lặp của SigVerify.

Transaction rác từ Candy Machine: Tháng 4 / Tháng 5 năm 2022 

Thời gian ngừng hoạt động: Tám giờ

Vấn đề gốc rễ: Transaction rác từ các account bot

Cách khắc phục:

  • Thuế bot trên program Candy Machine
  • Cải thiện bộ nhớ trong Solana v1.10

Ngày 30 tháng 4 năm 2022, Solana ghi nhận lượng yêu cầu transaction tăng đột biến chưa từng có. Một số node báo cáo đạt sáu triệu yêu cầu mỗi giây, tạo ra hơn 100 Gbps lưu lượng trên mỗi node. Mức tăng này do các bot cố giành NFT mới được mint thông qua program Metaplex Candy Machine. Cơ chế mint này hoạt động theo nguyên tắc ai đến trước được phục vụ trước, tạo động lực kinh tế mạnh mẽ để làm ngập mạng bằng transaction nhằm giành quyền mint.

Khi khối lượng transaction tăng vọt, các validator hết bộ nhớ và gặp sự cố, cuối cùng khiến đồng thuận đình trệ. Thông lượng bỏ phiếu không đủ khiến các block trước đó không thể đạt tính chung cuộc, đồng thời ngăn việc dọn dẹp các fork đã bị bỏ. Kết quả là validator bị quá tải bởi số lượng fork khổng lồ phải đánh giá, vượt quá khả năng xử lý ngay cả sau khi khởi động lại và đòi hỏi can thiệp thủ công để khôi phục mạng.

Dù sự cố này có nhiều điểm tương đồng với sự cố tháng 9 năm 2021, Solana đã thể hiện khả năng phục hồi tốt hơn. Mặc dù nhận nhiều hơn 10.000% yêu cầu transaction so với sự cố trước, mạng vẫn hoạt động lâu hơn đáng kể, phản ánh những cải tiến mà cộng đồng validator đã thực hiện để ứng phó với các thách thức mở rộng trước đó.

Quá trình khởi động lại mạng mất chưa đến 1,5 giờ sau khi các bên thống nhất snapshot chính tắc. Solana v1.10 có các cải tiến về sử dụng bộ nhớ nhằm kéo dài thời gian node có thể chịu được tình trạng đồng thuận chậm hoặc đình trệ. 

Tuy nhiên, các vấn đề nền tảng vẫn chưa được giải quyết. Leader vẫn xử lý những transaction tranh chấp cùng dữ liệu account theo nguyên tắc ai đến trước được phục vụ trước mà không có biện pháp ngăn transaction rác hiệu quả, khiến người dùng không thể chỉ định mức độ khẩn cấp cho transaction. Để giải quyết vấn đề này, ba cơ chế dài hạn đã được đề xuất làm giải pháp thực tế.

Áp dụng QUIC: Trước đây, Solana dựa vào giao thức mạng UDP (User Datagram Protocol) để gửi transaction qua Gulf Stream từ các node RPC đến leader hiện tại. Dù nhanh và hiệu quả, UDP không có kết nối, không hỗ trợ kiểm soát luồng và xác nhận đã nhận. Vì vậy, không có cách hữu hiệu để ngăn cản hoặc giảm thiểu hành vi lạm dụng. Để kiểm soát lưu lượng mạng, giao thức tiếp nhận transaction của validator (tức Fetch Stage của TPU) đã được triển khai lại bằng QUIC.

QUIC cố gắng kết hợp những ưu điểm tốt nhất của cả TCP và UDP. Giao thức này hỗ trợ giao tiếp bất đồng bộ nhanh tương tự UDP, đồng thời có phiên bảo mật và các chiến lược kiểm soát luồng nâng cao của TCP. Nhờ đó, mạng có thể đặt giới hạn cho từng nguồn lưu lượng riêng lẻ để tập trung xử lý transaction hợp lệ. QUIC cũng có khái niệm các stream riêng biệt, nên nếu một transaction bị loại bỏ, nó sẽ không chặn những transaction còn lại. QUIC cuối cùng được tích hợp vào client Solana Labs trong bản phát hành 1.13.4.

Chất lượng dịch vụ theo trọng số stake (SWQoS): Một hệ thống mới ưu tiên lưu lượng mạng dựa trên lượng stake mà validator nắm giữ đã được triển khai, bảo đảm những validator có stake cao hơn có thể gửi transaction hiệu quả hơn. Theo cơ chế này, validator nắm 3% tổng stake có thể gửi tối đa 3% tổng số gói tin đến leader. SWQoS đóng vai trò là biện pháp chống tấn công Sybil, khiến tác nhân độc hại khó làm ngập mạng bằng transaction chất lượng thấp hơn. Cách tiếp cận này thay thế mô hình ai đến trước được phục vụ trước trước đây, vốn chấp nhận transaction không phân biệt nguồn gửi.

Bổ sung phí ưu tiên: Sau khi được tiếp nhận, các transaction vẫn phải cạnh tranh để truy cập dữ liệu account dùng chung. Trước đây, tranh chấp này được xử lý theo nguyên tắc đơn giản là ai đến trước được phục vụ trước, khiến người dùng không có cách thể hiện mức độ khẩn cấp của transaction. Vì bất kỳ ai cũng có thể gửi transaction, việc áp dụng trọng số stake không phù hợp để ưu tiên ở giai đoạn này. Để giải quyết vấn đề, một instruction mới đã được thêm vào program Compute Budget, cho phép người dùng chỉ định khoản phí bổ sung được thu khi thực thi và đưa transaction vào block. Tỷ lệ phí trên đơn vị tính toán quyết định mức ưu tiên thực thi của transaction, bảo đảm cách sắp xếp transaction linh hoạt hơn và dựa trên thị trường.

Thuế bot của Candy Machine

Metaplex nhanh chóng áp dụng mức thuế bot được mã hóa cứng là 0,01 SOL đối với các transaction mint tương tác với program Candy Machine để chống transaction rác do bot tạo ra. Cơ chế chống rác này áp dụng một khoản phí nhỏ nhằm ngăn chặn hành vi độc hại mà không phạt những người dùng hợp lệ vô tình mắc lỗi. Thuế được áp dụng trong các trường hợp cụ thể, bao gồm:

  • Cố mint khi Candy Machine chưa hoạt động
  • Cố mint khi không còn vật phẩm
  • Transaction mà thao tác mint hoặc thiết lập bộ sưu tập không phải instruction cuối cùng
  • Sử dụng ID bộ sưu tập không chính xác
  • Các instruction Set Collection không khớp
  • Người ký và người trả phí không khớp giữa các instruction thiết lập bộ sưu tập và mint
  • Transaction đáng ngờ liên quan đến các program không được phép
  • Cố mint từ Candy Machine được bảo vệ bằng AllowList mà không nắm giữ token allowlist bắt buộc

Biện pháp răn đe kinh tế này tỏ ra rất hiệu quả. Tiền của các bot săn mint nhanh chóng cạn kiệt và hoạt động gửi rác chấm dứt. Chỉ trong vài ngày đầu, các đơn vị vận hành bot đã mất tổng cộng hơn 426 SOL.

Lỗi durable nonce: Tháng 6 năm 2022 

Thời gian ngừng hoạt động: Bốn tiếng rưỡi

Vấn đề gốc rễ: Lỗi durable nonce dẫn đến thất bại đồng thuận 

Cách khắc phục: 

  • Tạm thời vô hiệu hóa transaction durable nonce
  • Cập nhật Solana 1.10.23

Một lỗi runtime cho phép một số transaction durable nonce được xử lý hai lần—một lần dưới dạng transaction thông thường và lần nữa dưới dạng transaction nonce—nếu chúng dùng blockhash gần đây thay vì durable nonce trong trường recent_blockhash. Điều này dẫn đến hành vi không tất định giữa các validator, vì một số node từ chối lần thực thi thứ hai trong khi những node khác chấp nhận. Nghiêm trọng hơn, do hơn một phần ba validator chấp nhận block, hệ thống không thể đạt được đa số hai phần ba cần thiết để đi đến đồng thuận.

Không giống transaction tiêu chuẩn, transaction durable nonce không hết hạn và cần một cơ chế riêng để ngăn thực thi hai lần. Chúng được xử lý tuần tự bằng giá trị nonce on-chain gắn với từng account, được xoay vòng mỗi khi một transaction durable nonce được xử lý. Sau khi xoay vòng, cùng một transaction nonce sẽ không còn hợp lệ.

Để giảm thiểu vấn đề, transaction durable nonce đã tạm thời bị vô hiệu hóa. Sau đó, một bản sửa lỗi được triển khai trong Solana 1.10.23, ngăn thực thi trùng lặp bằng cách tách miền nonce và blockhash. Bản cập nhật bảo đảm rằng khi cập nhật account nonce, blockhash được hash cùng một chuỗi cố định, khiến blockhash không hợp lệ khi dùng làm giá trị nonce. Nhờ đó, transaction đã thực thi một lần dưới dạng transaction thông thường không thể được thực thi lại dưới dạng transaction durable và ngược lại. Ngoài ra, kiểu DurableNonce mới thay thế các giá trị blockhash trước đây trong trạng thái account nonce, tăng tính an toàn kiểu và ngăn các vấn đề tương tự trong tương lai.

Đọc bài viết trước đây trên blog Helius để tìm hiểu thêm về durable nonce và các trường hợp sử dụng.

Lỗi block trùng lặp: Tháng 9 năm 2022

Thời gian ngừng hoạt động: Tám tiếng rưỡi

Vấn đề gốc rễ: Lỗi trong quy tắc chọn fork dẫn đến thất bại đồng thuận

Cách khắc phục: 

  • Bản vá client

Sự cố này xảy ra khi một validator tạo nhầm các block trùng lặp ở cùng độ cao block. Nguyên nhân là cả node chính lẫn node dự phòng của validator đều hoạt động đồng thời, sử dụng cùng danh tính node nhưng đề xuất các block khác nhau. Tình trạng này kéo dài ít nhất 24 giờ trước sự cố, trong thời gian đó mạng vẫn xử lý chính xác các slot leader trùng lặp của validator.

Cuối cùng, cluster dừng lại khi mạng gặp một fork không thể phục hồi do lỗi trong logic chọn fork. Lỗi này ngăn các đơn vị sản xuất block xây dựng trên block trước đó, dẫn đến thất bại đồng thuận.

Fork thường xuyên xuất hiện trên Solana và validator thường giải quyết bằng cách thống nhất theo fork có đa số phiếu bầu (fork nặng nhất). Khi validator chọn sai fork, nó phải chuyển sang fork nặng nhất để duy trì đồng bộ với mạng. Tuy nhiên, trong trường hợp này, validator không thể quay lại bank nặng nhất nếu slot của bank đó trùng với slot mà chúng bỏ phiếu gần nhất. Khiếm khuyết này khiến các validator mắc kẹt, ngăn đồng thuận tiếp tục và cuối cùng khiến mạng dừng hoạt động.

Trong ví dụ trên, validator C bị lỗi tạo các block trùng lặp cho những slot leader từ 5 đến 8. Khi validator G tiếp quản vai trò leader tiếp theo, nó chỉ quan sát thấy một trong các bản trùng lặp và mở rộng fork tương ứng. Tuy nhiên, leader kế tiếp là validator D phát hiện cả hai block trùng lặp từ validator C và quyết định loại bỏ chúng, thay vào đó xây dựng fork trên slot 4.

Khi mạng tiếp tục tiến triển, fork do validator G xây dựng nhận được phiếu bầu từ phần lớn stake và trở thành chuỗi chính tắc. Nhận thấy fork của mình đang thua, validator D cố chuyển sang fork của validator G. Tuy nhiên, quá trình chuyển đổi thất bại do lỗi trong logic chọn fork. Vấn đề phát sinh vì tổ tiên chung của hai fork—một block trùng lặp tại slot 5—không được xử lý đúng cách, khiến validator D không thể nhận ra fork đa số. Kết quả là validator D mắc kẹt trên fork riêng và không thể tham gia lại chuỗi chính.

Vấn đề được giải quyết sau khi đội ngũ cốt lõi xem xét. Một bản vá đã được hợp nhất vào nhánh master và backport sang mọi nhánh phát hành.

Block lớn làm Turbine quá tải: Tháng 2 năm 2023

Thời gian ngừng hoạt động: Gần 19 giờ

Vấn đề gốc rễ: Logic loại bỏ trùng lặp trong các dịch vụ chuyển tiếp shred bị lỗi

Cách khắc phục:

  • Nhiều cải tiến cho logic loại bỏ trùng lặp và bộ lọc của Turbine
  • Thêm bản vá client buộc đơn vị sản xuất block phải hủy nếu tạo ra block lớn

Dịch vụ chuyển tiếp shred tùy chỉnh của một validator gặp trục trặc, truyền một block đặc biệt lớn (gần 150.000 shred), lớn hơn block tiêu chuẩn nhiều bậc độ lớn, trong slot leader của validator đó. Việc này làm quá tải bộ lọc loại bỏ trùng lặp của validator, khiến dữ liệu liên tục được chuyển tiếp lại. Vấn đề trở nên nghiêm trọng hơn khi các block mới được tạo ra và cuối cùng làm bão hòa giao thức.

Lưu lượng mạng bất thường tăng vọt làm Turbine quá tải, buộc dữ liệu block phải được truyền qua giao thức dự phòng Block Repair chậm hơn đáng kể. Mặc dù Turbine được thiết kế để chịu được block lớn bằng cách lọc chúng, các dịch vụ chuyển tiếp shred hoạt động ở thượng nguồn của logic lọc này, làm giảm hiệu quả của nó. Trong giai đoạn suy giảm hiệu suất, các leader block tự động chuyển sang chế độ chỉ bỏ phiếu, một cơ chế an toàn mà trong đó leader loại trừ những transaction kinh tế không phải phiếu bầu.

Nguyên nhân gốc rễ là logic loại bỏ trùng lặp trong các dịch vụ chuyển tiếp shred bị lỗi, không thể ngăn shred dư thừa được truyền lại. Ngoài ra, bộ lọc loại bỏ trùng lặp trong pipeline truyền lại ban đầu không được thiết kế để ngăn vòng lặp trong cây Turbine, khiến vấn đề trầm trọng hơn.

Mạng được khởi động lại thủ công sau khi hạ cấp về phiên bản phần mềm validator ổn định gần nhất đã biết. Để giảm thiểu các vấn đề này, Solana v1.13.7 và v1.14.17 đã bổ sung những cải tiến cho logic loại bỏ trùng lặp, nâng cao khả năng ngăn bộ lọc bão hòa và bảo đảm hiệu suất mạng ổn định hơn.

Vòng lặp biên dịch lại vô hạn: Tháng 2 năm 2024

Thời gian ngừng hoạt động: Gần năm giờ

Vấn đề gốc rễ: Lỗi gây ra vòng lặp biên dịch lại vô hạn trong cache JIT

Cách khắc phục: 

  • Vô hiệu hóa loader cũ trong v1.17.20

Validator Agave dùng cơ chế just-in-time (JIT) để biên dịch mọi program trước khi thực thi các transaction tham chiếu đến chúng. Để tối ưu hiệu suất, đầu ra JIT của các program thường dùng được lưu vào cache, qua đó giảm những lần biên dịch lại không cần thiết. Trong Agave v1.16, cơ chế cache hiện có là LoadedPrograms được thay thế bằng một triển khai mới có tên ExecutorsCache, mang lại nhiều cải tiến về hiệu quả.

LoadedPrograms cung cấp góc nhìn toàn cục và nhận biết fork về các program được lưu trong cache, giảm trùng lặp dữ liệu kế toán và cho phép các thread thực thi transaction cùng nhau tải program mới, qua đó ngăn xung đột biên dịch. Một tính năng quan trọng của hệ thống này là theo dõi slot nơi program bắt đầu hoạt động (được gọi là độ cao slot hiệu lực) để phát hiện cache mất hiệu lực khi dữ liệu program on-chain được cập nhật.

Độ cao slot hiệu lực của phần lớn program được lấy từ slot triển khai, vốn được lưu trong account on-chain của chúng. Tuy nhiên, các program được triển khai bằng loader cũ không lưu lại slot triển khai này trong account. LoadedPrograms gán cho các program đó độ cao slot hiệu lực bằng 0 như một giải pháp tạm thời.

Một ngoại lệ xảy ra khi hệ thống phát hiện instruction triển khai, báo hiệu bytecode của program đã được thay thế. Trong trường hợp này, LoadedPrograms tạm thời chèn một mục có độ cao slot hiệu lực chính xác. Tuy nhiên, vì không có transaction nào tham chiếu mục này, nó rất dễ bị loại khỏi cache. Khi bị loại, đầu ra JIT bị xóa và program được đánh dấu là chưa tải, nhưng độ cao slot hiệu lực vẫn được giữ lại.

Nếu sau đó một transaction tham chiếu program chưa tải này, LoadedPrograms sẽ biên dịch lại và chèn lại một mục tại độ cao slot hiệu lực của nó. Thông thường, việc này sẽ giúp program sẵn sàng thực thi trong vòng lặp tiếp theo. Tuy nhiên, với các program dùng loader cũ, đầu ra JIT mới được gán độ cao slot sentinel bằng 0, đặt nó phía sau mục chưa tải trước đó. Kết quả là LoadedPrograms không bao giờ nhận diện program là đã tải, kích hoạt vòng lặp biên dịch lại liên tục trong mỗi lần lặp.

Trong Agave v1.16, LoadedPrograms không hỗ trợ tải cộng tác, cho phép transaction kích hoạt lỗi được đóng gói vào block. Sau đó, block này được truyền khắp mạng, khiến mọi validator phát lại nó và rơi vào cùng vòng lặp biên dịch lại vô hạn. Vì hơn 95% stake của cluster đang chạy Agave v1.17 trong thời gian xảy ra sự cố, phần lớn validator bị đình trệ tại block này, khiến mạng dừng hoạt động.

Lỗi này đã được xác định vào tuần trước đó trong quá trình điều tra sự cố ngừng hoạt động của cluster Devnet, và một bản vá đã được lên lịch triển khai. Biện pháp giảm thiểu được chọn là backport các thay đổi sang Agave v1.17 và ngay lập tức loại bỏ một feature gate khi mạng khởi động lại. Điều này vô hiệu hóa loader cũ gây ra lỗi, ngăn sự cố tái diễn.

Bản vá lỗ hổng được phối hợp: Tháng 8 năm 2024

Thời gian ngừng hoạt động: Không có

Vấn đề gốc rễ: Giả định không chính xác về căn chỉnh địa chỉ ELF

Cách khắc phục: 

  • Cập nhật bản vá 

Ngày 5 tháng 8, các kỹ sư cốt lõi của Anza nhận được cảnh báo về một lỗ hổng trong client Agave do nhà nghiên cứu bên ngoài báo cáo. Kẻ tấn công có thể khai thác khiếm khuyết này để làm các validator leader gặp sự cố, dẫn đến toàn mạng dừng hoạt động. Để ứng phó, các kỹ sư của Anza nhanh chóng phát triển một bản vá, sau đó được nhiều công ty bảo mật bên thứ ba kiểm tra.

Các program Solana được biên dịch bằng LLVM thành Định dạng thực thi và liên kết (ELF). Lỗ hổng bắt nguồn từ một giả định không chính xác về căn chỉnh địa chỉ trong các tệp ELF được tạo ra. Dù quy trình làm sạch ELF thường thực thi nhiều bước kiểm tra tính toàn vẹn, nó không xác thực việc căn chỉnh section .text. Sơ suất này có thể cho phép một tệp ELF độc hại xác định section .text bị căn chỉnh sai, khiến máy ảo nhảy đến một địa chỉ không hợp lệ. Điều này sẽ gây lỗi phân đoạn trên máy chủ và làm validator gặp sự cố.

Kẻ tấn công có thể khai thác lỗ hổng này bằng cách:

  • Tạo một program Solana độc hại sử dụng opcode CALL_REG.
  • Thao túng tệp ELF để căn chỉnh sai section .text.
  • Triển khai và gọi program trên mạng, khiến các validator gặp sự cố.

Quy trình cập nhật bản vá

Bất kỳ bản cập nhật vá lỗi nào được phát hành công khai cũng sẽ ngay lập tức làm lộ rõ lỗ hổng cho mọi người. Điều này có thể cho kẻ tấn công đủ thời gian để dịch ngược lỗ hổng và làm mạng ngừng hoạt động trước khi đủ lượng stake nâng cấp. Một lượng validator trọng yếu cần áp dụng mọi bản vá nhanh nhất có thể để tránh tình huống đó.

Đến ngày 7 tháng 8, nhiều thành viên của Solana Foundation đã liên hệ với validator qua tin nhắn riêng trên nhiều nền tảng liên lạc, thông báo về một bản vá quan trọng sắp được phát hành và chia sẻ thông điệp đã hash để xác nhận ngày cùng mã định danh duy nhất của sự cố. Nhiều thành viên nổi bật của Anza, Jito và Solana Foundation đã chia sẻ hash này trên X, GitHub và LinkedIn để xác minh tính chính xác của thông điệp. Ví dụ về hash được chia sẻ: 

Trong ngày tiếp theo, các thành viên cốt lõi tiếp tục liên hệ với validator, nhấn mạnh tính cấp bách và bảo mật. Vào thời điểm đã định trước, 2 giờ chiều UTC ngày 8 tháng 8, các đơn vị vận hành validator nhận được thông điệp tiếp theo chứa hướng dẫn tải xuống, xác minh và áp dụng bản vá. Bản vá được lưu trữ trên kho Github của một kỹ sư Anza đã được biết đến, thay vì kho Agave chính. Hướng dẫn bao gồm việc xác minh các tệp bản vá đã tải xuống dựa trên shasum được cung cấp.

Đến 8 giờ tối UTC ngày 8 tháng 8, một siêu đa số stake đã được vá, bảo đảm an ninh mạng. Sau đó, lỗ hổng và bản vá tương ứng được công bố công khai, kèm lời kêu gọi mọi validator còn lại nâng cấp.

Việc âm thầm phân phối bản vá và phối hợp hậu trường giữa các validator làm dấy lên lo ngại về tính phi tập trung của Solana. Không lâu sau sự việc, giám đốc điều hành của Solana Foundation, Dan Albert, đã phản hồi những chỉ trích này trong một cuộc phỏng vấn với truyền thông.

“Tôi cho rằng điều quan trọng là không được nhầm lẫn giữa sự tập trung hóa và khả năng phối hợp. Có 1.500 node sản xuất block trên khắp thế giới, do gần như tương ứng từng ấy cá nhân vận hành…. Khả năng tự nguyện liên lạc với họ, hoặc một số người trong số họ, không nên bị nhầm lẫn với sự tập trung hóa.”

Tôi cho rằng điều quan trọng là không được nhầm lẫn giữa sự tập trung hóa và khả năng phối hợp. Có 1.500 node sản xuất block trên khắp thế giới, do gần như tương ứng từng ấy cá nhân vận hành…. Khả năng tự nguyện liên lạc với họ, hoặc một số người trong số họ, không nên bị nhầm lẫn với sự tập trung hóa.

Dan Albert
Dan Albert
Giám đốc điều hành, Solana Foundation

Kết luận

Tại thời điểm bài viết này được thực hiện, Solana đã trải qua hơn một năm không gặp sự cố ngừng hoạt động, đạt một cột mốc quan trọng để gỡ nhãn “beta” khỏi mainnet-beta. Tần suất sự cố có vẻ đang giảm khi mạng trưởng thành, và Firedancer được kỳ vọng sẽ tăng tính đa dạng của client, giảm nguy cơ lỗi chưa được phát hiện hoặc trường hợp biên gây dừng toàn bộ cluster. Tuy nhiên, một số lãnh đạo cộng đồng, bao gồm nhà sáng lập Helius Mert Mumtaz, dự đoán rằng sự cố ngừng hoạt động sẽ tiếp diễn. Thời gian sẽ trả lời.

Xin chân thành cảm ơn Zantetsu (Shinobi Systems) và OxIchigo đã đánh giá các phiên bản trước của bài viết này.

Tài nguyên khác

Đăng ký nhận tin từ Helius

Luôn cập nhật những thông tin mới nhất về phát triển Solana và nhận thông báo khi chúng tôi đăng bài

Hình ảnh phóng to