MỚI: Helius mua lại Light Protocol
Đồng thuận trên Solana
Blog/Kiến thức nền tảng

Đồng thuận trên Solana

Nghiên cứu và Dữ liệuRyan Chern trên X
Đọc trong 23 phút

Những thông tin chuyên sâu có thể áp dụng

  • Vai trò của Proof-of-History (PoH) trong đồng bộ hóa: PoH không phải là thuật toán đồng thuận mà là công cụ được cơ chế đồng thuận của Solana sử dụng để đồng bộ hóa. Tương tự, Proof-of-Stake (PoS) không phải là cơ chế đồng thuận mà thực chất là cơ chế chống tấn công Sybil.
  • Giao dịch bỏ phiếu là cần thiết cho đồng thuận: Các phiếu bầu trong block không phải là giao dịch thừa nhằm thổi phồng chỉ số TPS một cách giả tạo. Nếu phiếu bầu chỉ được truyền qua gossip (giao tiếp ngang hàng, không chính thức), cách các validator nhìn nhận trạng thái Tower (phiếu bầu) có thể không nhất quán.
  • Solana có hai quy tắc xác nhận chính: một quy tắc để chọn fork ngắn hạn (xác nhận lạc quan) và một quy tắc dành cho đồng thuận PoS đầy đủ để đạt tính chung cuộc (finalized/rooted). Client và người dùng có thể tuân theo các quy tắc xác nhận này để đạt được những thuộc tính bảo mật mong muốn và tùy chỉnh lựa chọn UX. Điều này được thể hiện qua hai mức cam kết: “confirmed” và “finalized”.
  • Hiểu rủi ro kiểm duyệt: Validator và nhà phát triển cần nhận thức được nguy cơ xảy ra các cuộc tấn công kiểm duyệt, trong đó một validator cố gắng phá vỡ trình tự sản xuất block. Cần hiểu cơ chế của những cuộc tấn công này cũng như vai trò của sức mạnh tính toán và stake trong việc thực hiện chúng.
  • Các bản nâng cấp giao thức sắp tới: Validator và nhà phát triển nên chủ động chuẩn bị cho những thay đổi sắp tới đối với cơ chế đồng thuận của Solana, chẳng hạn như thực thi bất đồng bộ và slashing theo chương trình.

Giới thiệu

Khi hoạt động trên Solana gia tăng, nhiều lớp trong stack của nền tảng đang được thử thách ở quy mô chưa từng có. Đã có nhiều bài viết và thảo luận về các chủ đề “nóng” như thị trường phí cục bộ, nhưng cơ chế đồng thuận trên Solana từ lâu lại ít được chú ý. Tuy nhiên, khi hoạt động và sự quan tâm gia tăng, cộng đồng cần hiểu thấu đáo về đồng thuận vì động lực thực hiện các cuộc tấn công độc hại và lợi nhuận từ những hành vi khai thác tiềm tàng cũng tăng theo.

Đồng thuận là một trong những khía cạnh quan trọng nhất của Solana mà cộng đồng nói chung cần hiểu, vì nó quyết định cách hàng nghìn validator thống nhất về thứ tự chuẩn tắc của các giao dịch.

Đồng thuận đã được nghiên cứu trong các hệ thống phân tán suốt nhiều năm. Bài toán các vị tướng Byzantine, do Lamport, Shostak và Pease viết, được công bố vào đầu thập niên 1980. Các thuật toán đồng thuận như RAFT từ lâu đã được sử dụng trong web2. Trong lĩnh vực crypto, hầu hết thuật toán đồng thuận là các cách triển khai khác nhau của đồng thuận BFT, bao gồm Gasper (Ethereum), Tendermint (Cosmos), MonadBFT (Monad), HotShot (Espresso) và Narwhal/Tusk (Sui). 

Bài viết này không nhằm chứng minh chính thức cơ chế đồng thuận của Solana (TowerBFT). Thay vào đó, bài viết giải thích cách đồng thuận vận hành trên Solana cho các nhà phát triển và cộng đồng nói chung, vì đến nay chủ đề này chủ yếu mới nằm trong phạm vi hiểu biết của những người đóng góp cho Solana Labs và Firedancer. Bài viết cũng thảo luận một số đánh đổi và hạn chế.

Tổng quan ngắn gọn về đồng thuận

