diff --git a/Cargo.lock b/Cargo.lock index 58e1e37..12975f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -447,6 +447,12 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "atty" version = "0.2.14" @@ -497,6 +503,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -1707,6 +1719,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1886,7 +1913,26 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.11", + "indexmap 2.2.5", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", "indexmap 2.2.5", "slab", "tokio", @@ -2032,6 +2078,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -2039,7 +2096,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.11", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", "pin-project-lite", ] @@ -2071,9 +2151,9 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.22", + "http 0.2.11", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -2085,6 +2165,26 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.1", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -2092,13 +2192,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.11", + "hyper 0.14.28", "rustls", "tokio", "tokio-rustls", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.4.1", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.4.1", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.59" @@ -2507,7 +2643,7 @@ dependencies = [ [[package]] name = "more-cli" -version = "1.1.0" +version = "1.1.1" dependencies = [ "bincode", "bs58 0.5.1", @@ -2522,7 +2658,9 @@ dependencies = [ "ore-api", "ore-utils", "rand 0.8.5", + "reqwest 0.12.4", "rodio", + "serde_json", "solana-cli-config", "solana-client", "solana-program", @@ -2547,6 +2685,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "ndk" version = "0.8.0" @@ -2829,12 +2984,50 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl" +version = "0.10.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "ore-api" version = "2.1.0" @@ -2944,6 +3137,26 @@ dependencies = [ "num", ] +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -3320,10 +3533,10 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", + "h2 0.3.22", + "http 0.2.11", + "http-body 0.4.6", + "hyper 0.14.28", "hyper-rustls", "ipnet", "js-sys", @@ -3333,7 +3546,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", @@ -3347,7 +3560,49 @@ dependencies = [ "wasm-bindgen-futures", "web-sys", "webpki-roots 0.25.3", - "winreg", + "winreg 0.50.0", +] + +[[package]] +name = "reqwest" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.4.1", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 2.1.3", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.52.0", ] [[package]] @@ -3476,7 +3731,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "schannel", "security-framework", ] @@ -3490,6 +3745,22 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -4008,7 +4279,7 @@ dependencies = [ "gethostname", "lazy_static", "log", - "reqwest", + "reqwest 0.11.23", "solana-sdk", "thiserror", ] @@ -4156,7 +4427,7 @@ dependencies = [ "crossbeam-channel", "futures-util", "log", - "reqwest", + "reqwest 0.11.23", "semver", "serde", "serde_derive", @@ -4240,7 +4511,7 @@ dependencies = [ "bs58 0.4.0", "indicatif", "log", - "reqwest", + "reqwest 0.11.23", "semver", "serde", "serde_derive", @@ -4263,7 +4534,7 @@ dependencies = [ "base64 0.21.7", "bs58 0.4.0", "jsonrpc-core", - "reqwest", + "reqwest 0.11.23", "semver", "serde", "serde_derive", @@ -4919,6 +5190,12 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "synstructure" version = "0.12.6" @@ -5102,6 +5379,16 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.24.1" @@ -5189,6 +5476,27 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -5242,7 +5550,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.11", "httparse", "log", "rand 0.8.5", @@ -5363,6 +5671,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vec_map" version = "0.8.2" @@ -5807,6 +6121,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "x509-parser" version = "0.14.0" diff --git a/Cargo.toml b/Cargo.toml index d2fe39e..0532313 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "more-cli" -version = "1.1.0" +version = "1.1.1" edition = "2021" license = "Apache-2.0" description = "A command line interface for ORE cryptocurrency mining. Tailored by Miraland Labs." @@ -37,6 +37,7 @@ ore-utils = "2.1.0" # ore-api = { git = "https://github.com/regolith-labs/ore", rev = "ce9a701" } # ore-utils = { git = "https://github.com/regolith-labs/ore", rev = "ce9a701" } rand = "0.8.4" +reqwest = { version = "0.12", features = ["json"] } rodio = "0.18.1" solana-cli-config = "^1.18" solana-client = "^1.18" @@ -44,6 +45,7 @@ solana-program = "^1.18" solana-rpc-client = "^1.18" solana-sdk = "^1.18" solana-transaction-status = "^1.18" +serde_json = "1.0" spl-token = { version = "^4", features = ["no-entrypoint"] } spl-associated-token-account = { version = "^2.3", features = [ "no-entrypoint", diff --git a/src/dynamic_fee.rs b/src/dynamic_fee.rs new file mode 100644 index 0000000..e5c29b9 --- /dev/null +++ b/src/dynamic_fee.rs @@ -0,0 +1,87 @@ +use crate::Miner; + +use ore_api::consts::BUS_ADDRESSES; +use reqwest::Client; +use serde_json::{json, Value}; + +impl Miner { + pub async fn dynamic_fee(&self) -> u64 { + let ore_addresses: Vec = + std::iter::once("oreV2ZymfyeXgNgBdqMkumTqqAprVqgBWQfoYkrtKWQ".to_string()) + .chain(BUS_ADDRESSES.iter().map(|pubkey| pubkey.to_string())) + .collect(); + + match &self.dynamic_fee_strategy { + None => self.priority_fee.unwrap_or(0), + Some(strategy) => { + let client = Client::new(); + + let body = match strategy.as_str() { + "helius" => { + json!({ + "jsonrpc": "2.0", + "id": "priority-fee-estimate", + "method": "getPriorityFeeEstimate", + "params": [{ + "accountKeys": ore_addresses, + "options": { + "recommended": true + } + }] + }) + } + "triton" => { + json!({ + "jsonrpc": "2.0", + "id": "priority-fee-estimate", + "method": "getRecentPrioritizationFees", + "params": [ + ore_addresses, + { + "percentile": 5000, + } + ] + }) + } + _ => return self.priority_fee.unwrap_or(0), + }; + + let response: Value = client + .post(self.dynamic_fee_url.as_ref().unwrap()) + .json(&body) + .send() + .await + .unwrap() + .json() + .await + .unwrap(); + + let calculated_fee = match strategy.as_str() { + "helius" => response["result"]["priorityFeeEstimate"] + .as_f64() + .map(|fee| fee as u64) + .ok_or_else(|| { + format!("Failed to parse priority fee. Response: {:?}", response) + }) + .unwrap(), + "triton" => response["result"] + .as_array() + .and_then(|arr| arr.last()) + .and_then(|last| last["prioritizationFee"].as_u64()) + .ok_or_else(|| { + format!("Failed to parse priority fee. Response: {:?}", response) + }) + .unwrap(), + _ => return self.priority_fee.unwrap_or(0), + }; + + // Check if the calculated fee is higher than self.dynamic_fee_max + if let Some(max_fee) = self.dynamic_fee_max { + calculated_fee.min(max_fee) + } else { + calculated_fee + } + } + } + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 62bb952..eeb6062 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,7 @@ mod send_and_confirm; mod stake; mod upgrade; mod utils; +mod dynamic_fee; use std::sync::Arc; @@ -28,8 +29,12 @@ use solana_sdk::{ struct Miner { pub keypair_filepath: Option, - pub priority_fee: u64, + pub priority_fee: Option, + pub dynamic_fee_url: Option, + pub dynamic_fee_strategy: Option, + pub dynamic_fee_max: Option, pub rpc_client: Arc, + pub fee_payer_filepath: Option, pub no_sound_notification: bool, } @@ -98,6 +103,14 @@ struct Args { )] keypair: Option, + #[arg( + long, + value_name = "FEE_PAYER_FILEPATH", + help = "Filepath to keypair to use for fee payer", + global = true + )] + fee_payer_filepath: Option, + #[arg( long, value_name = "MICROLAMPORTS", @@ -105,8 +118,34 @@ struct Args { default_value = "0", global = true )] - priority_fee: u64, + priority_fee: Option, + #[arg( + long, + value_name = "DYNAMIC_FEE_URL", + help = "RPC URL to use for dynamic fee estimation. If set will enable dynamic fee pricing instead of static priority fee pricing.", + global = true + )] + dynamic_fee_url: Option, + + #[arg( + long, + value_name = "DYNAMIC_FEE_STRATEGY", + help = "Strategy to use for dynamic fee estimation. Must be one of 'helius', or 'triton'.", + default_value = "helius", + global = true + )] + dynamic_fee_strategy: Option, + + #[arg( + long, + value_name = "DYNAMIC_FEE_MAX", + help = "Maximum priority fee to use for dynamic fee estimation.", + default_value = "500000", + global = true + )] + dynamic_fee_max: Option, + /// Mine with sound notification on/off #[arg( long, @@ -139,13 +178,18 @@ async fn main() { // Initialize miner. let cluster = args.rpc.unwrap_or(cli_config.json_rpc_url); - let default_keypair = args.keypair.unwrap_or(cli_config.keypair_path); + let default_keypair = args.keypair.unwrap_or(cli_config.keypair_path.clone()); + let fee_payer_filepath = args.fee_payer_filepath.unwrap_or(cli_config.keypair_path.clone()); let rpc_client = RpcClient::new_with_commitment(cluster, CommitmentConfig::confirmed()); let miner = Arc::new(Miner::new( Arc::new(rpc_client), args.priority_fee, Some(default_keypair), + args.dynamic_fee_url, + args.dynamic_fee_strategy, + args.dynamic_fee_max, + Some(fee_payer_filepath), args.no_sound_notification, )); @@ -191,14 +235,22 @@ async fn main() { impl Miner { pub fn new( rpc_client: Arc, - priority_fee: u64, + priority_fee: Option, keypair_filepath: Option, + dynamic_fee_url: Option, + dynamic_fee_strategy: Option, + dynamic_fee_max: Option, + fee_payer_filepath: Option, no_sound_notification: bool, ) -> Self { Self { rpc_client, keypair_filepath, priority_fee, + dynamic_fee_url, + dynamic_fee_strategy, + dynamic_fee_max, + fee_payer_filepath, no_sound_notification, } } @@ -210,4 +262,12 @@ impl Miner { None => panic!("No keypair provided"), } } + + pub fn fee_payer(&self) -> Keypair { + match self.fee_payer_filepath.clone() { + Some(filepath) => read_keypair_file(filepath.clone()) + .expect(format!("No fee payer keypair found at {}", filepath).as_str()), + None => panic!("No fee payer keypair provided"), + } + } } diff --git a/src/mine.rs b/src/mine.rs index bde15ca..456ce1e 100644 --- a/src/mine.rs +++ b/src/mine.rs @@ -34,17 +34,18 @@ impl Miner { // Start mining loop loop { // Fetch proof + let config = get_config(&self.rpc_client).await; let proof = get_proof_with_authority(&self.rpc_client, signer.pubkey()).await; println!( - "\nStake balance: {} ORE", - amount_u64_to_string(proof.balance) + "\nStake: {} ORE\n Multiplier: {:12}x", + amount_u64_to_string(proof.balance), + calculate_multiplier(proof.balance, config.top_balance) ); // Calc cutoff time let cutoff_time = self.get_cutoff(proof, args.buffer_time).await; // Run drillx - let config = get_config(&self.rpc_client).await; let solution = Self::find_hash_par( proof, cutoff_time, @@ -123,7 +124,7 @@ impl Miner { // Exit if time has elapsed if nonce % 100 == 0 { if timer.elapsed().as_secs().ge(&cutoff_time) { - if best_difficulty.gt(&min_difficulty) { + if best_difficulty.ge(&min_difficulty) { // Mine until min difficulty has been met break; } @@ -203,6 +204,10 @@ impl Miner { } } +fn calculate_multiplier(balance: u64, top_balance: u64) -> f64 { + 1.0 + (balance as f64 / top_balance as f64).min(1.0f64) +} + // TODO Pick a better strategy (avoid draining bus) fn _find_bus() -> Pubkey { let i = rand::thread_rng().gen_range(0..BUS_COUNT); diff --git a/src/open.rs b/src/open.rs index 40c2345..640b9c9 100644 --- a/src/open.rs +++ b/src/open.rs @@ -6,6 +6,7 @@ impl Miner { pub async fn open(&self) { // Return early if miner is already registered let signer = self.signer(); + let fee_payer = self.fee_payer(); let proof_address = proof_pubkey(signer.pubkey()); if self.rpc_client.get_account(&proof_address).await.is_ok() { return; @@ -13,7 +14,7 @@ impl Miner { // Sign and send transaction. println!("Generating challenge..."); - let ix = ore_api::instruction::open(signer.pubkey(), signer.pubkey(), signer.pubkey()); + let ix = ore_api::instruction::open(signer.pubkey(), signer.pubkey(), fee_payer.pubkey()); self.send_and_confirm(&[ix], ComputeBudget::Dynamic, false) .await .ok(); diff --git a/src/send_and_confirm.rs b/src/send_and_confirm.rs index 8626118..7289f05 100644 --- a/src/send_and_confirm.rs +++ b/src/send_and_confirm.rs @@ -45,9 +45,10 @@ impl Miner { let progress_bar = spinner::new_progress_bar(); let signer = self.signer(); let client = self.rpc_client.clone(); + let fee_payer = self.fee_payer(); // Return error, if balance is zero - if let Ok(balance) = client.get_balance(&signer.pubkey()).await { + if let Ok(balance) = client.get_balance(&fee_payer.pubkey()).await { if balance <= sol_to_lamports(MIN_SOL_BALANCE) { panic!( "{} Insufficient balance: {} SOL\nPlease top up with at least {} SOL", @@ -69,9 +70,17 @@ impl Miner { final_ixs.push(ComputeBudgetInstruction::set_compute_unit_limit(cus)) } } - final_ixs.push(ComputeBudgetInstruction::set_compute_unit_price( - self.priority_fee, - )); + + let priority_fee = match &self.dynamic_fee_url { + Some(_) => { + self.dynamic_fee().await + } + None => { + self.priority_fee.unwrap_or(0) + } + }; + + final_ixs.push(ComputeBudgetInstruction::set_compute_unit_price(priority_fee)); final_ixs.extend_from_slice(ixs); // Build tx @@ -82,19 +91,31 @@ impl Miner { max_retries: Some(RPC_RETRIES), min_context_slot: None, }; - let mut tx = Transaction::new_with_payer(&final_ixs, Some(&signer.pubkey())); + let mut tx = Transaction::new_with_payer(&final_ixs, Some(&fee_payer.pubkey())); // Sign tx let (hash, _slot) = client .get_latest_blockhash_with_commitment(self.rpc_client.commitment()) .await .unwrap(); - tx.sign(&[&signer], hash); + + if signer.pubkey() == fee_payer.pubkey() { + tx.sign(&[&signer], hash); + } else { + tx.sign(&[&signer, &fee_payer], hash); + } // Submit tx let mut attempts = 0; loop { - progress_bar.set_message(format!("Submitting transaction... (attempt {})", attempts)); + + let message = match &self.dynamic_fee_url { + Some(_) => format!("Submitting transaction... (attempt {} with dynamic priority fee of {} via {})", attempts, priority_fee, self.dynamic_fee_strategy.as_ref().unwrap()), + None => format!("Submitting transaction... (attempt {} with static priority fee of {})", attempts, priority_fee), + }; + + progress_bar.set_message(message); + match client.send_transaction_with_config(&tx, send_cfg).await { Ok(sig) => { // Skip confirmation