MỚI: Helius mua lại Light Protocol
Cách xử lý lỗi blockhash trên Solana
Blog/Phát triển

Cách xử lý lỗi blockhash trên Solana

Kỹ sư Trải nghiệm Nhà phát triểnOwen Venter trên XOwen Venter trên LinkedIn
Đọc trong 7 phút

Blockhash là gì?

Để hiểu blockhash là gì, trước tiên bạn cần hiểu slot và khối là gì.

  • Slot là một khoảng thời gian mà trình xác thực có thể tạo ra một khối 
  • Khối là tập hợp các giao dịch và siêu dữ liệu mà trình xác thực xử lý. Siêu dữ liệu trong mỗi khối liên kết khối đó với khối trước, qua đó tạo thành một chuỗi.

Điều quan trọng cần hiểu là mỗi slot kéo dài từ 400 đến 600ms và trong mỗi slot, một trình xác thực có thể đề xuất một khối mới. Nếu không có khối nào được tạo, slot sẽ tăng lên và một trình xác thực khác sẽ cố gắng tạo khối mới. Điều này có nghĩa là không phải slot nào cũng có khối tương ứng, nhưng mọi khối đều có slot tương ứng nơi chúng được đề xuất.

Vậy blockhash là gì? Blockhash là giá trị băm duy nhất của tất cả các mục trong sổ cái blockchain được tạo trong một slot. Giá trị này được tính từ ID của mục cuối cùng trong khối. Mỗi khối được tạo ra sẽ cho một blockhash duy nhất. Các blockhash này được dùng làm dấu thời gian.

Các mức cam kết của Solana là gì?

Một khái niệm quan trọng khác cần hiểu là các mức cam kết. Các mức cam kết này đo lường mức độ xác nhận của mạng đối với một khối cụ thể. Ba tùy chọn là processed, confirmed và finalized.

Khi một trình xác thực gửi khối lên chuỗi, khối đó sẽ ở trạng thái processed. Sau khi đủ số lượng trình xác thực (66% số trình xác thực) bỏ phiếu để đưa khối vào chuỗi, khối sẽ được thêm vào chuỗi và mức cam kết chuyển thành confirmed. Sau khi có thêm 31 khối được xây dựng trên khối này, mức cam kết chuyển thành finalized.

Tại sao lỗi blockhash xảy ra?

Mọi giao dịch đều chứa một blockhash gần đây đóng vai trò là dấu thời gian, và giao dịch đó sẽ hết hạn khi blockhash không còn được xem là đủ mới. Các trình xác thực xử lý giao dịch sẽ kiểm tra “BlockhashQueue” (danh sách 300 blockhash gần nhất) để xác định blockhash của giao dịch có đủ mới hay không. Nếu blockhash không có trong danh sách, giao dịch sẽ bị từ chối. Vì mỗi slot thường kéo dài từ 400ms đến 600ms, một blockhash sẽ còn hiệu lực trong 60–90 giây.

Không tìm thấy blockhash (Mô phỏng giao dịch thất bại: Không tìm thấy blockhash)

Lỗi “ Không tìm thấy blockhash" xảy ra khi blockhash có trong giao dịch không được xem là hợp lệ tại thời điểm trình xác thực xử lý giao dịch. Nguyên nhân có thể là blockhash quá cũ hoặc trong một số trường hợp, quá mới. 

Nguyên nhân phổ biến nhất của lỗi này là blockhash có trong giao dịch không xuất hiện trong hàng đợi 300 blockhash gần nhất mà trình xác thực dùng để đối chiếu. Điều này sẽ gây ra lỗi không tìm thấy blockhash. Giao dịch có thể hết hạn khi được tạo nhưng không được xử lý trong khoảng thời gian quy định. Điều này có thể xảy ra do người dùng mất quá nhiều thời gian để ký giao dịch. Cũng có thể xảy ra trường hợp một giao dịch hợp lệ đã được gửi nhưng không được đưa vào khối hiện tại; đến khi có thể được đưa vào một khối sau đó, blockhash của giao dịch đã quá cũ.

Trong những tình huống như vậy, khi giao dịch trên thực tế đã hết hạn, bạn thường sẽ gặp lỗi vượt quá độ cao khối (TransactionExpiredBlock heightExceededError). Để hiểu rõ hơn về lỗi này, cần biết độ cao khối có nghĩa là gì. Độ cao khối là số lượng khối nằm bên dưới khối hiện tại. Nếu khối hiện tại là khối 1000 thì độ cao khối là 1000. Khi một giao dịch được tạo, hệ thống sẽ ghi lại độ cao khối tối đa mà giao dịch đó còn hiệu lực. Nếu trong khi xử lý giao dịch, độ cao khối hiện tại được xác định là cao hơn độ cao khối hợp lệ tối đa của giao dịch, lỗi sẽ được trả về.

Một tình huống khác có thể gây ra “lỗi không tìm thấy blockhash” là khi blockhash của giao dịch mới hơn blockhash được dùng để kiểm tra thời điểm hết hạn của giao dịch đó. Điều này hơi khó hiểu, vì vậy hãy xem ví dụ sau: Bạn tạo một giao dịch và thêm blockhash của một khối cụ thể, giả sử là khối 1000, rồi lập tức gửi giao dịch đó đến một RPC. RPC có thể lấy blockhash của khối trước đó, trong trường hợp này có thể là khối 999 (do RPC sử dụng mức cam kết cao hơn hoặc node RPC đang chậm hơn mạng). Vì vậy, hệ thống sẽ không tìm thấy blockhash trong giao dịch. Đây là tình huống bất thường nhưng có thể xảy ra trong hai trường hợp:

1. Mức cam kết không khớp

Khi tạo giao dịch, mức cam kết confirmed được sử dụng, nhưng khi RPC tính toán tính hợp lệ của giao dịch, mặc định RPC lại sử dụng mức finalized.

Điều này có thể khiến blockhash dùng để kiểm tra cũ hơn blockhash của giao dịch, vì các khối finalized “chậm hơn” khối mới nhất 31 khối.

Nếu mức cam kết processed được dùng để lấy blockhash cho một giao dịch trên nhánh thiểu số mà sau đó bị loại bỏ, blockhash sẽ không hợp lệ và không được tìm thấy trong quá trình xử lý.

2. RPC không khớp

Nếu sử dụng hai RPC khác nhau để lấy blockhash và gửi giao dịch, bất kỳ độ trễ nào ở RPC gửi giao dịch cũng có thể khiến khối mà RPC đó dùng để kiểm tra tính hợp lệ cũ hơn khối được dùng khi tạo giao dịch.

Cách khắc phục lỗi blockhash

Bạn có thể thực hiện một số bước để xử lý từng tình huống nêu trên.

1. Đảm bảo giao dịch được gửi với blockhash không quá cũ:

Sử dụng mức cam kết confirmed khi lấy blockhash cho giao dịch, vì mức này đảm bảo blockhash được thêm vào mới hơn so với khi sử dụng mức cam kết finalized.

Bạn cũng có thể sử dụng mức cam kết processed để lấy blockhash mới hơn một chút, nhưng khoảng 5% số khối đã xử lý không được cụm mạng finalized. Điều này đồng nghĩa với việc blockhash của giao dịch sẽ thuộc về một nhánh đã bị loại bỏ và không còn hợp lệ.

2. Đảm bảo blockhash của giao dịch không mới hơn blockhash được dùng để kiểm tra tính hợp lệ của giao dịch:

Luôn đặt preflightCommitment (ngay cả khi sử dụng skipPreflight) thành cùng mức cam kết được dùng để lấy blockhash của giao dịch. Điều này giúp tránh trường hợp blockhash của giao dịch mới hơn blockhash được dùng để kiểm tra tính hợp lệ của giao dịch.

Để xử lý các node RPC bị chậm khi gửi giao dịch, bạn nên tiếp tục gửi lại giao dịch đến RPC. Có thể thực hiện việc này theo một khoảng thời gian cố định để nếu RPC bị chậm, cuối cùng nó sẽ bắt kịp và phát hiện giao dịch đã hết hạn.

Nếu sử dụng yêu cầu simulateTransaction, bạn nên đặt tham số replaceRecentBlockhash. Cờ này yêu cầu RPC thay thế blockhash của giao dịch được mô phỏng bằng một blockhash luôn hợp lệ cho quá trình mô phỏng.

3. Tiếp tục thử lại giao dịch trong khi blockhash vẫn còn hiệu lực:

Khi tạo giao dịch và lấy blockhash mới nhất, bạn nên ghi lại lastValidBlockHeight của blockhash đó. Sau đó, bạn có thể tiếp tục thử lại giao dịch với blockhash này cho đến khi độ cao khối hiện tại vượt quá độ cao khối hợp lệ của giao dịch. Có thể sử dụng lệnh gọi RPC getBlockHeight để liên tục kiểm tra xem giao dịch còn hợp lệ hay không. Khi độ cao khối hiện tại cao hơn độ cao lastValidBlock của giao dịch, bạn nên lấy và sử dụng một blockhash mới.

Hy vọng bài viết này giúp bạn hiểu rõ hơn về lỗi blockhash và cách giảm số lần xảy ra các lỗi này. Nếu có thêm câu hỏi, đừng ngần ngại tham gia cộng đồng Discord của chúng tôi hoặc nhắn tin trực tiếp cho chúng tôi trên X.

Tài nguyên bổ sung:

‍

Đă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