Mục tiêu của một giao thức đồng thuận là đạt được sự thống nhất về các giao dịch và thứ tự tương đối của chúng trong một block. Có hai loại giao thức đồng thuận chính giúp các validator trong mạng thống nhất về thứ tự chuẩn tắc của giao dịch:

  • Giao thức chuỗi dài nhất: các giao thức này, chẳng hạn như đồng thuận Nakamoto của Bitcoin, chọn chuỗi đòi hỏi nhiều nỗ lực tính toán nhất để xây dựng làm chuỗi chuẩn tắc. Dù điều này thường tương quan với chuỗi có nhiều block nhất, mô tả chính xác hơn là chuỗi thể hiện tổng lượng công việc hoặc sức mạnh tính toán tích lũy lớn nhất.
  • Giao thức kiểu BFT: hầu hết giao thức PoS triển khai một phiên bản của thuật toán đồng thuận BFT. Các giao thức này, chẳng hạn như pBFT, dựa vào các ngưỡng về khả năng hoạt động và bảo mật. Tính nhất quán và tính sẵn sàng là hai đảm bảo của định lý CAP, theo đó mọi kho dữ liệu phân tán chỉ có thể cung cấp hai trong ba đảm bảo sau: tính nhất quán, tính sẵn sàng và khả năng chịu phân vùng.

Cả giao thức đồng thuận chuỗi dài nhất lẫn kiểu BFT đều có được tính bảo mật từ các quy tắc xác nhận tương ứng. Tính bảo mật, bao gồm cả an toàn và khả năng hoạt động, bắt nguồn từ một quy tắc xác nhận nhất định chứ không phải là thuộc tính của chuỗi. Theo định nghĩa của Ethereum Foundation, quy tắc xác nhận là “một thuật toán được các node chạy để xác định một block nhất định đã được xác nhận hay chưa. Khi block được xác nhận, nó được đảm bảo sẽ không bao giờ bị tái tổ chức, dựa trên một số giả định, chủ yếu về tính đồng bộ của mạng và tỷ lệ stake trung thực.”

Suy cho cùng, mọi thứ đều dựa trên đồng thuận xã hội, được xác định bởi những người viết mã client để thể hiện điều gì tạo nên tính bảo mật thông qua các quy tắc xác nhận nhất định.

Proof-of-Stake bổ sung các lớp khác vào mô hình BFT, yêu cầu người tham gia đưa stake của mình vào hệ thống. Người tham gia được thưởng khi tuân thủ một bộ quy tắc nhưng có thể bị slashing nếu hành vi sai trái được chứng minh, chẳng hạn như ký hai lần. Cơ chế này được gọi là an toàn có thể quy trách nhiệm và cho phép giao thức xác định, trừng phạt các node độc hại mà không gây tác động ngoại lai lên các node trung thực. Điều này không thay thế cơ chế bảo mật nền tảng của các giao thức đồng thuận BFT: mạng vẫn cần ít hơn một phần ba số node không trung thực để tránh ngừng hoạt động và ít hơn hai phần ba để ngăn việc xác thực giao dịch sai. Hệ thống dựa trên stake áp đặt hậu quả đối với các hành động có thể làm gián đoạn hoặc suy giảm hiệu quả mạng.

Một mạng BFT như vậy có hai ngưỡng quan trọng:

  1. 1/3: Nếu các node không trung thực chiếm từ một phần ba tổng số trở lên, mạng có thể “ngừng hoạt động”. Trong trường hợp này, các node đó có thể đơn giản là không tham gia, khiến phần còn lại không thể đạt siêu đa số hai phần ba cần thiết cho đồng thuận. Do đó, mạng không tạo ra giao dịch sai mà ngừng tạo mọi giao dịch. Một chỉ số phổ biến, dù còn thô, là Hệ số Nakamoto, biểu thị số node tối thiểu cần thiết để gây ra lỗi khả năng hoạt động, tức ngừng sản xuất block.
  2. 2/3: Nếu các node không trung thực chiếm từ hai phần ba tổng số trở lên, chúng có thể thông đồng để xác thực bất kỳ giao dịch nào chúng muốn. Đây là kịch bản tồi tệ nhất, khi mạng không còn vận hành đúng mà xử lý giao dịch theo chỉ thị của siêu đa số không trung thực. Trong trường hợp một bên đối nghịch kiểm soát hơn 67% stake, họ có thể cô lập một node trung thực, chẳng hạn như node của một sàn giao dịch lớn như Binance. Việc cô lập có thể được thực hiện bằng cách thông đồng với trung tâm dữ liệu để hạn chế lưu lượng mạng của node. Sau đó, thực thể độc hại có thể khiến node bị cô lập này hoàn tất một block do mình tạo, đồng thời phân phối một block xung đột đến phần còn lại của mạng. Kiểu tấn công này lợi dụng góc nhìn hạn chế của node bị cô lập, có thể dẫn đến chi tiêu hai lần vì phần còn lại của mạng và node bị cô lập có cách nhìn khác nhau về trạng thái on-chain.

