tensor_eigen/commands/
fees.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use crate::{spinner::pb_with_len, FEE_SHARDS};

use super::*;

use std::{fs::File, str::FromStr};

use solana_sdk::{
    instruction::Instruction, pubkey, signer::Signer, system_instruction, transaction::Transaction,
};

const TFEE_PROGRAM_ID: Pubkey = pubkey!("TFEEgwDP6nn1s8mMX2tTNPPz8j2VomkphLUmyxKm17A");

pub struct FeeParams {
    pub keypair_path: Option<PathBuf>,
    pub rpc_url: Option<String>,
}

pub fn generate_fee_shards() -> Result<()> {
    let mut shards = vec![];

    for i in 0..=255 {
        let shard: &[u8] = &[i];
        shards.push(
            Pubkey::find_program_address(&[b"fee_vault", shard], &TFEE_PROGRAM_ID)
                .0
                .to_string(),
        );
    }

    let file = File::create("fee_vault_shards.json")?;
    serde_json::to_writer_pretty(&file, &shards)?;

    Ok(())
}

pub fn fund_shards(args: FeeParams) -> Result<()> {
    let config = CliConfig::new(args.keypair_path, args.rpc_url)?;

    let rent_exempt_lamports = config.client.get_minimum_balance_for_rent_exemption(0)?;

    // Convert FEE_SHARDS to Pubkeys
    let shard_pubkeys: Vec<Pubkey> = FEE_SHARDS
        .iter()
        .filter_map(|s| Pubkey::from_str(s).ok())
        .collect();

    // Check balances and create transfer instructions only for underfunded shards
    let mut instructions: Vec<Instruction> = Vec::new();
    let pb = pb_with_len("shards checked", shard_pubkeys.len() as u64)?;

    for pubkey in &shard_pubkeys {
        let balance = config.client.get_balance(pubkey)?;
        if balance < rent_exempt_lamports {
            instructions.push(system_instruction::transfer(
                &config.keypair.pubkey(),
                pubkey,
                rent_exempt_lamports - balance,
            ));
        }
        pb.inc(1);
    }
    pb.finish_with_message("Finished checking shard balances");

    if instructions.is_empty() {
        println!("All shards are already funded.");
        return Ok(());
    }

    // Pack instructions into transactions (15 instructions per transaction)
    for chunk in instructions.chunks(15) {
        let transaction = Transaction::new_signed_with_payer(
            chunk,
            Some(&config.keypair.pubkey()),
            &[&config.keypair],
            config.client.get_latest_blockhash()?,
        );

        config
            .client
            .send_and_confirm_transaction_with_spinner(&transaction)?;
    }

    Ok(())
}

pub fn get_shard_balances(args: FeeParams) -> Result<()> {
    let config = CliConfig::new(args.keypair_path, args.rpc_url)?;

    let shard_pubkeys: Vec<Pubkey> = FEE_SHARDS
        .iter()
        .filter_map(|s| Pubkey::from_str(s).ok())
        .collect();

    let rent_exempt_lamports = config.client.get_minimum_balance_for_rent_exemption(0)?;

    let mut fully_funded_count = 0;

    for pubkey in &shard_pubkeys {
        let balance = config.client.get_balance(pubkey)?;
        let status = if balance >= rent_exempt_lamports {
            fully_funded_count += 1;
            "✓"
        } else {
            "✗"
        };
        println!("{} {} {}", pubkey, balance, status);
    }

    if fully_funded_count == shard_pubkeys.len() {
        println!("All shards fully funded!");
    } else {
        println!(
            "{}/{} shards fully funded.",
            fully_funded_count,
            shard_pubkeys.len()
        );
    }

    Ok(())
}