
Đồng sáng lập Solana: Giải pháp nào cho sự tăng trưởng trạng thái của Solana?
Tuyển chọn TechFlowTuyển chọn TechFlow

Đồng sáng lập Solana: Giải pháp nào cho sự tăng trưởng trạng thái của Solana?
Phải quản lý trạng thái và bộ nhớ trong giới hạn phần cứng hiện tại.
Tác giả: toly, đồng sáng lập Solana
Biên dịch: Felix, PANews
Mỗi ngày có khoảng 1 triệu tài khoản mới được thêm vào Solana, tổng trạng thái hiện tại vượt quá 500 triệu và kích thước snapshot khoảng 70GB. Dù những con số này hoàn toàn có thể quản lý được khi phần cứng cải thiện, mục tiêu của môi trường thực thi SVM là cung cấp cách truy cập phần cứng rẻ nhất, để đạt được điều đó cần phải quản lý trạng thái và bộ nhớ trong giới hạn phần cứng hiện tại.
Băng thông PCI
Tính đến năm 2024, băng thông PCI mới nhất có thể đạt từ 0,5 Tbs đến 1 Tb thông lượng, hoặc 64GB đến 128GB mỗi giây. Mặc dù nghe có vẻ lớn, nhưng nếu một giao dịch đọc/ghi 128MB thì băng thông PCI 128GBps sẽ giới hạn TPS của chuỗi ở mức khoảng 1000. Trên thực tế, hầu hết các giao dịch truy cập bộ nhớ vừa được tải gần đây và đã được lưu vào RAM. Thiết kế lý tưởng nên cho phép nạp 1000 giao dịch với trạng thái mới 128MB cộng thêm 10.000 hoặc nhiều hơn các giao dịch đọc và ghi trạng thái đã được lưu cache trước đó.
Chỉ mục tài khoản
Việc tạo tài khoản mới cần chứng minh rằng tài khoản đó hiện không tồn tại. Việc này thường được hoàn thành tự động trên mỗi trình xác thực vì mỗi trình xác thực đều có chỉ mục đầy đủ về tất cả tài khoản hợp lệ hiện tại. Ngay cả khi dữ liệu tài khoản không được lưu trữ cục bộ mà chỉ lưu hash dữ liệu, 500 triệu tài khoản cũng sẽ chiếm 32 byte khóa + 32 byte hash dữ liệu, tức là 64 byte mỗi mục, tương đương 32 GB. Kích thước này đã đủ để đảm bảo sự tách biệt giữa RAM và đĩa.
Kích thước Snapshot
Ở một mức kích thước snapshot nhất định, nếu một phần mạng gặp sự cố phần cứng, thời gian cần thiết để khởi động lại hệ thống mới có thể làm kéo dài thời gian khởi động lại trong trường hợp xấu nhất. Cùng với sự cải tiến của băng thông và phần cứng, tình hình thay đổi từng ngày, và Solana hiện chưa tới giới hạn này, nhưng giới hạn đó luôn tồn tại tại mọi thời điểm.
Tổng quan
Bộ nhớ và đĩa có các đặc tính hiệu suất và giới hạn khác nhau. Nếu SVM không phân biệt chúng, thì các giao dịch và giới hạn phải được định giá theo trường hợp tồi tệ nhất, từ đó hạn chế hiệu suất. Trong suốt quá trình thực thi giao dịch, tất cả các khóa tài khoản ít nhất phải sẵn có, và tổng số tài khoản sẽ ảnh hưởng đến việc sử dụng băng thông PCI giữa RAM và đĩa. Snapshot không thể tăng kích thước tùy ý. Giải pháp lý tưởng là:
-
Cho phép đóng gói thêm nhiều giao dịch không cần tài nguyên PCI vào khối
-
Quản lý kích thước chỉ mục tổng và kích thước snapshot
Chilly, Avocado, LSR. Những cái tên tệ thường là dấu hiệu của thiết kế phần mềm tuyệt vời. Các kỹ sư Anza và Firedancer đã đưa ra giải pháp sau.
Chilly
Bộ nhớ đệm của runtime tài khoản được quản lý một cách xác định bởi tất cả các instance. Nhìn từ cấp độ cao, đây là bộ nhớ đệm LRU (truy cập gần đây nhất) cho trạng thái. Trong quá trình xây dựng và lên lịch khối, việc triển khai có thể dễ dàng kiểm tra tài khoản mà không cần khóa hay lặp lại bộ nhớ đệm LRU. Bộ nhớ đệm được thực hiện bằng cơ chế bộ đếm rất đơn giản.
-
Tổng số byte đã tải được theo dõi như Bank::loaded_bytes:u64
-
Mỗi tài khoản khi được sử dụng sẽ được đánh dấu bằng bộ đếm chạy hiện tại account::load_counter:u64
-
Khi tải tài khoản, nếu Bank::loaded_bytes - Account::load_counter > CACHE_SIZE, tài khoản được coi là tài khoản lạnh (cold), kích thước của nó được tính theo LOAD_LIMIT mỗi khối
-
Tài khoản mới có load_counter bằng 0, do đó mọi tài khoản mới đều là tài khoản lạnh
-
Trình lên lịch của Leader sử dụng LOAD_LIMIT như một mực nước, tương tự giới hạn CU khóa ghi.
Điểm tuyệt vời của thiết kế này là nó phù hợp một cách tự nhiên với trình lên lịch hiện tại. Người dùng chỉ cần lo lắng về phí ưu tiên của họ. Trình lên lịch phải xử lý việc đặt tất cả các giao dịch dưới giới hạn LOAD_LIMIT và giới hạn khóa ghi tài khoản vào bài toán ba lô. Các giao dịch có mức ưu tiên cao nhất có thể được tải đầu tiên và sử dụng LOAD_LIMIT. Một khi giới hạn này đạt đến, tất cả các giao dịch khác vẫn có thể được đưa vào khối. Do đó, trình xác thực có thể tối đa hóa tính cục bộ bộ nhớ đệm của các giao dịch.
Avocado
Avocado gồm hai phần: nén trạng thái và nén chỉ mục. Đầu tiên thay thế dữ liệu tài khoản bằng hash, sau đó di chuyển chỉ mục tài khoản sang Binary Trie / patricia Trie. Tài khoản mới phải cung cấp bằng chứng rằng chúng không tồn tại trong 'trie'.
Nén trạng thái
Thiết kế đại khái như sau:
-
Trong quá trình phân bổ, mỗi tài khoản bị ràng buộc X lamports mỗi byte.
-
Nếu X < giá sàn kinh tế hiện tại, tài khoản sẽ bị nén khi giữ trong bộ nhớ
-
Việc nén là một quá trình nhiều bước, diễn ra trong một epoch
-
Dữ liệu tài khoản được thay thế bằng giá trị hash (data)
-
Khóa tài khoản vẫn nằm trong trạng thái
-
Giao dịch tham chiếu đến tài khoản đã nén sẽ thất bại
-
Giải nén yêu cầu tải lên dữ liệu tương tự như chương trình nạp (loader)
-
Chi phí giải nén nên bằng chi phí phân bổ tài khoản mới
Ước tính 75% tài khoản không được truy cập trong hơn 6 tháng và có khả năng sẽ không bao giờ được truy cập. Việc nén chúng có thể tiết kiệm 50% kích thước snapshot.
Nén chỉ mục
Đây là vấn đề khó giải quyết hơn. Chỉ bằng nén trạng thái, trình xác thực vẫn sở hữu tất cả các tài khoản hợp lệ có thể có trong hệ thống. Việc tạo tài khoản mới cần kiểm tra cơ sở dữ liệu này. Chi phí lưu trữ cơ sở dữ liệu này của trình xác thực là rất cao, nhưng chi phí người dùng tạo tài khoản mới lại rất thấp. Cần đảm bảo khóa riêng mới không xung đột với bất kỳ tài khoản hiện tại nào.
Mining Binary Trie
-
Binary Trie được theo dõi như một phần của snapshot
-
Các trình xác thực muốn nhận thêm SOL có thể tạo giao dịch xóa cặp kv tài khoản đã nén khỏi trạng thái và thêm chúng vào Binary Trie
-
Người dùng có thể loại bỏ kv khỏi Trie trong quá trình giải nén, đảo ngược hành động này mà không cần được phép (việc này có thể yêu cầu thao tác nguyên tử khi giải nén để dễ dàng hơn khi dịch vụ nền đang nén tài khoản).
-
Đối với trình xác thực, kích thước gốc Trie là hằng số bất kể chứa bao nhiêu cặp kv
-
Sử dụng zkp, mỗi giao dịch có thể nén khoảng 30 tài khoản
-
Giả sử mỗi khối chỉ có một giao dịch như vậy, việc nén 500 triệu tài khoản sẽ mất khoảng 80 ngày
Điểm then chốt của quá trình này là trình xác thực thực hiện việc này sẽ nhận được phần thưởng, nhưng không phải tất cả trình xác thực đều phải thực hiện. Nếu tất cả trình xác thực đều phải thực hiện, thì tất cả đều phải duy trì nội dung Binary Trie hiện tại, nghĩa là toàn bộ trạng thái phải là một phần của snapshot. Trình xác thực muốn duy trì toàn bộ trạng thái nên gửi giao dịch nén N tài khoản trong chỉ mục vào Trie.
Bằng chứng tài khoản mới
Để tạo tài khoản mới, người dùng phải chứng minh tài khoản đó không tồn tại trong Trie. Trình xác thực duy trì toàn bộ trạng thái có thể tạo bằng chứng rằng tài khoản không nằm trong Trie. Điều này gây gánh nặng cho người dùng, họ phải luôn kết nối với nhà cung cấp trạng thái lớn để tạo các bằng chứng này.
Hoặc, người dùng có thể chứng minh tài khoản của họ được tạo bằng hash PoH gần nhất. Cách đơn giản nhất hỗ trợ điều này là:
-
Tạo PKI mới
-
Địa chỉ tài khoản là hash (hash PoH gần nhất, PKI::public_key)
Vì tài khoản trong Trie phải được nén trạng thái trước, việc này cần một epoch đầy đủ. Không thể có tài khoản nào trong Trie sử dụng hash PoH gần nhất để tạo địa chỉ.
Một phương pháp hỗ trợ khác là bản thân việc tạo PKI có thể cung cấp bằng chứng rằng khóa riêng được tạo bằng hash (bí mật ẩn của người dùng, hash PoH gần nhất).
LSR
Lightweight Simple Rent, còn gọi là Less Stupid Rent. Làm thế nào để định giá chi phí phân bổ tài khoản mới, và làm sao đảm bảo các tài khoản cũ bị bỏ rơi cuối cùng được nén lại, giảm tải tổng thể của hệ thống và giá cả cho người dùng mới?
Cần khôi phục chế độ thuê bao (Rent). Rent nghĩa là tài khoản ở trạng thái hiện tại nên trả phí X đô la/byte/ngày, giống như tài khoản trên AWS trả phí lưu trữ.
Đường cong lãi suất Rent Rate
RentRate = K*(state_size)^N
Bất kể kích thước trạng thái hiện tại là bao nhiêu, nếu nhỏ thì tỷ lệ nên thấp, nếu gần giới hạn snapshot thì tỷ lệ nên rất cao.
Giá ràng buộc tối thiểu khi phân bổ
Tài khoản phải tồn tại ít nhất một epoch. Việc phân bổ cần đưa tài khoản vào trạng thái Hot. Tài khoản nóng nên tồn tại trong suốt thời gian cache.
New Account bond = Epoch Slots * RentRate * Account::size
Số dư của tài khoản mới phải có ít nhất số lamport này để được tạo.
Đốt tài khoản nóng (Hot Account Burn)
lruturnverrate = thời gian trung bình mỗi tài khoản chiếm trong bộ nhớ cache LRU, tối đa bằng 1 epoch. Giá trị này có thể là hằng số hoặc được tính bên ngoài chuỗi và báo cáo cho SVM như một hằng số trung vị có trọng số theo cổ phần.
Nén
Khi (current slot - account::creation_slot) * RentRate * account::size > account::lamports, tài khoản bị nén và tất cả lamport bị đốt cháy.
Các giải pháp trên nên khiến State trở nên rẻ, vì theo thời gian, các tài khoản không dùng đến cuối cùng sẽ đạt lamport bằng 0 và bị nén. Vì vậy chi phí dữ liệu sẽ giảm, thậm chí chi phí chỉ mục cũng giảm, dẫn đến giảm kích thước trạng thái hiện tại. Giảm kích thước trạng thái sẽ làm giảm chi phí phân bổ siêu bậc hai.
Chào mừng tham gia cộng đồng chính thức TechFlow
Nhóm Telegram:https://t.me/TechFlowDaily
Tài khoản Twitter chính thức:https://x.com/TechFlowPost
Tài khoản Twitter tiếng Anh:https://x.com/BlockFlow_News