Một cuộc tấn công tương tự vẫn khả thi với lượng stake thấp hơn, trên 33%, nhưng sẽ cần tạo ra phân vùng mạng thay vì chỉ cô lập. Trong tình huống này, bên nắm stake Byzantine có thể lợi dụng phân vùng mạng để thao túng các phần khác nhau của mạng bằng thông tin xung đột, tiếp tục gây nguy cơ chi tiêu hai lần và các lỗi an toàn khác.

Thông thường, số lượng node lớn hơn khiến bất kỳ bên nào muốn chi phối một phần đáng kể để đạt các ngưỡng này gặp nhiều khó khăn hơn, giả định các node được phân tách về địa lý. Tuy nhiên, mong muốn xây dựng mạng lớn hơn thường xung đột với hiệu quả. Số lượng node cao hơn có thể làm chậm quá trình đồng thuận do nhu cầu truyền dữ liệu tăng lên, vì cần nhiều thời gian hơn để truyền phiếu bầu. Một số giao thức còn đặt giới hạn cứng cho số node tối đa.

Proof-of-History (PoH)

Trong khi Proof-of-Stake (PoS) đảm bảo đồng thuận trong mạng, Solana tích hợp Proof of History (PoH) vào cơ chế đồng thuận PoS để đồng bộ hóa quá trình sản xuất block liên tục. Solana thực hiện điều này bằng cách bỏ qua các slot có leader chậm hoặc không phản hồi mà không cần chờ một vòng đồng thuận đồng bộ. PoH không nhằm chứng minh thời điểm chính xác một sự kiện xảy ra, mà chứng minh trình tự và khoảng thời gian trôi qua giữa các sự kiện.

Trái với quan niệm phổ biến, bản thân Proof-of-History (PoH) không phải là cơ chế hay thuật toán đồng thuận. Dù cách triển khai hiện tại của cơ chế đồng thuận sử dụng một số khía cạnh của PoH, về lý thuyết vẫn có thể loại bỏ PoH và thực hiện vài thay đổi nhỏ trong cách triển khai để cơ chế đồng thuận trên Solana tiếp tục hoạt động.

Cốt lõi của PoH là một thuật toán băm đơn giản tương tự Hàm trì hoãn có thể xác minh (VDF), nhưng về mặt kỹ thuật không phải là VDF. Solana triển khai cơ chế này bằng một hàm băm tuần tự chống tìm ảnh trước (SHA-256) chạy liên tục, lấy đầu ra của một lần lặp làm đầu vào cho lần tiếp theo. Phép tính này chạy trên một lõi của mỗi validator.

Mặc dù quá trình tạo chuỗi diễn ra tuần tự và trên một luồng duy nhất, đầu ra có thể được xác minh song song, cho phép xác minh hiệu quả trên các hệ thống đa lõi. Dù tốc độ băm có giới hạn trên, những cải tiến về phần cứng có thể mang lại thêm lợi ích hiệu năng.

Hãy xem xét ví dụ gồm bốn validator trên mạng Solana: Validator A, B, C và D. Trong ví dụ này, lịch leader có thể quy định trình tự sản xuất block là A - B - C - D. Validator A bắt đầu bằng việc tạo một block theo lượt. Để làm vậy, Validator A sử dụng cơ chế PoH, trong đó hàm băm SHA-256 được chạy lặp lại để tạo nên một thang thời gian gồm các “tick”. Quá trình băm này tạo ra bản ghi duy nhất và có thể xác minh về thời gian đã trôi qua, đảm bảo block của Validator A phản ánh chính xác thời gian. Khi Validator A hoàn tất block, đến lượt Validator B tạo block tiếp theo, rồi đến Validator C.

Giả sử Validator C cố gắng phá vỡ trình tự bằng cách phát một block không đúng lượt, nhằm theo ngay sau Validator A và bỏ qua Validator B. Để thay thế Validator B một cách thuyết phục, Validator C cần tái tạo chuỗi băm PoH mà Validator B lẽ ra sẽ tạo, tức phải tạo một chuỗi băm thể hiện khoảng thời gian Validator B cần để sản xuất block. Hiệu năng băm đơn lõi có giới hạn vật lý tối đa. Vì máy tính chỉ có thể tạo một số lượng băm tối đa trong một khoảng thời gian nhất định, ta biết rằng một khoảng thời gian cụ thể đã trôi qua.

