Skip to content

Commit 845cccf

Browse files
committed
make this sane
1 parent 1895c05 commit 845cccf

File tree

7 files changed

+71
-45
lines changed

7 files changed

+71
-45
lines changed

apps/fortuna/Cargo.lock

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

apps/fortuna/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "fortuna"
3-
version = "6.8.1"
3+
version = "7.0.0"
44
edition = "2021"
55

66
[dependencies]

apps/fortuna/config.sample.yaml

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,32 @@ chains:
66
# Keeper configuration for the chain
77
reveal_delay_blocks: 0
88
gas_limit: 500000
9-
# Increase the transaction gas limit by 10% each time the callback fails
10-
# defaults to 100 (i.e., don't change the gas limit) if not specified.
11-
backoff_gas_multiplier_pct: 110
12-
# Maximum percentage that the gas limit can be multiplied by during backoff retries
13-
# defaults to 500 (i.e., up to 5x the original gas limit) if not specified.
14-
backoff_gas_multiplier_cap_pct: 500
9+
10+
# Multiplier for the priority fee estimate, as a percentage (i.e., 100 = no change).
11+
# Defaults to 100 if the field is omitted.
12+
priority_fee_multiplier_pct: 100
13+
14+
escalation_policy:
15+
# Pad the first callback transaction's gas estimate by 25%,
16+
# then multiply each successive callback transaction's gas estimate by 10% until the cap is reached.
17+
# All numbers are expressed as percentages where 100 = no change.
18+
initial_gas_multiplier_pct: 125
19+
gas_multiplier_pct: 110
20+
gas_multiplier_cap_pct: 600
21+
22+
# Multiply successive callback transaction's fees by 10% until the cap is reached.
23+
# All numbers are expressed as percentages where 100 = no change.
24+
# (See also priority_fee_multiplier_pct above to generically adjust the priority fee estimates for the chain --
25+
# adjusting that parameter will influence the fee of the first transaction, in addition to other things)
26+
fee_multiplier_pct: 110
27+
fee_multiplier_cap_pct: 200
28+
1529
min_keeper_balance: 100000000000000000
1630

1731
# Provider configuration
1832
# How much to charge in fees
1933
fee: 1500000000000000
2034

21-
# Multiplier for the priority fee estimate, as a percentage (i.e., 100 = no change).
22-
# Defaults to 100 if the field is omitted.
23-
priority_fee_multiplier_pct: 100
24-
2535
# Configuration for dynamic fees under high gas prices. The keeper will set
2636
# on-chain fees to make between [min_profit_pct, max_profit_pct] of the max callback
2737
# cost in profit per transaction.

apps/fortuna/src/api.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ mod test {
224224
contract: avax_read.clone(),
225225
provider_address: PROVIDER,
226226
reveal_delay_blocks: 2,
227-
confirmed_block_status: BlockStatus::Latest
227+
confirmed_block_status: BlockStatus::Latest,
228228
};
229229

230230
let mut chains = HashMap::new();

apps/fortuna/src/command/run.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ async fn setup_chain_state(
295295
contract,
296296
provider_address: *provider,
297297
reveal_delay_blocks: chain_config.reveal_delay_blocks,
298-
confirmed_block_status: chain_config.confirmed_block_status
298+
confirmed_block_status: chain_config.confirmed_block_status,
299299
};
300300
Ok(state)
301301
}

