区块链中文技术社区

Solana 计算账户租金与燃烧逻辑

分析文档

https://docs.anza.xyz/implemented-proposals/rent/

收租原因:Solana 上的账户可能具有与账户余额(Account::lamports)分开的所有者控制状态(Account::data)。由于网络上的验证者需要在内存中维护此状态的工作副本,因此网络会针对此资源消耗收取基于时间和空间的费用,也称为租金。

费用收取间隔:每个纪元,genesis时固定
免租下限:余额不小于当前账户所需的2年租金
为什么设置2年:根据硬件成本每2年下降 50% 的事实得出
下次收租时间:Account::rent_epoch
交易不可见:租金的收取是根据协议级账户更新进行的,例如向验证者分配租金,这意味着没有相应的租金扣除交易。因此,租金的收取是相当不可见的,只能通过最近的交易或给定其账户地址前缀的预定时间隐式观察到。

分析代码

版本:v2.0.25
核心代码:https://github.com/anza-xyz/agave/blob/v2.0.25/sdk/program/src/rent.rs

核心默认参数

参数解释默认值genesis初始化参数
lamports_per_byte_year租赁费率(单位:lampports/byte-year)1000000000 / 100 x 365 / (1024 x 1024)lamports_per_byte_year
exemption_threshold账户余额必须包含租金的时间(以年为单位)才能免除租金2.0rent_exemption_threshold
burn_percent所收取租金中被销毁的百分比。有效值在 [0, 100] 范围内。剩余百分比分配给验证者。50rent_burn_percentage

ACCOUNT_STORAGE_OVERHEAD:128,这是存储没有数据的账户所需的字节数。在计算 [Rent::minimum_balance] 时,它会被添加到账户数据长度中。

核心方法

 /// 给定帐户数据大小的免租应付最低余额。
pub fn minimum_balance(&self, data_len: usize) -> u64 {
     let bytes = data_len as u64;
     (((ACCOUNT_STORAGE_OVERHEAD + bytes) * self.lamports_per_byte_year) as f64
      * self.exemption_threshold) as u64
 }

/// 给定的余额和数据长度是否可以免除。
pub fn is_exempt(&self, balance: u64, data_len: usize) -> bool {
    balance >= self.minimum_balance(data_len)
}

minimum_balance 中 字节的长度由基础账户字节数(128)+存储数据字节长度累加,然后乘以租赁费率(费用/每年字节),再乘以免除阈值(2)
对于普通没有数据的地址,最小的免租计算为 ACCOUNT_STORAGE_OVERHEAD x lamports_per_byte_year x exemption_threshold
默认参数情况下,免租下限计算为 0.00089 SOL

目前租金逻辑将被禁用
已生效:Devnet, Testnet,可能主网也快支持了
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0084-disable-rent-fees-collection.md

对于genesis中cluster_type等于ClusterType::Development默认会开启所有feature,包含该禁用

if genesis_config.cluster_type == ClusterType::Development {
    solana_runtime::genesis_utils::activate_all_features(&mut genesis_config);
}

如果想在ClusterType::Development类型下禁用feature disable_rent_fees_collection,如果首次部署,简单粗暴直接注释掉激活行

// (disable_rent_fees_collection::id(), "Disable rent fees collection #33945"),

总结

  1. 收租配置在genesis中固定配置
  2. 每个纪元收取一次
  3. 余额不小于当前账户所需的2年租金时免租
  4. 下次收租时间:Account::rent_epoch
  5. 租金计算方式:基础账户字节数(128)+存储数据字节长度累加,然后乘以租赁费率(费用/每年字节),再乘以免除阈值(2)
  6. 普通没有数据的地址,默认参数情况下,账户余额不小于 0.00089 SOL 免租
  7. 收租逻辑在cluster_type Development类型下默认禁用,如需使用,需要手动调整,并且此功能主网可能也将被禁用

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »