regolith-labs / ore-cli

Command line interface for ORE cryptocurrency mining.
919 stars 443 forks source link

reduce API calls in busses script #81

Open DanielChrobak opened 3 weeks ago

DanielChrobak commented 3 weeks ago

use get_multiple_accounts instead of get_account_data to reduce API calls

pmcochrane commented 3 weeks ago

From my testing of this, I'm receiving an error message for your new code:

called `Result::unwrap()` on an `Err` value: Error { request: Some(GetMultipleAccounts), kind: Reqwest(reqwest::Error { kind: Status(413), u
rl: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("XXXXXXXXXXX.solana-devnet.quiknode.pro")), port: None, path: "/6ce56c53d2f8c7ab0c455b44e3c2e4e5481227a3/", query: None, fragment: None } }) }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

I twiddled your code a little to get it to show the error message:

match client.get_multiple_accounts(&BUS_ADDRESSES).await {
    Ok(data) => {
        for (_address, account) in BUS_ADDRESSES.iter().zip(data.iter()) {
            if let Some(account) = account {
                let data_bytes = &account.data[..]; // Extract data bytes
                if let Ok(bus) = Bus::try_from_bytes(data_bytes) {
                    let rewards = (bus.rewards as f64) / 10f64.powf(TOKEN_DECIMALS as f64);
                    println!("Bus {}: {} ORE", bus.id, rewards);
                }
            }
        }
    }
    Err(err) => {
        eprintln!("Error: {}", err); 
    }
}

Digging into this gives an error: Error: HTTP status client error (413 Payload Too Large) for url (https://XXXXXX.solana-devnet.quiknode.pro/6ce56c53d2f8c7ab0c455b44e3c2e4e5481227a3/)

Maybe it's because I am using a free RPC

pmcochrane commented 3 weeks ago

Free RPC for quiknode only allows 5 items in a call https://support.quicknode.com/hc/en-us/articles/20626358903185-Understanding-the-413-Request-Entity-Too-Large-Error

pmcochrane commented 3 weeks ago

My error can be worked around by calling get_multiple_accounts twice:

        match client.get_multiple_accounts(&BUS_ADDRESSES[0..4]).await {
            Ok(data) => {
                for (_address, account) in BUS_ADDRESSES.iter().zip(data.iter()) {
                    if let Some(account) = account {
                        let data_bytes = &account.data[..]; // Extract data bytes
                        if let Ok(bus) = Bus::try_from_bytes(data_bytes) {
                            let rewards = (bus.rewards as f64) / 10f64.powf(TOKEN_DECIMALS as f64);
                            let theoretical_rewards = (bus.theoretical_rewards as f64) / 10f64.powf(TOKEN_DECIMALS as f64);
                            println!("Bus {}: {:} ORE [{:} ORE (theoretical)]", bus.id, rewards, theoretical_rewards);
                                }
                    }
                }
            }
            Err(err) => {
                eprintln!("Error: {}", err); 
            }
        }
        match client.get_multiple_accounts(&BUS_ADDRESSES[4..8]).await {
            Ok(data) => {
                for (_address, account) in BUS_ADDRESSES.iter().zip(data.iter()) {
                    if let Some(account) = account {
                        let data_bytes = &account.data[..]; // Extract data bytes
                        if let Ok(bus) = Bus::try_from_bytes(data_bytes) {
                            let rewards = (bus.rewards as f64) / 10f64.powf(TOKEN_DECIMALS as f64);
                            let theoretical_rewards = (bus.theoretical_rewards as f64) / 10f64.powf(TOKEN_DECIMALS as f64);
                            println!("Bus {}: {:} ORE [{:} ORE (theoretical)]", bus.id, rewards, theoretical_rewards);
                        }
                    }
                }
            }
            Err(err) => {
                eprintln!("Error: {}", err); 
            }
        }