Skip to content

Commit 9a1865d

Browse files
committed
simplify dynamic fee ux
1 parent 5c1d8eb commit 9a1865d

File tree

5 files changed

+106
-92
lines changed

5 files changed

+106
-92
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ spl-associated-token-account = { version = "^2.3", features = [
4646
"no-entrypoint",
4747
] }
4848
tokio = "1.35.1"
49+
url = "2.5"
4950

5051
# [patch.crates-io]
5152
# drillx = { path = "../drillx/drillx" }

src/dynamic_fee.rs

Lines changed: 86 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -3,89 +3,100 @@ use crate::Miner;
33
use ore_api::consts::BUS_ADDRESSES;
44
use reqwest::Client;
55
use serde_json::{json, Value};
6+
use url::Url;
7+
8+
enum FeeStrategy {
9+
Helius,
10+
Triton,
11+
}
612

713
impl Miner {
8-
pub async fn dynamic_fee(&self) -> u64 {
14+
pub async fn dynamic_fee(&self) -> Option<u64> {
15+
// Get url
16+
let rpc_url = self
17+
.dynamic_fee_url
18+
.clone()
19+
.unwrap_or(self.rpc_client.url());
20+
21+
// Select fee estiamte strategy
22+
let host = Url::parse(&rpc_url)
23+
.unwrap()
24+
.host_str()
25+
.unwrap()
26+
.to_string();
27+
let strategy = if host.contains("helius-rpc.com") {
28+
FeeStrategy::Helius
29+
} else if host.contains("rpcpool.com") {
30+
FeeStrategy::Triton
31+
} else {
32+
return None;
33+
};
34+
35+
// Build fee estimate request
36+
let client = Client::new();
937
let ore_addresses: Vec<String> = std::iter::once(ore_api::ID.to_string())
1038
.chain(BUS_ADDRESSES.iter().map(|pubkey| pubkey.to_string()))
1139
.collect();
40+
let body = match strategy {
41+
FeeStrategy::Helius => {
42+
json!({
43+
"jsonrpc": "2.0",
44+
"id": "priority-fee-estimate",
45+
"method": "getPriorityFeeEstimate",
46+
"params": [{
47+
"accountKeys": ore_addresses,
48+
"options": {
49+
"recommended": true
50+
}
51+
}]
52+
})
53+
}
54+
FeeStrategy::Triton => {
55+
json!({
56+
"jsonrpc": "2.0",
57+
"id": "priority-fee-estimate",
58+
"method": "getRecentPrioritizationFees",
59+
"params": [
60+
ore_addresses,
61+
{
62+
"percentile": 5000,
63+
}
64+
]
65+
})
66+
}
67+
};
1268

13-
match &self.dynamic_fee_strategy {
14-
None => self.priority_fee.unwrap_or(0),
15-
Some(strategy) => {
16-
let client = Client::new();
17-
let body = match strategy.as_str() {
18-
"helius" => {
19-
json!({
20-
"jsonrpc": "2.0",
21-
"id": "priority-fee-estimate",
22-
"method": "getPriorityFeeEstimate",
23-
"params": [{
24-
"accountKeys": ore_addresses,
25-
"options": {
26-
"recommended": true
27-
}
28-
}]
29-
})
30-
}
31-
"triton" => {
32-
json!({
33-
"jsonrpc": "2.0",
34-
"id": "priority-fee-estimate",
35-
"method": "getRecentPrioritizationFees",
36-
"params": [
37-
ore_addresses,
38-
{
39-
"percentile": 5000,
40-
}
41-
]
42-
})
43-
}
44-
_ => return self.priority_fee.unwrap_or(0),
45-
};
46-
47-
// Send request
48-
let url = self
49-
.dynamic_fee_url
50-
.clone()
51-
.unwrap_or(self.rpc_client.url());
52-
let response: Value = client
53-
.post(url)
54-
.json(&body)
55-
.send()
56-
.await
57-
.unwrap()
58-
.json()
59-
.await
60-
.unwrap();
69+
// Send request
70+
let response: Value = client
71+
.post(rpc_url)
72+
.json(&body)
73+
.send()
74+
.await
75+
.unwrap()
76+
.json()
77+
.await
78+
.unwrap();
6179

62-
// Parse fee
63-
let calculated_fee = match strategy.as_str() {
64-
"helius" => response["result"]["priorityFeeEstimate"]
65-
.as_f64()
66-
.map(|fee| fee as u64)
67-
.ok_or_else(|| {
68-
format!("Failed to parse priority fee. Response: {:?}", response)
69-
})
70-
.unwrap(),
71-
"triton" => response["result"]
72-
.as_array()
73-
.and_then(|arr| arr.last())
74-
.and_then(|last| last["prioritizationFee"].as_u64())
75-
.ok_or_else(|| {
76-
format!("Failed to parse priority fee. Response: {:?}", response)
77-
})
78-
.unwrap(),
79-
_ => return self.priority_fee.unwrap_or(0),
80-
};
80+
// Parse response
81+
let calculated_fee = match strategy {
82+
FeeStrategy::Helius => response["result"]["priorityFeeEstimate"]
83+
.as_f64()
84+
.map(|fee| fee as u64)
85+
.ok_or_else(|| format!("Failed to parse priority fee. Response: {:?}", response))
86+
.unwrap(),
87+
FeeStrategy::Triton => response["result"]
88+
.as_array()
89+
.and_then(|arr| arr.last())
90+
.and_then(|last| last["prioritizationFee"].as_u64())
91+
.ok_or_else(|| format!("Failed to parse priority fee. Response: {:?}", response))
92+
.unwrap(),
93+
};
8194

82-
// Check if the calculated fee is higher than max
83-
if let Some(max_fee) = self.priority_fee {
84-
calculated_fee.min(max_fee)
85-
} else {
86-
calculated_fee
87-
}
88-
}
95+
// Check if the calculated fee is higher than max
96+
if let Some(max_fee) = self.priority_fee {
97+
Some(calculated_fee.min(max_fee))
98+
} else {
99+
Some(calculated_fee)
89100
}
90101
}
91102
}

src/main.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct Miner {
3232
pub keypair_filepath: Option<String>,
3333
pub priority_fee: Option<u64>,
3434
pub dynamic_fee_url: Option<String>,
35-
pub dynamic_fee_strategy: Option<String>,
35+
pub dynamic_fee: bool,
3636
pub rpc_client: Arc<RpcClient>,
3737
pub fee_payer_filepath: Option<String>,
3838
}
@@ -100,23 +100,23 @@ struct Args {
100100
#[arg(
101101
long,
102102
value_name = "KEYPAIR_FILEPATH",
103-
help = "Filepath to keypair to use",
103+
help = "Filepath to keypair to use.",
104104
global = true
105105
)]
106106
keypair: Option<String>,
107107

108108
#[arg(
109109
long,
110110
value_name = "FEE_PAYER_FILEPATH",
111-
help = "Filepath to keypair to use as transaction fee payer",
111+
help = "Filepath to keypair to use as transaction fee payer.",
112112
global = true
113113
)]
114114
fee_payer: Option<String>,
115115

