
Cập nhật Agave v2.2: Mọi điều bạn cần biết
Mục lục
- Những cập nhật đáng chú ý trong chu kỳ phát hành Agave 2.2
- Triển khai tính năng
- Nâng giới hạn block lên 60M CU
- Thách thức khi nâng giới hạn block
- Accounts Lattice Hash (ALH)
- Cách Accounts Lattice Hash hoạt động
- Tích hợp và ngừng sử dụng các hàm băm
- Hiệu năng và sự đánh đổi
- Tích hợp snapshot
- Xác minh chữ ký Secp256r1 nguyên bản
- Lỗi căn chỉnh precompile
- Triển khai và thực thi các chương trình SBPFv1, v2 và v3
- Gỡ bỏ hạn chế đối với bên gọi CPI
- Loader-v4
- Các tính năng chính trong Loader-v4:
- Kết luận
- Tài nguyên bổ sung
Xin chân thành cảm ơn Alexander Meißner, 0xIchigo và Will Hickey đã đánh giá các phiên bản trước của bài viết này.
Bản phát hành client validator Agave v2.2 đánh dấu một cột mốc quan trọng khác trong hành trình hướng tới hệ sinh thái đa client có khả năng phục hồi tốt hơn của Solana. Bản cập nhật này mang đến những cải tiến chủ chốt nhằm nâng cao hiệu năng mạng và trải nghiệm của nhà phát triển.
Những cập nhật đáng chú ý trong chu kỳ phát hành Agave 2.2
- Tối ưu hóa hiệu năng trên diện rộng
- Tăng 20% giới hạn block, từ 50M lên 60M CU
- Ra mắt Accounts Lattice Hash (ALH)
- Xác minh chữ ký Secp256r1 (được dời từ chu kỳ phát hành Agave 2.1)
- Triển khai và thực thi các chương trình SBPFv1, v2 và v3
- Gỡ bỏ hạn chế đối với bên gọi CPI
- Loader-v4
Mỗi phần trong bài viết này đều độc lập, giúp người đọc dễ dàng khám phá những chủ đề phù hợp nhất với mình. Dù là đơn vị vận hành validator, nhà phát triển hay người dùng tích cực, hướng dẫn toàn diện về Agave 2.2 này sẽ cung cấp những thông tin chuyên sâu cần thiết để tận dụng tối đa các cải tiến mới nhất.
Triển khai tính năng
Tại thời điểm viết bài, 19,8% tổng stake đang chạy Agave v2.2.*, cho thấy sự ủng hộ mạnh mẽ đối với việc áp dụng trên toàn mạng. Hoạt động kích hoạt feature gate trên mainnet đã tạm dừng trong giai đoạn nâng cấp và dự kiến sớm được tiếp tục theo trình tự kích hoạt đã lên kế hoạch.
Hầu hết các tính năng chính được giới thiệu trong Agave 2.2 hiện vẫn nằm sau feature gate và chưa hoạt động trên mainnet. Chúng sẽ được kích hoạt dần trong suốt chu kỳ phát hành 2.2 thông qua hệ thống feature gate của Solana. Thời điểm kích hoạt được xác định theo mức độ ưu tiên của tính năng và thứ tự triển khai trên các cluster testnet và devnet. Vui lòng tham khảo trình theo dõi feature gate của Agave để biết thông tin cập nhật mới nhất.
Nâng giới hạn block lên 60M CU
Anza đã đặt ra một mục tiêu đầy tham vọng cho năm 2025: tăng gấp đôi không gian block khả dụng trên Solana. Trong nỗ lực này, SIMD-0256: Tăng giới hạn block lên 60M dự kiến sẽ được đưa vào bản phát hành Solana 2.2 sắp tới, tương đương mức tăng 20% so với giới hạn block hiện tại.
Thay đổi này tiếp nối một bản nâng cấp trước đó, trong đó giới hạn block được tăng từ 48 triệu lên 50 triệu đơn vị tính toán (CU), sau đó thời gian block luôn duy trì dưới mục tiêu 400ms. Dữ liệu gần đây cho thấy các block thường xuyên chạm trần 50M CU, báo hiệu hệ thống đã sẵn sàng mở rộng thêm.
Lưu ý: Một số block hiển thị mức đầy 104% do một hằng số được mã hóa cứng trong logic báo cáo của bảng điều khiển Firedancer.
Các giới hạn giao thức khác không thay đổi trong bản cập nhật này:
- Ngân sách tính toán trên mỗi account trong mỗi block không đổi ở mức 12 triệu CU.
- Mức tính toán tối đa trên mỗi transaction vẫn bị giới hạn ở 1,4 triệu CU.
- Giới hạn tính toán tổng hợp cho các vote transaction trong mỗi block vẫn ở mức 36 triệu CU.
- Dung lượng dữ liệu account mới tối đa được phân bổ trong mỗi block vẫn bị giới hạn ở 100 MB.
Việc nâng giới hạn block tác động trực tiếp đến trải nghiệm người dùng: thông lượng mạng cao hơn giúp giảm phí transaction trung vị và tăng khả năng transaction được ghi nhận thành công trong những thời điểm tắc nghẽn.
Thách thức khi nâng giới hạn block
Khi tăng thông lượng, nên nâng giới hạn block một cách thận trọng và từ từ vì cần giải quyết hai thách thức chính:
1. Mức độ sẵn sàng của hạ tầng
Hạ tầng của hệ sinh thái rộng lớn hơn phải theo kịp các tối ưu hóa của client lõi. Cụ thể, lớp ghi không thể phát triển nhanh hơn lớp đọc (ví dụ: các node RPC, trình lập chỉ mục và dịch vụ lưu trữ) nếu không muốn làm suy giảm trải nghiệm người dùng.
2. Truyền block kịp thời
Một nút thắt khác nằm ở việc phân phối block từ node leader đến phần còn lại của cluster. Các block lớn hơn đáng kể có thể khiến thời gian phân phối block vượt mục tiêu 400ms, đặc biệt trong điều kiện tải cao.
Một thách thức cấp bách nằm ở giai đoạn truyền lại của Transaction Validation Unit (TVU), nơi các shred được phân phối khắp cluster. Các validator lớn đạt gần 150.000 gói tin gửi đi mỗi giây (PPS) do hệ số fanout cao 200 của Turbine (tức là mỗi node chịu trách nhiệm chuyển tiếp shred đến 200 node khác). Nếu quá trình này được xử lý không hiệu quả, nó có thể gây tồn đọng shred, chuyển giao leader thất thường và góc nhìn trạng thái thiếu nhất quán trên toàn mạng.
Để giải quyết vấn đề này, các kỹ sư Anza hiện đang đại tu pipeline phân phối block. Đội ngũ đang thực hiện quá trình chuyển đổi sang XDP (eXpress Data Path), cho phép bỏ qua kernel bằng cách đưa hoạt động xử lý gói tin trực tiếp ra không gian người dùng. Cách tiếp cận này loại bỏ các thao tác sao chép trung gian tốn kém, cho phép phần mềm validator giao tiếp trực tiếp với card giao tiếp mạng (NIC).
Accounts Lattice Hash (ALH)
Để hỗ trợ hàng tỷ account, Solana cần một phương pháp có khả năng mở rộng tốt hơn nhằm băm trạng thái account toàn cục. Accounts Lattice Hash (ALH) mới được giới thiệu sẽ thay thế các hàm băm account dựa trên Merkle trước đây bằng một giải pháp thay thế hiệu quả và có khả năng mở rộng hơn dựa trên hàm băm đồng cấu, cho phép tạo hàm băm mới từ các hàm băm hiện có mà không phải tính toán lại từ đầu.
Solana hiện duy trì hai hàm băm trạng thái account:
- Epoch Accounts Hash (EAH): Root Merkle của toàn bộ trạng thái account, được tính một lần trong mỗi epoch.
- Accounts Delta Hash (ADH): Root Merkle của các account được sửa đổi trong một block, được tính lại ở mỗi block.
Cả hai đều dựa vào việc sắp xếp account theo khóa công khai và xây dựng cây Merkle, dẫn đến các thách thức về hiệu năng và khả năng mở rộng, đặc biệt khi tập hợp account ngày càng lớn. Mô hình băm kép ra đời như một giải pháp dung hòa: EAH chính xác (bao gồm toàn bộ trạng thái account) nhưng không thường xuyên, trong khi ADH thường xuyên nhưng chỉ phản ánh một phần (chỉ các account đã sửa đổi). Lý tưởng nhất là mỗi block đều chứa một hàm băm đầy đủ và cập nhật của toàn bộ trạng thái account mà không phải chịu chi phí tính toán lại cây Merkle.
Cách Accounts Lattice Hash hoạt động
ALH đạt được mục tiêu này bằng cách sử dụng hàm băm đồng cấu cho phép cập nhật tăng dần. Thay vì xây dựng lại cây Merkle mỗi lần, ALH chỉ cần cộng hoặc trừ các hàm băm account riêng lẻ (LtHashes) khi account được ghi. Kết quả cuối cùng là một hàm băm 2048 byte duy nhất, tóm lược trạng thái của tất cả account. Điều quan trọng là nó có thể được cập nhật theo từng block mà không cần tính toán lại từ đầu.
Hãy tưởng tượng bạn có một chiếc lọ khổng lồ chứa đầy tiền xu. Nếu thêm hoặc bớt vài đồng, bạn sẽ không đổ hết ra để đếm lại từ đầu—bạn chỉ cần cập nhật tổng số. Đó là bản chất cách SIMD-0215 mới được hợp nhất của Solana: Accounts Lattice Hash giúp việc quản lý hàng tỷ account trở nên khả thi.

Cách tiếp cận này có độ phức tạp O(n), một bước cải thiện đáng kể so với độ phức tạp O(n log n) của cây Merkle. Nó cho phép mỗi block chứa hàm băm của toàn bộ trạng thái account mà không cần tính toán lại tốn kém.
Tích hợp và ngừng sử dụng các hàm băm
Quá trình triển khai trải dài trên ba SIMD riêng biệt với các đợt kích hoạt feature gate độc lập tương ứng trong suốt chu kỳ phát hành Agave 2.2.
- SIMD-0215: Accounts Lattice Hash
- SIMD-0220: Snapshot sử dụng Accounts Lattice Hash
- SIMD-0223: Loại bỏ Accounts Delta Hash
Với những thay đổi này, Accounts Lattice Hash thay thế cả ADH và EAH. ALH sẽ được tích hợp vào hàm băm bank của mỗi block, cho phép băm toàn bộ trạng thái theo tần suất block thay vì tần suất epoch.
Hiệu năng và sự đánh đổi
Việc chuyển sang ALH mang lại lợi ích đáng kể về hiệu năng validator nhờ loại bỏ hoạt động băm dựa trên Merkle ở mỗi block. Điều này sẽ tinh giản quá trình đồng thuận và tạo snapshot. Ví dụ, validator không còn phải sắp xếp account hoặc xây dựng lại cây trong quá trình hoàn tất block hay tạo snapshot—các bản cập nhật ALH chỉ là những phép cộng đơn giản.
Tuy nhiên, cách tiếp cận này không hỗ trợ bằng chứng bao hàm hoặc loại trừ, không giống cây Merkle hoặc Verkle. Dù điều này ảnh hưởng đến một số trường hợp sử dụng xác minh mật mã, chẳng hạn như client nhẹ và Simple Payment Verification (SPV), sự đánh đổi này được xem là xứng đáng nhờ mức cải thiện hiệu quả vượt trội. Bạn có thể xem phần thảo luận về các phương pháp thay thế cho bằng chứng bao hàm tại đây.
Tích hợp snapshot
Vì việc tính Accounts Lattice Hash ban đầu rất tốn kém, giá trị ALH hiện được lưu giữ trong snapshot của validator và được khôi phục khi khởi động nếu có. Snapshot sẽ phản ánh định dạng ALH mới thay vì Snapshot Hash dựa trên Merkle, qua đó tiếp tục đồng bộ mô hình lưu trữ và băm của Solana với thiết kế mới này.
Xác minh chữ ký Secp256r1 nguyên bản
Solana đang bổ sung hỗ trợ nguyên bản cho việc xác minh chữ ký đường cong elliptic secp256r1, một nâng cấp quan trọng giúp tương thích on-chain với Passkeys, tiêu chuẩn WebAuthn và các mô hình trừu tượng hóa account nâng cao, bao gồm xác thực hai yếu tố (2FA). Bản cập nhật này đưa phương thức xác thực không cần mật khẩu vốn đã phổ biến trong Web2 vào lĩnh vực Web3, qua đó tăng cường tính bảo mật và khả năng sử dụng cho các ứng dụng on-chain.
Ban đầu được lên lịch cho bản phát hành Agave 2.1, tính năng này đã được dời sang 2.2. Để biết thêm chi tiết, hãy xem phân tích toàn diện của chúng tôi về Xác minh chữ ký Secp256r1 trong bản cập nhật Agave 2.1.
Lỗi căn chỉnh precompile
Không lâu sau đợt triển khai Agave 2.2 ban đầu, một lỗi nghiêm trọng đã được phát hiện trong quá trình triển khai các chương trình precompile Secp256r1 và Ed25519. Lỗi được kích hoạt khi dùng cờ chế độ xem `--transaction-structure` mới, cờ này hiển thị bố cục transaction thô mà không đảm bảo căn chỉnh. Các precompile đã giả định sai rằng dữ liệu instruction được căn chỉnh theo 2 byte, dẫn đến kết quả thực thi không nhất quán giữa bên tạo block và validator. Điều này gây ra sự không khớp hàm băm bank, buộc các leader phải hủy bỏ và làm suy giảm tính sẵn sàng. Vấn đề được báo cáo lần đầu vào ngày 9 tháng 4 và nhanh chóng được vá vào ngày 11 tháng 4. Lỗi không ảnh hưởng đến tài sản của người dùng. Bạn có thể tìm hiểu thêm chi tiết trong bản Phân tích nguyên nhân gốc rễ được công bố ngay sau đó.
Triển khai và thực thi các chương trình SBPFv1, v2 và v3
Solana Berkeley Packet Filter (SBPF) là một máy ảo tùy chỉnh, được thiết kế để thực thi các chương trình Solana hiệu quả và an toàn. Đây là một nhánh phát triển dựa trên Rust của extended Berkeley Packet Filter (eBPF), vốn ban đầu được xây dựng cho Linux.
Việc nâng cấp Solana Berkeley Packet Filter (SBPF) là điều thiết yếu để nâng cao hiệu năng, tăng cường bảo mật và mở ra các khả năng mới cho nhà phát triển ứng dụng. Agave 2.2 đặt nền móng cho khả năng bảo trì lâu dài và nâng cấp hiệu năng bằng cách giới thiệu hệ thống quản lý phiên bản chính thức cho máy ảo SBPF, lần đầu được trình bày trong SIMD-0161. Thay đổi này cho phép triển khai và thực thi các chương trình SBPFv1 (SIMD-0166), SBPFv2 (SIMD-0173, SIMD-0174) và SBPFv3 (SIMD-0178, SIMD-0179, SIMD-0189), qua đó thiết lập một khuôn khổ bền vững để phát triển môi trường thực thi chương trình theo từng giai đoạn mà không cần triển khai lại trên toàn mạng.
Cho đến nay, mọi nâng cấp SBPF đều phải được đưa vào thông qua các feature gate toàn cục, khiến việc phát triển runtime trở nên cồng kềnh và gần như không thể điều phối triển khai. Hệ thống quản lý phiên bản giải quyết vấn đề này bằng cách tách hành vi của chương trình khỏi runtime toàn cục và thay vào đó gắn hành vi với thẻ phiên bản riêng cho từng chương trình, được mã hóa trong trường e_flags của tiêu đề tệp Executable and Linkable Format (ELF). Cách tiếp cận này cho phép:
Hành vi runtime rõ ràng
Mỗi chương trình chỉ định kiến trúc tập lệnh (tức là một phiên bản SBPF) mà chương trình yêu cầu. Dựa trên phiên bản này, runtime của chương trình sẽ điều chỉnh hành vi.
Triển khai có kiểm soát
Các feature gate sẽ độc lập cho phép triển khai và thực thi phiên bản SBPF mới, đồng thời loại bỏ dần các phiên bản cũ theo thời gian. Toàn bộ các thay đổi được nhóm vào những phiên bản SBPF riêng biệt, giúp việc nâng cấp gọn gàng và dễ quản lý hơn.
Ngừng hỗ trợ theo từng giai đoạn
Cuối cùng, khả năng hỗ trợ các phiên bản SBPF cũ có thể được loại bỏ sau khi chúng ngừng được hỗ trợ, giúp đơn giản hóa logic của máy ảo. Quá trình này sẽ diễn ra chậm, cho nhà phát triển đủ thời gian để di chuyển hoặc triển khai lại chương trình và thích ứng với các phiên bản mới hơn.
Bộ phân biệt phiên bản
Hiện tại, giao thức coi mọi giá trị e_flags khác 0x0020 là SBPF v0, điều này hợp lệ trong hệ thống hiện có. Tuy nhiên, cách tiếp cận này không thể mở rộng để hỗ trợ nhiều phiên bản SBPF và cần được cập nhật.
Sau khi feature gate đầu tiên cho phép một phiên bản SBPF mới được kích hoạt, giao thức sẽ thay đổi cách diễn giải e_flags và ánh xạ trực tiếp giá trị này tới số phiên bản SBPF tương ứng. Theo hệ thống này, 0x0000 sẽ đại diện cho SBPF v0, 0x0001 sẽ đại diện cho SBPF v1, v.v.
Gỡ bỏ hạn chế đối với bên gọi CPI
Chu kỳ phát hành Agave 2.2 bao gồm một cải tiến được mong đợi từ lâu, giúp loại bỏ hạn chế trước đây đối với Cross-Program Invocations (CPI). Hiện tại, mọi chương trình được gọi qua CPI đều phải được bên gọi truyền rõ ràng dưới dạng một instruction account. Điều này khiến quá trình xây dựng transaction trở nên phức tạp và tạo ra chi phí tính toán đáng kể, đặc biệt với các CPI lồng nhau nhiều tầng. Tuy nhiên, hạn chế này chỉ mang tính lịch sử và không còn cần thiết cho giao thức hiện tại.
SIMD-0163 gỡ bỏ hạn chế này bằng cách cho phép instruction CPI tham chiếu trực tiếp đến program account từ danh sách account cấp cao nhất của transaction, thay vì yêu cầu các account đó được truyền đệ quy qua mọi cấp gọi. Thay đổi này mang lại các lợi ích sau:
- Giảm mạnh mức sử dụng CU nhờ tránh tuần tự hóa và giải tuần tự hóa program account một cách dư thừa (ngoại trừ các chương trình loader-v3 lưu tệp thực thi trong một account riêng), vốn đặc biệt tốn kém do kích thước lớn của chúng (tệp nhị phân ~10 MB).
- Đơn giản hóa quá trình xây dựng transaction bằng cách loại bỏ nhu cầu truyền program account của bên được gọi qua các ngăn xếp instruction.
- Cải thiện khả năng kết hợp, giúp xây dựng kiến trúc chương trình dạng mô-đun và lồng nhau nhiều tầng dễ dàng hơn.
Khả năng tương thích ngược
Các chương trình hiện có sẽ không bị ảnh hưởng trừ khi muốn tận dụng thay đổi này. Trong trường hợp đó, chúng có thể thực hiện một trong những cách sau:
Các chương trình đã mã hóa cứng bên được gọi theo cách tĩnh và chỉ cần bên đó dưới dạng một instruction account bất kỳ để đáp ứng ràng buộc do runtime áp đặt có thể nhận một trình giữ chỗ như NativeLoader1111111111111111111111111111111 để không làm thay đổi chỉ mục của các instruction account khác.
Tất cả chương trình hiện có khác vốn gọi động bất kỳ nội dung nào được truyền trong một instruction account cụ thể sẽ phải được cập nhật và triển khai lại để hưởng lợi từ việc gỡ bỏ hạn chế này.
Tối ưu hóa này không làm ảnh hưởng đến độ an toàn. Tính năng "delay visibility" đảm bảo rằng các chương trình không thể gọi những chương trình khác đã được thêm, sửa đổi hoặc xóa trong cùng một transaction.
Loader-v4
Agave 2.2 bổ sung hỗ trợ cho Loader-v4, một cơ chế triển khai chương trình tinh gọn và linh hoạt hơn, được thiết kế để thay thế Loader-v3. Được kích hoạt thông qua SIMD-0167, Loader-v4 đơn giản hóa việc quản lý program account, cải thiện quy trình nâng cấp và bổ sung các tính năng an toàn quan trọng cho chương trình đang hoạt động, đặc biệt là những chương trình vận hành trong môi trường có rủi ro cao như DeFi.
Các tính năng chính trong Loader-v4:
Mô hình một account: Loader-v4 loại bỏ nhu cầu sử dụng account proxy và bộ đệm dữ liệu chương trình riêng biệt. Giờ đây, một account duy nhất đại diện cho mỗi chương trình.
Chế độ bảo trì
Giờ đây, chương trình có thể được đưa vào "chế độ bảo trì" không thể thực thi mà không bị đóng vĩnh viễn hoặc triển khai lại. Điều này bảo toàn địa chỉ chương trình ban đầu, cho phép nhà phát triển tạm dừng thực thi (ví dụ: khi xảy ra khai thác lỗ hổng) mà không phải từ bỏ địa chỉ đó.
Thay đổi kích thước tùy ý
Loader-v4 hỗ trợ cả việc tăng và giảm kích thước tệp nhị phân của chương trình sau khi triển khai, cho phép phân bổ tài nguyên linh hoạt hơn và thu hồi tài sản bị khóa.
Tùy chọn sử dụng bộ đệm
Khác với Loader-v3, vốn luôn yêu cầu một buffer account bên ngoài khi triển khai lại, Loader-v4 không bắt buộc sử dụng bộ đệm. Giờ đây, chương trình có thể được triển khai lại trực tiếp vào program account chính, nhờ đó giảm một nửa lượng tài sản phải khóa trong quá trình tải lên.
Triển khai lại một phần
Loader-v3 yêu cầu tải lại toàn bộ tệp nhị phân của chương trình cho mỗi lần nâng cấp. Ngược lại, Loader-v4 hỗ trợ tải lên một phần, cho phép nhà phát triển chỉ vá các phần cụ thể của chương trình. Điều này đặc biệt hữu ích với các bản cập nhật nhỏ.
Di chuyển liền mạch từ Loader-v3
Các chương trình được triển khai bằng Loader-v3 có thể chuyển sang Loader-v4 mà không cần thay đổi địa chỉ chương trình. Quá trình này được thực hiện qua instruction Migrate mới trong Loader-v3. Thao tác này sẽ trì hoãn khả năng hiển thị, nghĩa là chương trình sẽ không khả dụng trong phần còn lại của slot hiện tại.
Sau khi Loader-v4 được kích hoạt, một feature gate riêng sẽ được kích hoạt để vô hiệu hóa các lượt triển khai mới lên Loader-v3. Các chương trình Loader-v3 hiện có vẫn hoạt động, nhưng tất cả lượt triển khai trong tương lai dự kiến sẽ sử dụng Loader-v4.
Khi hoàn tất một chương trình loader-v4, có thể chỉ định trước địa chỉ phiên bản tiếp theo, từ đó có khả năng hình thành một danh sách liên kết. Điều này cung cấp một giải pháp thay thế cho việc triển khai lại chương trình và cho phép giao diện người dùng cung cấp danh sách các phiên bản chương trình đã hoàn tất để người dùng lựa chọn.
Các cơ chế quản lý quyền hạn và đóng account vẫn giữ nguyên trong Loader-v4. Tất cả chức năng này sẽ khả dụng thông qua lệnh con CLI program-v4 mới.
Kết luận
Agave 2.2 là một cột mốc quan trọng đối với giao thức Solana, mang đến những cải tiến thiết yếu cho runtime và các khả năng mới giúp mở rộng giới hạn kỹ thuật của mạng. Bản phát hành này giới thiệu một số thay đổi chính: tăng 20% dung lượng block, tích hợp Accounts Lattice Hash (ALH) để băm trạng thái có khả năng mở rộng, nhiều nâng cấp cho hoạt động phát triển chương trình và hỗ trợ xác minh chữ ký Secp256r1, yếu tố thiết yếu để cho phép tích hợp mật mã trên quy mô đại chúng. Cùng nhau, các cải tiến này giúp tăng thông lượng, cải thiện trải nghiệm của nhà phát triển và nâng cao khả năng hỗ trợ nhiều loại ứng dụng hơn của mạng.
Dù đang xây dựng chương trình, vận hành validator hay tương tác với mạng, Agave 2.2 đều mang lại hiệu năng, tính linh hoạt và khả năng phục hồi cao hơn cho Solana.
Tài nguyên bổ sung
Bài viết liên quan
Đă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