Validator C có thể cố kiểm duyệt Validator B trong lịch leader bằng cách tạo một chuỗi block rỗng, bắt đầu từ cuối block hợp lệ trước đó là block của Validator A, mà không chứa giao dịch nào. Để kiểm duyệt B thành công, C phải đáp ứng hai điều kiện. Thứ nhất, C cần đủ sức mạnh tính toán để xử lý chuỗi PoH rỗng. Thứ hai, C phải nhanh chóng phổ biến block của mình đến đủ số node có stake để đảm bảo block được chấp nhận trong slot được chỉ định cho chính C, qua đó kiểm duyệt B một cách hiệu quả. Quá trình này diễn ra nhanh hơn đối với validator có trọng số stake cao nhờ Turbine, hệ thống ưu tiên luồng thông tin theo trọng số stake của validator.

Kịch bản tấn công này khả thi, nhưng khoảng thời gian để kiểm duyệt thành công rất hạn chế. Node tấn công phải sở hữu tài nguyên tính toán đáng kể để băm SHA-256 và một lượng stake lớn, vì số block mà nó có thể tạo tỷ lệ thuận với stake.

Ngoài việc phải tiếp cận mạng nhanh hơn node A, C còn phải tạo hàm băm với tốc độ cao. Cuộc tấn công này chủ yếu nhắm đến trường hợp một validator được chỉ định làm leader tại slot n muốn kiểm duyệt các validator có slot leader trước đó, tức trước n. Mức độ kiểm duyệt mà validator này có thể thực hiện phụ thuộc vào stake, vì khả năng tạo slot leader gắn trực tiếp với lượng stake mà nó nắm giữ.

Cơ chế PoH cũng đảm bảo các block được sản xuất với tốc độ ổn định. Vì mỗi validator có thể xác minh độc lập chuỗi PoH nên không cần đồng bộ thời gian bên ngoài. Chẳng hạn, Ethereum sử dụng Network Time Protocol (NTP) trong mỗi block để đồng thuận. Trên Solana, mỗi validator tự xác minh rằng từng block được sản xuất trong đúng slot thời gian theo cơ chế nội sinh mà không dùng giao thức bên ngoài.

Tower BFT (Cơ chế đồng thuận của Solana)

Tower BFT, cơ chế đồng thuận của Solana, hoạt động sau khi các shred (block thành phần) đã được truyền đến những validator khác:

Như đã đề cập, Solana chạy Tower BFT cùng với Proof-of-History. Tower BFT là một thuật toán đồng thuận giống pBFT, được thiết kế để tận dụng các phép tính đồng hồ đồng bộ từ Proof-of-History. Cơ chế này thiết lập một đồng hồ chung trên toàn mạng, cho phép mạng bỏ qua hiệu quả các slot được gán cho leader chậm hoặc không phản hồi. Nhờ đó, mạng không cần trải qua một vòng đồng thuận đồng bộ cho mỗi slot và có thể sản xuất block liên tục, vì validator không phải chờ block trước đó đến rồi mới xây dựng block tiếp theo.

Một quan niệm sai lầm khác là cơ chế đồng thuận của Solana hiện đã triển khai slashing theo chương trình. Dù slashing có trong lộ trình, mạng hiện sẽ ngừng hoạt động sau khi xảy ra vi phạm an toàn và dựa vào đồng thuận xã hội để thực hiện slashing khi cần.

Cơ chế đồng thuận của Solana trao mức độ ảnh hưởng khác nhau cho từng node. Các phiếu bầu trong mạng không ngang nhau mà được tính trọng số theo stake của từng node, dựa trên cùng các nguyên tắc của QoS theo trọng số stake và Turbine. Khi các yếu tố khác như nhau, node có stake lớn hơn sẽ có nhiều ảnh hưởng hơn trong việc xác định đồng thuận chuẩn tắc so với node có stake nhỏ hơn.

Ví dụ, trong một mạng có bốn node nắm giữ tổng cộng 100 đơn vị stake, cách phân bổ và mức ảnh hưởng có thể như sau:

  • Node A có 10 đơn vị stake.
  • Node B có 20 đơn vị stake.
  • Node C có 30 đơn vị stake.
  • Node D có 40 đơn vị stake.

Trong cấu hình này, năng lực của từng nhóm node không trung thực là khác nhau. Một node duy nhất như Node D có thể khiến mạng ngừng hoạt động dù chỉ chiếm 25% tổng số node, do node này có lượng stake lớn. Tương tự, tổ hợp Node C và D có thể phê duyệt các giao dịch sai dù chỉ chiếm 50% số node, vì chúng nắm giữ đủ stake để tác động đến kết quả.