116116
#[arg(
117117
long,
118118
value_name = "MICROLAMPORTS",
119-
help = "Price to pay for compute unit. If dynamic fee url is also set, this value will be the max.",
119+
help = "Price to pay for compute units. If dynamic fees are being used, this value will be the max.",
120120
default_value = "500000",
121121
global = true
122122
)]
@@ -130,13 +130,8 @@ struct Args {
130130
)]
131131
dynamic_fee_url: Option<String>,
132132

133-
#[arg(
134-
long,
135-
value_name = "DYNAMIC_FEE_STRATEGY",
136-
help = "Strategy to use for dynamic fee estimation. Must be one of 'helius', or 'triton'.",
137-
global = true
138-
)]
139-
dynamic_fee_strategy: Option<String>,
133+
#[arg(long, help = "Use dynamic priority fees", global = true)]
134+
dynamic_fee: bool,
140135

141136
#[command(subcommand)]
142137
command: Commands,
@@ -169,7 +164,7 @@ async fn main() {
169164
args.priority_fee,
170165
Some(default_keypair),
171166
args.dynamic_fee_url,
172-
args.dynamic_fee_strategy,
167+
args.dynamic_fee,
173168
Some(fee_payer_filepath),
174169
));
175170

@@ -221,15 +216,15 @@ impl Miner {
221216
priority_fee: Option<u64>,
222217
keypair_filepath: Option<String>,
223218
dynamic_fee_url: Option<String>,
224-
dynamic_fee_strategy: Option<String>,
219+
dynamic_fee: bool,
225220
fee_payer_filepath: Option<String>,
226221
) -> Self {
227222
Self {
228223
rpc_client,
229224
keypair_filepath,
230225
priority_fee,
231226
dynamic_fee_url,
232-
dynamic_fee_strategy,
227+
dynamic_fee,
233228
fee_payer_filepath,
234229
}
235230
}

src/send_and_confirm.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,17 @@ impl Miner {
8888
// Sign tx with a new blockhash
8989
if attempts % 5 == 0 {
9090
// Reset the compute unit price
91-
if self.dynamic_fee_strategy.is_some() {
92-
let fee = self.dynamic_fee().await;
91+
if self.dynamic_fee {
92+
let fee = if let Some(fee) = self.dynamic_fee().await {
93+
progress_bar.println(format!(" Priority fee: {} microlamports", fee));
94+
fee
95+
} else {
96+
let fee = self.priority_fee.unwrap_or(0);
97+
progress_bar.println(format!(" {} Dynamic fees not supported by this RPC. Falling back to static value: {} microlamports", "WARNING".bold().yellow(), fee));
98+
fee
99+
};
93100
final_ixs.remove(1);
94101
final_ixs.insert(1, ComputeBudgetInstruction::set_compute_unit_price(fee));
95-
progress_bar.println(format!(" Priority fee: {} microlamports", fee));
96102
}
97103

98104
// Resign the tx

0 commit comments

Comments
 (0)