背景

Solana 默认配置手续费会燃烧50%,有些时候不需要燃烧

配置

先直接说如何配置
拿multinode-demo/setup.sh 举例,初始化genesis时,传入 --fee-burn-percentage 0
例如尾部加一行

...
default_arg --fee-burn-percentage 0

$solana_genesis "${args[@]}"

代码分析

genesis创建时,会读取传入参数

genesis/src/main.rs

...
.arg(
    Arg::with_name("fee_burn_percentage")
    .long("fee-burn-percentage")
    .value_name("NUMBER")
    .takes_value(true)
    .default_value(default_fee_burn_percentage)
    .help("percentage of collected fee to burn")
    .validator(is_valid_percentage),
)
...

手续费派发逻辑

runtime/src/bank/fee_distribution.rs

pub(super) fn distribute_transaction_fees(&self) {
        let collector_fees = self.collector_fees.load(Relaxed);
        if collector_fees != 0 {
            let (deposit, mut burn) = self.fee_rate_governor.burn(collector_fees); // 燃烧一定比例
            if deposit > 0 {
                let validate_fee_collector = self.validate_fee_collector_account();
                match self.deposit_fees(
                    &self.collector_id,
                    deposit,
                    DepositFeeOptions {
                        check_account_owner: validate_fee_collector,
                        check_rent_paying: validate_fee_collector,
                    },
                ) {
                    Ok(post_balance) => {
                        self.rewards.write().unwrap().push((
                            self.collector_id,
                            RewardInfo {
                                reward_type: RewardType::Fee,
                                lamports: deposit as i64,
                                post_balance,
                                commission: None,
                            },
                        ));
                    }
                    Err(err) => {
                        debug!(
                            "Burned {} lamport tx fee instead of sending to {} due to {}",
                            deposit, self.collector_id, err
                        );
                        datapoint_warn!(
                            "bank-burned_fee",
                            ("slot", self.slot(), i64),
                            ("num_lamports", deposit, i64),
                            ("error", err.to_string(), String),
                        );
                        burn += deposit;
                    }
                }
            }
            self.capitalization.fetch_sub(burn, Relaxed);
        }
    }

sdk/program/src/fee_calculator.rs

pub fn burn(&self, fees: u64) -> (u64, u64) {
    let burned = fees * u64::from(self.burn_percent) / 100;
    (fees - burned, burned)
}