Có thể đạt ngưỡng một phần ba khiến mạng ngừng hoạt động thông qua các node không trung thực, bị xâm phạm hoặc bị chặn. Tuy nhiên, ngưỡng hai phần ba để xác thực giao dịch sai đòi hỏi sự thông đồng chủ động và không thể chỉ dựa vào việc chặn các node trung thực. Do đó, việc đạt ngưỡng sau khó hơn đáng kể. Lý do là phải làm tha hóa hoặc xâm phạm các node để chúng chủ động tham gia kế hoạch gian lận, thay vì chỉ chặn các node trung thực.

Bối cảnh trong các slot

Trên Solana, các slot leader được chỉ định bốn slot liên tiếp, kéo dài tổng cộng khoảng 1,6 giây (4 block x 400 ms mỗi block). Leader được chọn vào đầu mỗi epoch (432.000 slot hoặc ~2-3 ngày). Lịch leader được chọn ngẫu nhiên theo trọng số stake của validator.

Leader chịu trách nhiệm xây dựng và đề xuất một block mới cho từng slot được chỉ định. Không có sự tách biệt giữa proposer và builder như trong hệ sinh thái Ethereum. Các validator khác chứng thực tính hợp lệ của một block thông qua giao dịch bỏ phiếu bằng cách áp dụng quy tắc chọn fork cho góc nhìn cục bộ của mình về phần đầu mạng Solana.

Leader phải công bố block trong một phạm vi tick PoH nhất định để block đó hợp lệ; block không được công bố trong phạm vi này sẽ được coi là bị bỏ qua.

Hãy xem ví dụ sau về lịch leader có bốn bên tham gia (A, B, C, D), trong đó D cố phá vỡ trình tự. Nếu D tìm cách can thiệp trong lượt của C, D phải tạo một chuỗi tick PoH có tác dụng bỏ qua block của C, dẫn đến một chuỗi như sau:

A - B - [thiếu C] - D.

Trong trường hợp thiếu block của C, một D trung thực sẽ phải tạo chuỗi PoH bao phủ toàn bộ thời lượng slot của C trước khi bắt đầu slot của mình. Điều này khiến block của D có vẻ hợp lệ vì nó theo sau block của B sau khi thời gian dành cho slot của C đã trôi qua.

Trong khi D tạo chuỗi PoH cho slot của C, thông thường C sẽ truyền trực tiếp block của mình, kết nối với block của B bằng một chuỗi PoH phù hợp. Điều này dẫn đến hai kết quả có thể xảy ra:

  • Nếu quá trình tính PoH của D không nhanh hơn C: Khi C hoàn tất block vào khoảng thời điểm D bắt đầu phát block của mình, mạng đã nhìn thấy block của C và sẽ từ chối block của D.
  • Nếu D tính PoH nhanh hơn C: D bắt đầu phát block trước khi C hoàn tất block của mình. Dù vậy, D vẫn phải nhanh hơn C đáng kể mới có thể tác động rõ rệt đến trình tự. Điều này khó xảy ra do các CPU mà validator sử dụng để tính SHA-256 có tốc độ cao và giới hạn năng lực trên tương đối giống nhau.

Trong cả hai trường hợp, khả năng D thay thế C thành công đều rất thấp. Hơn nữa, nếu nỗ lực thay thế C thất bại, D sẽ mất cơ hội phát block trong slot của chính mình. Việc phát một block ngay sau B rồi thử phát block khác sau C cấu thành vi phạm vì tạo hai block cho slot của D, dẫn đến hành vi có thể bị slashing. Mỗi lần thử thất bại khiến D bỏ lỡ cơ hội tự sản xuất block, cho thấy đây khó có thể là chiến lược mà D theo đuổi. 

Từ góc nhìn của mạng, không thể xác định ý định của D. Rất khó, nếu không muốn nói là không thể, phân biệt giữa việc D đơn giản là không nhìn thấy block của C mà không có ý định kiểm duyệt C, và việc D có ý định kiểm duyệt B. Do đó, hành vi này không dễ phát hiện và mạng không thể trừng phạt.

Giao dịch bỏ phiếu

Cơ chế đồng thuận của Solana dựa vào giao dịch bỏ phiếu để đạt đồng thuận. Giao dịch bỏ phiếu nằm trong block nhưng được ưu tiên để không bị các giao dịch thông thường lấn át. Hiện tại, phần lớn giao dịch trong một block nhất định là giao dịch bỏ phiếu:

Tuy nhiên, điều này có thể không phải lúc nào cũng đúng, vì tỷ lệ giao dịch bỏ phiếu trong một block thể hiện tỷ lệ giữa mức độ hoạt động và số validator tham gia đồng thuận. Trong tương lai, giao dịch bỏ phiếu có thể chỉ chiếm thiểu số trong một block.

