本文深入分析了Jito在Solana平台上的架构及其运作方式,重点解释了Jito Relayer、Block Engine以及交易打包(Bundle)的处理流程。通过介绍MEV(最大化可提取价值)的捕获机制,Jito在提高交易效率与利润分配方面的作用得到了详细阐述,为开发者和验证者提供了清晰的参考资源。
图:Solana REV; Jito Tips以绿色标识。来源:Blockworks。
图:过去30天趋势,Solana REV; Jito Tips以绿色标识。来源:Jito.network。
在过去的一年里,Solana的实际经济价值(REV)——交易费用加上协议外的MEV小费——飙升至14亿美元的历史最高值。大部分增长来自Jito小费,单独占据了Solana 2024年12月REV的约一半。尽管逐月数据可能会波动,但从更大的角度来看,与去年的水平相比增长了近50倍。在过去30天中,Jito小费几乎占据了总费用和小费的三分之二。这一爆炸性趋势突显了Jito在推动Solana的费用收入和MEV活动中的关键作用。
鉴于Jito作为“领先的MEV基础设施团队”的地位,理解其基础架构至关重要——特别是随着网络的经济激励越来越多地围绕MEV捕获。然而,将Jito的技术(如Jito区块引擎、Jito-Solana客户端等)拼凑在一起理解其实际工作原理可能会很困难。它们代表了Solana“模块化堆栈”中一些最重要的基础设施,而Jito的MEV优化验证器客户端已经保护了超过90%的Solana活跃股份。
在本文中,我们将提供关于Jito内在工作机制的完整说明。我们将重点介绍MEV小费是如何处理的,这些优化对验证器和用户的意义,以及Jito生态系统如何适应Solana的更大战略路线图。我们希望提供一个完整且详细的参考资料,以帮助开发者、验证器和质押者充分理解在高交易量环境中运行Jito的优势和挑战。
Jito是一个经过修改的Solana客户端,能够实现更高效、更有利可图且更公平的MEV价值捕获。它在标准的Solana验证器基础上构建,增加了额外的链下组件(中继器和区块引擎)以及两个核心链上程序(小费支付程序和小费分配程序)。
Jito的最终目标是实现MEV价值捕获——在Solana区块内的可货币化机会——同时将这些收益重新分配给验证器和委托人,且所有操作都尽量减少信任假设。最终,Tip Rewards NCN
(节点共识网络)将进一步分散奖励分配,消除当前存在的单点故障。
以下是Jito系统架构的高层次图示。它展示了用户交易如何流入网络,Jito的链下组件(中继器、区块引擎)如何处理它们,以及链上程序如何最终完成MEV小费的分配。
来源:Jito-Solana, https://docs.Jito.wtf/
来源:https://www.bee.com/15574.html
组件
典型流:
BlockEngineStage
。BundleStage
)。BankingStage
。在深入之前,让我们首先了解Jito捆绑的工作原理。
捆绑是一组必须以原子性和顺序执行的交易(最多五个交易)。这意味着如果一个交易失败,整个捆绑将被丢弃。Jito通过专门的BundleStage
扩展了Solana的验证器流水线,该阶段处理这些捆绑。此捆绑的主要目标是捕获套利机会、清算或其他需要及时执行的盈利策略。
关键约束:
sequenceDiagram
participant User
participant Relayer
participant Searcher
participant BlockEngine
participant JitoValidator
participant TipPaymentProgram
User->>Relayer: 提交含有MEV小费的交易通过拍卖
Relayer->>JitoValidator: 持有交易200毫秒然后发送
Searcher->>BlockEngine: 创建并提交捆绑
BlockEngine->>BlockEngine: 模拟并选择最佳捆绑
JitoValidator->>BlockEngine: 发送交易(gRPC)
BlockEngine->>JitoValidator: 发送选择的捆绑(gRPC)
JitoValidator->>JitoValidator: 确保tip_receiver = TDA 为本Epoch
JitoValidator->>BundleStage: 原子执行捆绑
BundleStage->>BankingStage: 如果成功则提交
BankingStage->>TipPaymentProgram: 执行小费支付交易,存入lamports于小费PDA
JitoValidator->>JitoValidator: 最终确定区块
Jito捆绑拍卖简化了Solana上的区块空间分配,使得这一过程更加高效和有利可图。
通过频繁的拍卖及利用并行锁定模式,确保高价值交易被优先处理。这样的设置不仅增加了验证器获得的小费,还帮助搜索者和交易者更快地执行他们的策略。在Jito生态系统中,捆绑拍卖在提升Solana网络的整体性能和盈利能力方面发挥着至关重要的作用。
Jito捆绑拍卖决定哪些捆绑将在当前区块中执行。通过频繁的拍卖和利用并行锁定模式,确保高价值交易被优先处理。这样的设置不仅增加了验证器获得的小费,也帮助搜索者和交易者更快地执行策略。
中继器是Jito Solana架构中的重要组成部分,作为进入系统的交易网关。它是一个独立的服务,Jito验证器通过gRPC与之连接,有效地充当交易“网关”或“代理”。中继器延迟交易200毫秒,确保形成捆绑的机会。它与Jito-Solana验证器的集成使得MEV价值捕获和区块生成无缝对接。
关键功能:
关键代码库:
fn start_consuming_relayer_packets(
mut client: RelayerClient<...>,
packet_tx: &Sender<PacketBatch>,
...
) -> Result<(), ProxyError> {
let mut packet_stream = client.subscribe_packets(...).await?.into_inner();
while let Some(message) = packet_stream.message().await? {
match message.msg {
Some(relayer::subscribe_packets_response::Msg::Batch(proto_batch)) => {
let packet_batch = PacketBatch::new(
proto_batch.packets.iter().map(proto_packet_to_packet).collect()
);
// 可能信任或不信任
if trust_packets {
banking_packet_sender.send(...)?
} else {
packet_tx.send(packet_batch)?;
}
}
Some(relayer::subscribe_packets_response::Msg::Heartbeat(_)) => {
// 触发心跳频道
}
None => { ... }
}
}
Ok(())
}
典型流:
banking_packet_sender
。中继器与Jito Solana架构中的其他多个组件集成:
中继器面临着几个挑战,包括:
为了应对这些挑战,中继器实施了几项优化:
区块引擎是Jito Solana MEV价值捕获系统的核心。区块引擎是另一个gRPC服务,专门用于捆绑和交易流程。它通常与中继器并行使用。它位于中继器和Jito-Solana验证器之间,充当决策层,处理、模拟并选择MEV捆绑。下面我们将探讨其功能的详细分解。
flowchart LR
A[中继器] --> B[交易队列]
B --> C[模拟引擎]
C --> D[捆绑选择]
D --> E[转发模块]
E --> F[验证器]
关键责任:
关键代码片段:
pub struct BlockEngineStage {
t_hdls: Vec<JoinHandle<()>>,
}
impl BlockEngineStage {
pub fn new(
block_engine_config: Arc<Mutex<BlockEngineConfig>>,
bundle_tx: Sender<Vec<PacketBundle>>,
packet_tx: Sender<PacketBatch>,
banking_packet_sender: BankingPacketSender,
exit: Arc<AtomicBool>,
block_builder_fee_info: Arc<Mutex<BlockBuilderFeeInfo>>,
) -> Self {
let thread = Builder::new().name("block-engine-stage".to_string())
.spawn(move || {
let rt = tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap();
rt.block_on(Self::start(...));
}).unwrap();
Self { t_hdls: vec![thread] }
}
}
let subscribe_bundles_stream = client
.subscribe_bundles(SubscribeBundlesRequest {})
.await?
.into_inner();
while let Some(resp) = subscribe_bundles_stream.message().await? {
let bundles = resp.bundles.into_iter()
.map(|bundle_proto| PacketBundle {
batch: PacketBatch::new(
bundle_proto.packets.into_iter().map(proto_packet_to_packet).collect()
),
bundle_id: bundle_proto.uuid,
})
.collect();
// 转发到bundle_stage:
bundle_tx.send(bundles)?;
}
BlockEngineValidatorClient
订阅两个主要流:
subscribe_bundles
— 入站捆绑(每个“PacketBundle”是一组交易,通常每个捆绑4-5个交易)。BlockBuilderFeeInfoRequest
,用来让验证器查询区块引擎当前区块构建者的公钥和佣金。典型流:
BlockEngineStage
与区块引擎连接。通过gRPC,区块引擎同时传递正常交易(几乎就像第二个流水线)和捆绑。bundle_tx => consumed
由BundleStage
处理。trust_packets == true
),则绕过签名验证。BundleStage
是Jito-solana验证器中的新流水线,处理来自区块引擎的捆绑。捆绑具有所有包含的交易必须以原子方式成功执行或完全失败的特性——对于MEV流程来说至关重要。通过设计,BundleStage
作为现有Solana交易流程(如BankingStage)的并行对应物,但它对捆绑执行强制要求更严格的原子保证。一旦捆绑被接受,该捆绑中所有交易成功落入一个区块,或者整个捆绑被拒绝。
关键责任:
关键代码片段:
bundle_consumer.rs
协调整个流水线:接收、路由到专门的逻辑以进行模拟、原子锁定、最终提交等。bundle_account_locker.rs
确保捆绑一组交易所用的所有账户从系统的其余部分锁定,直到捆绑完成。如果多个捆绑到达,这些锁定可以防止冲突修改。bundle_packet_receiver.rs
接收来自区块引擎或中继器的入站gRPC基础或本地PacketBundle
流,并将其发送至下一个阶段。典型流:
// 来源于`bundle_packet_receiver.rs`的粗略代码片段
while let Ok(packet_bundles) = bundle_receiver.recv_timeout(recv_timeout) {
// ... 将其收集到内部结构中 ...
}
BundleStage
拥有一个BundleReceiver(在bundle_packet_receiver.rs
中)负责拾取捆绑。这些捆绑不是通过通常的原始UDP或QUIC流量传入,而是从区块引擎或中继器通过可靠的gRPC通道到达。
/// 一个捆绑有如下要求:
/// - 所有交易必须可清洗
/// - 无重复签名
/// - 不得包含黑名单帐户
/// - 不能已经被处理过或包含无效的块哈希
pub fn build_sanitized_bundle(
&self,
bank: &Bank,
blacklisted_accounts: &HashSet<Pubkey>,
transaction_error_metrics: &mut TransactionErrorMetrics,
) -> Result<SanitizedBundle, DeserializedBundleError> {
if bank.vote_only_bank() {
return Err(DeserializedBundleError::VoteOnlyMode);
}
let transactions: Vec<SanitizedTransaction> = self
.packets
.iter()
.filter_map(|p| {
p.build_sanitized_transaction(
bank.vote_only_bank(),
bank,
bank.get_reserved_account_keys(),
)
})
.collect();
if self.packets.len() != transactions.len() {
return Err(DeserializedBundleError::FailedToSerializeTransaction);
}
let unique_signatures: HashSet<&Signature, RandomState> =
HashSet::from_iter(transactions.iter().map(|tx| tx.signature()));
if unique_signatures.len() != transactions.len() {
return Err(DeserializedBundleError::DuplicateTransaction);
}
let contains_blacklisted_account = transactions.iter().any(|tx| {
tx.message()
.account_keys()
.iter()
.any(|acc| blacklisted_accounts.contains(acc))
});
if contains_blacklisted_account {
return Err(DeserializedBundleError::BlacklistedAccount);
}
// 假设所有内容均成功锁定,以检查是否有已经处理的交易或过期/无效块哈希
let lock_results: Vec<_> = repeat(Ok(())).take(transactions.len()).collect();
let check_results = bank.check_transactions(
&transactions,
&lock_results,
MAX_PROCESSING_AGE,
transaction_error_metrics,
);
if check_results.iter().any(|r| r.is_err()) {
return Err(DeserializedBundleError::FailedCheckTransactions);
}
Ok(SanitizedBundle {
transactions,
bundle_id: self.bundle_id.clone(),
})
}
Jito包括一个ImmutableDeserializedBundle
逻辑(在 immutable_deserialized_bundle.rs
中)以解包每个捆绑。它检查签名,丢弃无效或重复的交易,并确保整个捆绑可以被处理。失败的交易会让整个捆绑被丢弃。
pub struct LockedBundle<'a, 'b> {
bundle_account_locker: &'a BundleAccountLocker,
sanitized_bundle: &'b SanitizedBundle,
bank: Arc<Bank>,
}
impl<'a, 'b> LockedBundle<'a, 'b> {
pub fn new(
bundle_account_locker: &'a BundleAccountLocker,
sanitized_bundle: &'b SanitizedBundle,
bank: &Arc<Bank>,
) -> Self {
Self {
bundle_account_locker,
sanitized_bundle,
bank: bank.clone(),
}
}
pub fn sanitized_bundle(&self) -> &SanitizedBundle {
self.sanitized_bundle
}
}
// 自动解锁捆绑帐户时调用
impl<'a, 'b> Drop for LockedBundle<'a, 'b> {
fn drop(&mut self) {
let _ = self
.bundle_account_locker
.unlock_bundle_accounts(self.sanitized_bundle, &self.bank);
}
}
impl BundleAccountLocks {
pub fn read_locks(&self) -> HashSet<Pubkey> {
self.read_locks.keys().cloned().collect()
}
pub fn write_locks(&self) -> HashSet<Pubkey> {
self.write_locks.keys().cloned().collect()
}
pub fn lock_accounts(
...
}
...
一旦验证通过,BundleStage
将会锁定捆绑的整个集合所有使用的账户(bundle_account_locker.rs
)。这是一个重要步骤:不允许部分或并行使用这些账户,从而确保原子和无冲突的使用。
bundle_consumer.rs
执行捆绑中的交易,检查一系列潜在的失败:无效的块哈希、lamports不足或程序错误。如果任何交易的模拟失败,整个捆绑将被丢弃。如果全部通过:
系统会将交易加载到一个顺序批次中,提交给PoH(账本记录)。
由于交易被锁定且成本模型事先计算,系统知道可以安全地应用它们。
原子提交
fn execute_record_commit_bundle(
committer: &Committer,
recorder: &TransactionRecorder,
log_messages_bytes_limit: &Option<usize>,
max_bundle_retry_duration: Duration,
sanitized_bundle: &SanitizedBundle,
bank_start: &BankStart,
) -> ExecuteRecordCommitResult {
let transaction_status_sender_enabled = committer.transaction_status_sender_enabled();
let mut execute_and_commit_timings = LeaderExecuteAndCommitTimings::default();
debug!("捆绑: {} 正在执行", sanitized_bundle.bundle_id);
let default_accounts = vec![None; sanitized_bundle.transactions.len()];
let mut bundle_execution_results = load_and_execute_bundle(
...
)
...
}
如果最终执行和记录步骤成功,所有交易将被添加到账本(通过PoHRecorder
)。如果有些意外失败(例如突然出现的AccountInUse
错误),Jito会强制回滚整个集合。
/// 验证器需要管理与两个小费相关程序的状态
fn handle_tip_programs(
bundle_account_locker: &BundleAccountLocker,
tip_manager: &TipManager,
// ...
bank_start: &BankStart,
bundle_stage_leader_metrics: &mut BundleStageLeaderMetrics,
) -> Result<(), BundleExecutionError> {
// 1) 初始化小费支付和小费分配程序(如有需要)
if let Some(initialize_tip_programs_bundle) =
tip_manager.get_initialize_tip_programs_bundle(&bank_start.working_bank, &keypair)
{
// 锁定账户,然后执行和提交...
}
// 2) 创建并发送"小费刻度捆绑"(如小费接收者或块生成者发生更改时)
if let Some(tip_crank_bundle) = tip_manager.get_tip_programs_crank_bundle(
&bank_start.working_bank,
&kp,
&block_builder_fee_info.lock().unwrap(),
)? {
// 锁定账户,然后执行和提交...
}
Ok(())
}
BundleStage
将检查小费支付和小费分配程序是否已完全初始化。如果没有,它将自动生成(或重新初始化)它们,通过发送一个短初始化捆绑的交易。TipDistributionAccount
。如果一个新的轮次开始(或小费分配账户需要变更),验证器将构建另一个小捆绑——"小费刻度捆绑"。这确保小费接收者更新为正确的位置,以便验证器能够获得预期的MEV小费股份。TipDistributionAccount
。如果链上状态与预期不同,BundleStage
自动生成内部交易(如"清理旧小费"或"更改块生成者+小费接收者"),首先提交这些交易,然后再处理用户捆绑。BundleStage
将撤销整个小费更新。这避免在插槽中对小费账户进行部分或相互矛盾的更改。一旦验证器的领导插槽结束,BundleStage
会冲洗剩余或部分处理的捆绑。这可以防止过期状态干扰下一个领导者插槽。
区块引擎与Jito Solana架构中的几个其他组件进行集成:
区块引擎面临几个挑战,包括:
BundleStage
)强制执行这一顺序、切忌菜多菜少的属性。区块引擎必须准备这些捆绑,并以验证器可以容易地接受或拒绝的方式呈现它们。这导致有趣的难题,因为:为了应对这些挑战,区块引擎实施了几项优化:
Jito小费支付程序是Jito Solana架构中另一个关键组件,负责存储和管理MEV小费。通过将小费安全存储在PDA中,并向小费分配程序提供必要的数据,它确保搜索者有动力提交有利可图的MEV捆绑,而验证器和质押者则得到了公平的报酬。
关键责任:
典型流程
用户支付额外的MEV小费以获得交易的优先权。这些小费是存入多达八个静态PDAs (例如,PDA0…PDA7)
的lamports。配置PDA (CFG_PDA)
将它们全部联系在一起,允许验证器在每个轮次中设置正确的tip_receiver
。
小费支付流程:
changeTipReceiver
指令将当前轮次的TDA
(小费分配账户)设置为tip_receiver
。PDA
中。PDA
会倾倒到TDA
中进行分配。小费支付程序与Jito Solana架构中的多个其他组件进行集成:* 区块引擎:
提示支付程序面临几个挑战,包括:
为了解决这些挑战,提示支付程序实施了多项优化:
TIP_ACCOUNT_SEED_0..7
, CONFIG_ACCOUNT_SEED
) 键控的 PDAs,以确保只有授权用户可以重新分配或从这些提示账户中提取。 initialize_tip_payment_program_tx
,initialize_tip_distribution_account_tx
,或同时管理多个 PDAs 的“crank”捆绑包,而不是逐一处理。 提示分发程序管理每个纪元的提示收集。每个验证者都有一个 TDA: PDA(vote_key, epoch)
。它累积了该纪元的所有提示。
在纪元结束时,一个链下(或未来的去中心化 NCN)过程计算一个 Merkle 根,定义 TDA
中的提示是如何在验证者及其委托者(或质押者)之间按股份比例分配的。当前的提示分配是集中的,新的 JIP 提示奖励 NCN 将去中心化这个过程。
关键功能:
提示分发程序与 Jito Solana 架构中的几个其他组件集成:
在纪元结束时,一个链下机构计算分配。Merkle 根上传到链上以便质押者索取。
sequenceDiagram
participant OffChain
participant JitoValidator
participant TipDistributionProgram
participant Staker
OffChain->>OffChain: 计算 TDA 的 Merkle 根(验证者和质押者的份额)
OffChain->>JitoValidator: 提交交易在链上上传 Merkle 根
JitoValidator->>TipDistributionProgram: 用 Merkle 根更新 TDA
Staker->>TipDistributionProgram: 提交带有 Merkle 证明的索赔
TipDistributionProgram->Staker: 转移质押者的份额
在当前设置(预 NCN)中,由一个集中或“许可”方负责在每个纪元结束时确定奖励:
一个链下服务(通常由验证者或指定的权威机构运行)根据验证者及其质押者在该纪元获得了多少提示来计算 Merkle 根。
该服务然后向验证者发送交易,验证者将 Merkle 根传递给链上的 TipDistributionProgram
。
一旦 Merkle 根被存储,每个质押者提供 Merkle 证明以索取其提示份额。
在提供有效证明后,TipDistributionProgram
将正确的 lamports 部分转移到质押者的账户中。
Merkl 树中存储的内容
##[derive(Clone, Eq, Debug, Hash, PartialEq, Deserialize, Serialize)]
pub struct TreeNode {
// 要索取提示的权益账户或验证者投票账户。
pub claimant: Pubkey,
// ClaimStatus PDA 的 Pubkey(用于防止双重索赔)。
pub claim_status_pubkey: Pubkey,
// 上述 claim_status_pubkey 的 Bump 种子。
pub claim_status_bump: u8,
// 通常来自质押账户的质押者和提取者字段。
pub staker_pubkey: Pubkey,
pub withdrawer_pubkey: Pubkey,
// 当前纪元的提示应支付给该索赔者的 lamports。
pub amount: u64,
// 从该叶子到根的 Merkle 证明(树构建后填充)。
pub proof: Option<Vec<[u8; 32]>>,
}
备注:
(这是一项正在进行中的工作,所有具体细节现在都处于研发阶段。)
Jito 提示奖励 NCN 是一个去中心化框架,旨在确保在 Jito-Solana 生态系统中公平高效的奖励分配。通过结合链上程序与链下过程,它提供了一种强大的机制来处理奖励,确保所有参与者都有动力为网络的安全性和效率做出贡献。该系统专注于共识和削减机制,确保奖励分配的公平,并确保运营者对他们的参与承担责任。
graph TD
A[纪元开始] --> B[存入奖励]
B --> C[奖励 Dropbox]
C --> D[转移到 EpochRewardMerkleRoot]
D --> E[创建 EpochRewardMerkleRoot]
E --> F[运营者创建 Merkle 树]
F --> G[提交 Merkle 根票据]
G --> H[对 Merkle 根进行投票]
H --> I{达成共识了吗?}
I -->|是| J[最终确定 Merkle 根]
I -->|否| K[处理失信纪元]
J --> L[分配奖励]
L --> M[接受者收到奖励]
K --> N[将奖励转移到当前纪元]
N --> L
H --> O[削减条件]
O --> P{运营者投票了吗?}
P -->|否| Q[削减运营者]
P -->|是| R{运营者达成共识了吗?}
R -->|否| Q
R -->|是| S[运营者获得奖励]
Q --> T[运营者被削减]
S --> L
T --> L
关键组件:
奖励分配流程涉及几个步骤,从存入奖励到分配给接受者。以下是每个步骤的详细解释,以及相关代码段。
pub fn process_dropbox_to_latest(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
// 在此添加代码
todo!();
}
奖励可以存入 EpochRewardMerkleRoot
账户或 RewardDropbox
PDA。使用 dropbox_to_latest
指令转移奖励从 RewardDropbox
到当前纪元的 EpochRewardMerkleRoot
。
pub fn process_upload_and_vote(program_id: &Pubkey, accounts: &[AccountInfo], root: MerkleRoot) -> ProgramResult {
// 在此添加代码
todo!();
}
运营者在投票窗口内创建并对其 EpochRewardMerkleRootTicket
投票。使用 upload_and_vote
指令根据运营者的投票更新根。
pub fn process_distribute_crank(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
// 在此添加代码
todo!();
}
如果达成共识,则使用 distribute_crank
指令根据共识根哈希作为证明分配来自有效 EpochRewardMerkleRoot
的奖励。
pub fn process_delinquent_to_latest(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
// 在此添加代码
todo!();
}
如果不达成共识,则奖励可以使用 delinquent_to_latest
指令转移到当前纪元的奖励。
pub fn process_slash(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
// 在此添加代码
todo!();
}
未在投票窗口内投票或未达成共识的运营者可以使用 slash
指令进行削减。
NCN 节点的运营者各自计算 Merkle 根。一旦达成三分之二的共识,该根将被发布到链上,奖励分配会自动包含 DAO 和 NCN 参与者的 3% 费用。
sequenceDiagram
participant OffChainSoftware
participant Operators (NCN)
participant TipRouterNCN
participant TipDistributionProgram
participant DAO
participant Staker
OffChainSoftware->>Operators: 计算 TDA 的 Merkle 根
Operators->>TipRouterNCN: 对 Merkle 根进行投票,争取 66% 的共识
TipRouterNCN->>TipDistributionProgram: 一旦达成共识,上传 Merkle 根到链上
TipDistributionProgram->>DAO: 扣除 3% 费用(2.7% 给 DAO,0.3% 给 NCN 参与者)
TipDistributionProgram->Staker: 在索赔时,用证明支付相关部分
当 TipRouter NCN
正式上线时,分配通过一网络的运营者去中心化:
链下软件首先将所有的提示数据汇总为候选 Merkle 根。每个运营者(NCN 节点)计算或验证同一个 Merkle 根。
这些运营者通过 TipRouterNCN
智能合约提交对 Merkle 根的投票。如果三分之二的股权投票赞成,该 Merkle 根会最终确定。
共识达成后,NCN 程序自动将 Merkle 根发布到链上的 TipDistributionProgram
。
奖励的 3% 分成归 DAO 财库(2.7%)和 NCN 参与者(0.3%)。其余则根据 Merkle 根的规定支付给验证者和质押者。
最后,每个质押者使用 Merkle 证明索取他们的部分,确保分配的可信度更高。
备注:
提示分发程序面临几个挑战,包括:
为了解决这些挑战,提示分发程序可能实施几项优化:
总之,在 Solana 上的 MEV 是巨大的——无论在规模上还是在如何塑造用户体验和验证者经济上。超过 90% 的 Solana 股权选择进入 Jito 网络,理解 Jito 在很大程度上就是理解 Solana 如何日常运作。我们对 Jito 中继器、区块引擎、捆绑阶段及周边系统架构的深入探讨,应该为分析和交互 Solana 上的交易和 MEV 提供坚实基础。
在 Eclipse,我们相信开放研究可以为类似 Solana 的前沿区块链协议的演变带来更高透明度——最终建立链上机制、数据分析和最佳实践之间的桥梁。我们将继续发布作品,解析关键 Solana 基础设施的内在工作,以便生态系统中的每个人都能从经过深思熟虑的深入视角中受益。
通过阐明 Jito 的架构和 MEV 过程,我们希望更多的利益相关者——搜索者、交易者、验证者和普通用户——能拥有必要的知识,负责地参与和优化 Solana 网络。如果你有疑问或见解,欢迎合作,我们期待着在 Solana 新兴的“模块化”栈周围促进一个越来越丰富的研究社区。
- 原文链接: github.com/thogiti/thogi...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!