apps/fortuna/src/config.rs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ pub struct EthereumConfig {
134134
/// The gas limit to use for entropy callback transactions.
135135
pub gas_limit: u64,
136136

137+
/// The percentage multiplier to apply to priority fee estimates (100 = no change, e.g. 150 = 150% of base fee)
138+
#[serde(default = "default_priority_fee_multiplier_pct")]
139+
pub priority_fee_multiplier_pct: u64,
140+
137141
/// The escalation policy governs how the gas limit and fee are increased during backoff retries.
138142
pub escalation_policy: EscalationPolicyConfig,
139143

@@ -171,6 +175,10 @@ pub struct EthereumConfig {
171175
pub max_num_hashes: Option<u32>,
172176
}
173177

178+
fn default_priority_fee_multiplier_pct() -> u64 {
179+
100
180+
}
181+
174182
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
175183
pub struct EscalationPolicyConfig {
176184
/// The initial gas multiplier to apply to the gas limit.
@@ -185,11 +193,8 @@ pub struct EscalationPolicyConfig {
185193
#[serde(default = "default_gas_multiplier_cap_pct")]
186194
pub gas_multiplier_cap_pct: u64,
187195

188-
/// The initial fee multiplier to apply to the fee.
189-
#[serde(default = "default_initial_fee_multiplier_pct")]
190-
pub initial_fee_multiplier_pct: u64,
191-
192196
/// The fee multiplier to apply to the fee during backoff retries.
197+
/// The initial fee is 100% of the estimate (which itself may be padded based on our chain configuration)
193198
/// The fee on each successive retry is multiplied by this value, with the maximum multiplier capped at `fee_multiplier_cap_pct`.
194199
#[serde(default = "default_fee_multiplier_pct")]
195200
pub fee_multiplier_pct: u64,
@@ -199,14 +204,30 @@ pub struct EscalationPolicyConfig {
199204

200205
impl EscalationPolicyConfig {
201206
pub fn get_gas_multiplier_pct(&self, num_retries: u64) -> u64 {
202-
self.apply_escalation_policy(num_retries, self.initial_gas_multiplier_pct, self.gas_multiplier_pct, self.gas_multiplier_cap_pct)
207+
self.apply_escalation_policy(
208+
num_retries,
209+
self.initial_gas_multiplier_pct,
210+
self.gas_multiplier_pct,
211+
self.gas_multiplier_cap_pct,
212+
)
203213
}
204214

205215
pub fn get_fee_multiplier_pct(&self, num_retries: u64) -> u64 {
206-
self.apply_escalation_policy(num_retries, self.initial_fee_multiplier_pct, self.fee_multiplier_pct, self.fee_multiplier_cap_pct)
216+
self.apply_escalation_policy(
217+
num_retries,
218+
100,
219+
self.fee_multiplier_pct,
220+
self.fee_multiplier_cap_pct,
221+
)
207222
}
208223

209-
fn apply_escalation_policy(&self, num_retries: u64, initial: u64, multiplier: u64, cap: u64) -> u64 {
224+
fn apply_escalation_policy(
225+
&self,
226+
num_retries: u64,
227+
initial: u64,
228+
multiplier: u64,
229+
cap: u64,
230+
) -> u64 {
210231
let mut current = initial;
211232
let mut i = 0;
212233
while i < num_retries && current < cap {
@@ -223,15 +244,11 @@ fn default_initial_gas_multiplier_pct() -> u64 {
223244
}
224245

225246
fn default_gas_multiplier_pct() -> u64 {
226-
100
247+
110
227248
}
228249

229250
fn default_gas_multiplier_cap_pct() -> u64 {
230-
500
231-
}
232-
233-
fn default_initial_fee_multiplier_pct() -> u64 {
234-
100
251+
600
235252
}
236253

237254
fn default_fee_multiplier_pct() -> u64 {
@@ -289,10 +306,6 @@ fn default_chain_sample_interval() -> u64 {
289306
1
290307
}
291308

292-
fn default_priority_fee_multiplier_pct() -> u64 {
293-
100
294-
}
295-
296309
/// Configuration values for the keeper service that are shared across chains.
297310
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
298311
pub struct KeeperConfig {

apps/fortuna/src/keeper.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use {
88
reader::{BlockNumber, RequestedWithCallbackEvent},
99
traced_client::{RpcMetrics, TracedClient},
1010
},
11-
config::EthereumConfig,
1211
config::EscalationPolicyConfig,
12+
config::EthereumConfig,
1313
},
1414
anyhow::{anyhow, Result},
1515
backoff::ExponentialBackoff,
@@ -56,8 +56,6 @@ const UPDATE_COMMITMENTS_INTERVAL: Duration = Duration::from_secs(30);
5656
const UPDATE_COMMITMENTS_THRESHOLD_FACTOR: f64 = 0.95;
5757
/// Rety last N blocks
5858
const RETRY_PREVIOUS_BLOCKS: u64 = 100;
59-
/// By default, we scale the gas estimate by 25% when submitting the tx.
60-
const DEFAULT_GAS_ESTIMATE_MULTIPLIER_PCT: u64 = 125;
6159

6260
#[derive(Clone, Debug, Hash, PartialEq, Eq, EncodeLabelSet)]
6361
pub struct AccountLabel {
@@ -273,7 +271,7 @@ pub async fn run_keeper_threads(
273271
},
274272
contract.clone(),
275273
gas_limit,
276-
chain_eth_config.escalation_policy,
274+
chain_eth_config.escalation_policy.clone(),
277275
chain_state.clone(),
278276
metrics.clone(),
279277
fulfilled_requests_cache.clone(),
@@ -299,7 +297,7 @@ pub async fn run_keeper_threads(
299297
rx,
300298
Arc::clone(&contract),
301299
gas_limit,
302-
chain_eth_config.escalation_policy,
300+
chain_eth_config.escalation_policy.clone(),
303301
metrics.clone(),
304302
fulfilled_requests_cache.clone(),
305303
)
@@ -328,8 +326,8 @@ pub async fn run_keeper_threads(
328326
// However, the keeper will pad the gas limit for transactions (per the escalation policy) to ensure reliable submission.
329327
// Consequently, fees can be adjusted such that transactions are still unprofitable.
330328
// While we could scale up this value based on the padding, that ends up overcharging users as most transactions cost nowhere
331-
// near the maximum gas limit.
332-
// In the unlikely event that the keeper fees aren't sufficient, the solution to this is to configure the target
329+
// near the maximum gas limit.
330+
// In the unlikely event that the keeper fees aren't sufficient, the solution to this is to configure the target
333331
// fee percentage to be higher on that specific chain.
334332
chain_eth_config.gas_limit,
335333
chain_eth_config.min_profit_pct,
@@ -549,7 +547,6 @@ pub async fn process_event(
549547
// the padded gas estimate doesn't exceed the maximum amount of gas we are willing to use.
550548
let gas_estimate = gas_estimate.saturating_mul(gas_estimate_multiplier_pct.into()) / 100;
551549

552-
553550
let contract_call = contract
554551
.reveal_with_callback(
555552
event.provider_address,
@@ -572,7 +569,13 @@ pub async fn process_event(
572569

573570
// Apply the fee escalation policy. Note: the unwrap_or_default should never default as we have a gas oracle
574571
// in the client that sets the gas price.
575-
transaction.set_gas_price(transaction.gas_price().unwrap_or_default().saturating_mul(fee_estimate_multiplier_pct.into()) / 100);
572+
transaction.set_gas_price(
573+
transaction
574+
.gas_price()
575+
.unwrap_or_default()
576+
.saturating_mul(fee_estimate_multiplier_pct.into())
577+
/ 100,
578+
);
576579

577580
let pending_tx = client
578581
.send_transaction(transaction.clone(), None)
@@ -668,7 +671,7 @@ pub async fn process_block_range(
668671
block_range: BlockRange,
669672
contract: Arc<InstrumentedSignablePythContract>,
670673
gas_limit: U256,
671-
backoff_gas_multiplier_pct: u64,
674+
escalation_policy: EscalationPolicyConfig,
672675
chain_state: api::BlockchainState,
673676
metrics: Arc<KeeperMetrics>,
674677
fulfilled_requests_cache: Arc<RwLock<HashSet<u64>>>,
@@ -692,7 +695,7 @@ pub async fn process_block_range(
692695
},
693696
contract.clone(),
694697
gas_limit,
695-
backoff_gas_multiplier_pct,
698+
escalation_policy.clone(),
696699
chain_state.clone(),
697700
metrics.clone(),
698701
fulfilled_requests_cache.clone(),
@@ -715,7 +718,7 @@ pub async fn process_single_block_batch(
715718
block_range: BlockRange,
716719
contract: Arc<InstrumentedSignablePythContract>,
717720
gas_limit: U256,
718-
backoff_gas_multiplier_pct: u64,
721+
escalation_policy: EscalationPolicyConfig,
719722
chain_state: api::BlockchainState,
720723
metrics: Arc<KeeperMetrics>,
721724
fulfilled_requests_cache: Arc<RwLock<HashSet<u64>>>,
@@ -742,7 +745,7 @@ pub async fn process_single_block_batch(
742745
chain_state.clone(),
743746
contract.clone(),
744747
gas_limit,
745-
backoff_gas_multiplier_pct,
748+
escalation_policy.clone(),
746749
metrics.clone(),
747750
)
748751
.in_current_span(),
@@ -900,7 +903,7 @@ pub async fn process_new_blocks(
900903
block_range,
901904
Arc::clone(&contract),
902905
gas_limit,
903-
escalation_policy,
906+
escalation_policy.clone(),
904907
chain_state.clone(),
905908
metrics.clone(),
906909
fulfilled_requests_cache.clone(),

0 commit comments

Comments
 (0)