Giao dịch bỏ phiếu là yêu cầu cần thiết cho đồng thuận — chúng không phải là giao dịch thừa nhằm thổi phồng chỉ số TPS một cách giả tạo. Nếu phiếu bầu chỉ được truyền qua gossip (giao tiếp ngang hàng, không chính thức), cách các validator nhìn nhận trạng thái Tower (phiếu bầu) có thể không nhất quán. Sự khác biệt này có thể khiến các validator có quan điểm khác nhau về fork nào có nhiều khả năng là fork đúng, dẫn đến nguy cơ phân kỳ khi validator đưa ra lựa chọn tham lam dựa trên thông tin không đầy đủ hoặc không nhất quán. Sản xuất block liên tục đòi hỏi bỏ phiếu liên tục, đặc biệt khi các block trước đó vẫn đang được xác nhận. Điều này yêu cầu một góc nhìn đáng tin cậy và nhất quán về trạng thái của Tower.

Giống như các giao dịch thông thường do người dùng khởi tạo, giao dịch bỏ phiếu cũng phải trả phí cơ sở (0,000005 SOL). Khoản phí này do danh tính validator thanh toán. Danh tính này phải nằm trong ví nóng để ký liên tục, trong khi tài khoản bỏ phiếu được dùng để tra cứu tài khoản và ủy quyền.

Mỗi phiếu bầu do validator ký đều chứa khóa công khai của validator và hàm băm của block mà họ bỏ phiếu.

Khi một validator nhận được nhiều block cho cùng một slot, validator sẽ theo dõi mọi fork có thể có cho đến khi xác định được fork “tốt nhất”. Validator chạy cục bộ hàm chuyển đổi trạng thái liên quan, điều này sẽ thay đổi khi áp dụng thực thi bất đồng bộ, rồi bỏ phiếu cho các block mới sau khi phát lại. Validator thể hiện phiếu bầu cho một fork nhất định qua các giao dịch bỏ phiếu on-chain.

Trong mỗi giao dịch bỏ phiếu, validator công bố phiếu bầu kèm thời gian khóa. Thời gian khóa này đóng vai trò là cơ chế cam kết, ràng buộc validator với fork đã chọn và áp đặt chi phí cơ hội cho quyết định của họ. Hiện nay, thời gian khóa không được runtime thực thi mà được thực thi thông qua đồng thuận xã hội. Validator liên tục vi phạm thời gian khóa bỏ phiếu rất có thể sẽ bị slashing thủ công. Slashing theo chương trình đối với hành vi vi phạm thời gian khóa có thể sẽ được bổ sung trong tương lai gần, vì việc không nhận được tín dụng bỏ phiếu chưa tạo ra đủ sức răn đe.

Validator cũng ký hàm băm của block cho mọi block tổ tiên nằm giữa phiếu bầu trước đó và các block đã rooted/finalized. Điều này cần thiết để phát hiện block trùng lặp. Nếu một leader gửi các block khác nhau đến từng node, mỗi node sẽ bỏ phiếu cho một block tiền nhiệm khác nhau trong cùng một slot. Tuy nhiên, trong một epoch gồm 65.000 slot, kích thước mỗi phiếu bầu có thể lên tới 2 MB trong kịch bản cực đoan nhất. Lý do là phiếu bầu có thể cần hàm băm 32 byte cho từng slot trong số 65.000 slot. Vấn đề này sẽ được tìm hiểu sâu hơn trong một bài viết sau.

Các validator quản lý một “Vote Tower”, tức stack phiếu bầu tuần tự, trong đó mỗi phiếu củng cố một fork và là tổ tiên của fork phía trên nó trong tower. Khi thêm một phiếu bầu mới vào tower, thời gian khóa của mọi phiếu bầu trước đó trong stack sẽ tăng gấp đôi, qua đó tăng dần mức cam kết và thời gian khóa đối với các quyết định trước đó. Bản thân quá trình bỏ phiếu chịu sự điều chỉnh của một số phép kiểm tra: validator phải tôn trọng thời gian khóa của các phiếu bầu trước; họ cần đảm bảo một phần đáng kể của mạng, thường là hai phần ba, cũng cam kết với cùng fork; và cần có đa số đáng kể, trên 38%, phiếu bầu trên các fork thay thế trước khi chuyển sang fork mới.

