Chúng tôi đang theo đuổi độ trễ thấp nhất có thể. Chúng tôi đang xây dựng một tính năng ví mới mượt mà trên devnet của Midnight, và mã nguồn thì đẹp.
Chúng tôi đã thiết kế một kiến trúc trạng thái xuất sắc - một bản đồ tổng hợp duy nhất chứa tất cả dữ liệu người dùng. Nó thật sạch sẽ. Nó thật đơn giản. Nó thật thanh lịch.
Vào lúc 3:13 AM, trong một bài kiểm tra căng thẳng, sự thanh lịch đó trở thành một gánh nặng.
Hư Vô
Chúng tôi đã thực hiện hai chuyển khoản. Cùng một ví. Người nhận khác nhau. Trên một chuỗi truyền thống, đây không phải là vấn đề; cái thứ hai đơn giản chỉ chờ đến lượt. Nhưng trong môi trường thực thi song song của Midnight, chúng tôi không gặp phải sự chậm trễ.
Chúng tôi đã có một khoảng trống.
Giao dịch đầu tiên đã nắm giữ khóa ghi trên trạng thái ví đó. Giao dịch thứ hai đã vào mempool, được coi là hợp lệ, và sau đó... xếp hàng. Nó đã chờ đợi lượt của mình để ghi, nhưng đồng hồ đang chạy.
Cửa sổ khe Midnight—một khoảng thời gian chặt chẽ 150ms—đã đóng lại trước khi giao dịch thứ hai có thể lấy được khóa và thực thi.
Giao dịch không thất bại với mã lỗi. Nó không quay lại cho người gửi. Nó đơn giản biến mất. Không cảnh báo. Không mục nào trên trình khám phá khối. Chỉ có một khoảng trống ma quái trong chuỗi của chúng tôi nơi giá trị lẽ ra phải di chuyển.
Đó là khoảnh khắc chúng tôi nhận ra rằng trên Midnight, kẻ giết người im lặng không phải là thông lượng. Đó là sự va chạm trạng thái.
Ảo Tưởng về Thành Công
Chúng tôi đã học được một sự thật khó khăn vào đêm đó: Trên các chuỗi thực thi song song như Midnight, "thành công" có thể trông giống hệt như "mất mát im lặng."
Nếu hai giao dịch chạm vào cùng một tài khoản trong một khe duy nhất, một trong số chúng sẽ biến mất không có dấu vết. Bạn sẽ không tìm thấy nó trong nhật ký. Mạng sẽ không hét lên với bạn. Bạn chỉ phát hiện ra sự chảy máu khi kiểm tra bảng cân đối vào lúc bình minh và thấy một lỗ hổng lớn nơi quỹ lẽ ra phải có.
Vấn đề không phải là logic của chúng tôi; mà là kiến trúc của chúng tôi. Bằng cách đóng gói tất cả trạng thái người dùng vào một bản đồ khổng lồ, chúng tôi đã tạo ra một điểm tranh chấp đơn nhất. Mỗi giao dịch trở thành một nút thắt, đấu tranh để có quyền ghi vào cùng một khối dữ liệu.
Giải Pháp: Phân Mảnh hoặc Chết
Để sống sót trên Midnight, bạn phải thay đổi cách suy nghĩ về trạng thái. Bạn phải giả định rằng sự tranh chấp là kẻ thù và thiết kế dữ liệu của bạn để tránh nó bằng mọi giá.
1. Chấp nhận Sự Phân Mảnh
Ngừng nghĩ về trạng thái người dùng như một thực thể đơn thể duy nhất. Phá vỡ nó ra. Phân mảnh trạng thái người dùng của bạn thành các đoạn tách biệt, độc lập. Nếu một người dùng có nhiều tài sản hoặc hành động, chúng không nên sống dưới một mái nhà.
2. Nhóm Nonce là Bạn Bè của Bạn
Thay vì khóa toàn bộ hồ sơ người dùng, hãy tách biệt trạng thái theo nhóm nonce hoặc các miền hoạt động cụ thể. Một chuyển khoản chỉ nên khóa UTXO hoặc thùng cân bằng cụ thể mà nó cần—không phải toàn bộ lịch sử giao dịch của người dùng.
3. Thu hẹp Đường Ghi
Kiểm toán từng dòng tương tác trạng thái của bạn. Nếu một giao dịch không thực sự cần phải ghi vào một mảnh dữ liệu, đừng để nó chạm vào.
Con Dao Hai Lưỡi
Sức mạnh của Midnight là khả năng thực thi song song của nó, nhưng sức mạnh đó là một con dao hai lưỡi. Nó thưởng cho những ai thiết kế cho tính đồng thời và trừng phạt những ai mang tư duy chuỗi đơn thể, di sản.
Chúng tôi đã xây dựng lại mô hình trạng thái của mình. Chúng tôi đã phân mảnh bản đồ đơn thể thành các khóa tinh vi, mỗi khóa đại diện cho một tài nguyên riêng biệt. Bây giờ, các chuyển khoản đồng thời nhắm vào cùng một người dùng trượt vào các khe khác nhau mà không bao giờ phải chiến đấu cho cùng một khóa.
Kiểm toán Trước Khi Triển Khai
Kiểm toán trạng thái của bạn trước khi triển khai. Bởi vì trên Midnight, nếu bạn không tôn trọng thời gian khe, các giao dịch của bạn sẽ không chỉ thất bại—chúng sẽ biến mất.
Và sự im lặng sẽ là âm thanh đắt giá nhất mà bạn không bao giờ nghe thấy.
@MidnightNetwork $NIGHT #night