Đối với một block tại slot n, phiếu bầu ngoài leader bắt đầu xuất hiện on-chain sớm nhất từ n+1. Không có tiểu ban bỏ phiếu — mọi validator đều đủ điều kiện bỏ phiếu cho mọi block. Các phiếu này xuất hiện trước tiên trong block của những validator khác ở gần, cách một bước, trong cây Turbine. Phiếu cho slot n có thể xuất hiện cho đến slot n+512 vì validator được phép bỏ phiếu cho bất kỳ slot nào có “slot hash” vẫn còn được biết, và slot hash được lưu giữ trong 512 slot (cảm ơn Shinobi). Không có giới hạn trên được định trước tại một block cụ thể cho slot n; tuy nhiên, các slot rooted được xây dựng trên ít nhất 32 block liên tục sẽ không còn chấp nhận phiếu bầu và trở thành finalized.

Cơ chế bỏ phiếu có một số điểm đặc thù chưa được runtime thực thi đầy đủ. Ví dụ, hiện validator có động lực chỉ bỏ phiếu cho các slot “rooted”, bỏ qua đầu chuỗi, và đồng thuận không trừng phạt hành vi này. Điều này cho phép validator liên tục nhận tín dụng bỏ phiếu cho các fork gần như chắc chắn trở thành chuẩn tắc nhưng không đóng góp vào đầu chuỗi cho hoạt động đồng thuận thực tế. Điều này đang xảy ra hiện nay, với một validator có “độ trễ bỏ phiếu” trung bình trên 68 slot. Một tính năng được đề xuất có tên Timely Vote Credits nhằm giảm bớt sự lệch pha về động lực này.

Quy tắc chọn fork của Solana

Giống Ethereum (LMD Ghost và Casper FFG), Solana có hai quy tắc xác nhận: một quy tắc để chọn fork ngắn hạn và một quy tắc dành cho đồng thuận PoS đầy đủ để đạt tính chung cuộc. Điều này cho phép người dùng và client tùy chỉnh lựa chọn UX theo các quy tắc xác nhận khác nhau. Hai quy tắc được thể hiện qua hai mức cam kết: “confirmed” và “finalized”.

Các block “confirmed”, còn gọi là xác nhận lạc quan, yêu cầu ít nhất 2/3 validator đã bỏ phiếu cho một block cụ thể thông qua giao dịch bỏ phiếu. Khoảng ~4,6% lượng stake hiện tại sẽ phải bị slashing để có thể xảy ra vi phạm tính chung cuộc. Các block “finalized” yêu cầu phiếu bầu trên ít nhất 32 slot tiếp theo hoặc một siêu đa số (>2/3) phiếu bầu. Một cuộc tấn công độc hại sẽ khiến hơn 1/3 lượng stake phải bị slashing. Quá trình này mất nhiều thời gian hơn đáng kể so với block “confirmed” vì phải chờ các block rooted từ 32 block trước để đạt tính chung cuộc đầy đủ.

Quy tắc chọn fork cho phép mạng đạt đồng thuận về phần đầu của chuỗi. Cách triển khai của Solana Labs chủ yếu xử lý việc chọn fork bằng một tệp Rust dài ~4.600 dòng có tên rất phù hợp là heaviest_subtree_fork_choice.rs. Tệp này cung cấp logic cần thiết để validator xác định fork nào có nhiều khả năng trở thành chuẩn tắc nhất. Phần phân tích mã chi tiết hơn sẽ được trình bày trong một bài viết sau, nhưng ở mức tổng quan nhất, cơ chế chọn fork hoạt động như sau:

  1. Phiếu bầu được thêm bằng add_votes():

Thao tác này lặp qua các phiếu bầu mới, trừ stake của tài khoản bỏ phiếu khỏi các slot cũ nếu cần và thêm stake vào các slot mới được bỏ phiếu.

  1. generate_update_operations() được gọi để tạo một lô thao tác cập nhật fork:

Thao tác này:

  • Trừ stake khỏi fork cũ
  • Thêm stake vào fork mới
  • Tổng hợp stake dọc theo từng fork lên đến root
  1. process_update_operations():
  • Gọi mark_fork_valid()/invalid() nếu cần
  • Gọi aggregate_slot() dọc theo từng fork để cập nhật trọng số fork
  • Gọi add_slot_stake()/subtract_slot_stake() để cập nhật stake
  1. aggregate_slot():
  • Cộng stake của tất cả slot con
  • Tìm fork con nặng nhất theo trọng số stake
  • Tìm fork con sâu nhất theo chiều cao
  • Truyền các giá trị này lên trên để tìm fork nặng nhất/sâu nhất từ slot này
  1. select_forks():
  • Trả về fork nặng nhất tổng thể để sản xuất block
  • Trả về fork nặng nhất bắt nguồn từ phiếu bầu gần nhất

Stake được cộng hoặc trừ dựa trên phiếu bầu, quá trình tổng hợp tính lại trọng số từ dưới lên cho từng fork, và root có cây con mang trọng số lớn nhất được chọn làm fork tốt nhất để tiếp tục xây dựng và bỏ phiếu.

Khả năng được đưa vào

Khả năng giao dịch được đưa vào thay đổi trong suốt vòng đời giao dịch sau khi đạt các yêu cầu cần thiết của từng quy tắc xác nhận tương ứng.

Mặc dù slot có thể bị “bỏ qua”, chẳng hạn khi leader ngoại tuyến, giao dịch đó vẫn có thể được đưa vào các block trong tương lai hoặc hoàn toàn không được đưa vào.

Các slot ở đây chỉ là ước tính sơ bộ, nhưng nhằm giúp người đọc hình dung thời điểm phiếu bầu thường được tích lũy. Hơn nữa, quá trình này khác nhau với từng block; các block có thể đạt mức xác nhận “confirmed” hoặc “finalized” sau những khoảng thời gian khác nhau. Rủi ro bị đảo ngược giảm đơn điệu trong suốt vòng đời giao dịch. Ngay cả sau khi một block đã được finalized (rooted), về lý thuyết block vẫn có thể bị phân fork thông qua đồng thuận xã hội và bị loại khỏi chuỗi “chuẩn tắc”.

Các hướng nghiên cứu trong tương lai và kết luận

Bài viết này đã làm rõ cách vận hành bên trong của Tower BFT, cơ chế đồng thuận của Solana, cùng các cơ chế liên quan khác. Chúng ta đã tìm hiểu vai trò của Proof-of-History, giao dịch bỏ phiếu và việc chọn fork trong bối cảnh Solana nhằm tạo ra một fork chuẩn tắc để sắp xếp giao dịch.

Vẫn còn nhiều hướng nghiên cứu và chính thức hóa bổ sung xoay quanh các cơ chế này cần được khám phá, chẳng hạn như:

  • Các nhà nghiên cứu Ethereum đã định lượng giá trị của việc tham gia Timing Games, trong đó nhà sản xuất block chờ đến cuối slot mới gửi block. Những trò chơi này có đặc điểm định lượng như thế nào trên Solana, và chúng có đang diễn ra không?
  • Thực thi bất đồng bộ nằm trong lộ trình trở thành thay đổi giao thức chính cho năm 2024. Đâu là các vector tấn công tiềm ẩn và những yếu tố bảo mật liên quan đối với các node chỉ bỏ phiếu trên những fork hiện có thay vì tự tính toán cục bộ các chuyển đổi trạng thái?
  • Hiện nay, một bộ phận thiểu số đáng kể các validator (<20%) chạy những phiên bản sửa đổi của client Solana Labs hoặc Jito-Solana. Họ đang thay đổi những ngưỡng nào không do runtime hoặc quy tắc xác nhận quản lý?
  • Triển khai slashing theo chương trình. Hiện tại, ngoài đồng thuận xã hội, có rất ít động lực kinh tế để ngăn việc thực hiện các chiến lược giao dịch có lợi nhuận cao mà không bị slashing.
  • Hiệu năng của cơ chế đồng thuận Solana sẽ như thế nào khi chạy hai client hoàn toàn khác nhau, ngay cả khi chúng cố gắng tuân theo cùng các quy tắc xác nhận?
  • Các tiểu ban bỏ phiếu dự kiến mang lại những lợi ích gì về hiệu năng và giảm trạng thái?
  • Đâu là các vector tấn công tiềm ẩn khi khởi động lại từ một slot được xác nhận lạc quan thay vì một slot đã finalized? Các giải pháp off-chain của bên thứ ba như sàn giao dịch nên cân nhắc thế nào khi sử dụng xác nhận lạc quan hoặc tính chung cuộc đầy đủ?
  • Khoản tiền bị slashing có nên được dùng làm bảo hiểm cho các giao dịch liên quan đến vi phạm an toàn không? Cơ chế và động lực của một quỹ bảo hiểm định giá bằng SOL sẽ như thế nào?

Trong bài viết này, chúng ta đã tìm hiểu một số cơ chế và ngưỡng mà Solana triển khai trong cơ chế đồng thuận, cũng như mối liên hệ của chúng với quy trình sản xuất block thông thường của leader trong các slot được chỉ định. Sự gia tăng hoạt động gần đây trên Solana tạo ra các phép thử khả năng hoạt động và an toàn trong thực tế cho những cơ chế này, đồng thời làm tăng động lực thực hiện các cuộc tấn công độc hại.

Cảm ơn anoushk (Tinydancer), dubbel06 (Overclock), Prithvi (Helius), Mert (Helius) và Jarry (Ellipsis Labs) vì những cuộc thảo luận và nhận xét.

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