Skip to content

Commit 5047654

Browse files
committed
move escalation policy
1 parent dc992b0 commit 5047654

File tree

5 files changed

+78
-44
lines changed

5 files changed

+78
-44
lines changed

apps/fortuna/src/config.rs

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use {
22
crate::{
33
api::ChainId,
44
chain::reader::{BlockNumber, BlockStatus},
5+
eth_utils::utils::EscalationPolicy,
56
},
67
anyhow::{anyhow, Result},
78
clap::{crate_authors, crate_description, crate_name, crate_version, Args, Parser},
@@ -259,39 +260,15 @@ impl Default for EscalationPolicyConfig {
259260
}
260261

261262
impl EscalationPolicyConfig {
262-
pub fn get_gas_multiplier_pct(&self, num_retries: u64) -> u64 {
263-
self.apply_escalation_policy(
264-
num_retries,
265-
self.initial_gas_multiplier_pct,
266-
self.gas_multiplier_pct,
267-
self.gas_multiplier_cap_pct,
268-
)
269-
}
270-
271-
pub fn get_fee_multiplier_pct(&self, num_retries: u64) -> u64 {
272-
self.apply_escalation_policy(
273-
num_retries,
274-
100,
275-
self.fee_multiplier_pct,
276-
self.fee_multiplier_cap_pct,
277-
)
278-
}
279-
280-
fn apply_escalation_policy(
281-
&self,
282-
num_retries: u64,
283-
initial: u64,
284-
multiplier: u64,
285-
cap: u64,
286-
) -> u64 {
287-
let mut current = initial;
288-
let mut i = 0;
289-
while i < num_retries && current < cap {
290-
current = current.saturating_mul(multiplier) / 100;
291-
i += 1;
263+
pub fn to_policy(&self) -> EscalationPolicy {
264+
EscalationPolicy {
265+
gas_limit_tolerance_pct: self.gas_limit_tolerance_pct,
266+
initial_gas_multiplier_pct: self.initial_gas_multiplier_pct,
267+
gas_multiplier_pct: self.gas_multiplier_pct,
268+
gas_multiplier_cap_pct: self.gas_multiplier_cap_pct,
269+
fee_multiplier_pct: self.fee_multiplier_pct,
270+
fee_multiplier_cap_pct: self.fee_multiplier_cap_pct,
292271
}
293-
294-
current.min(cap)
295272
}
296273
}
297274

apps/fortuna/src/eth_utils/utils.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use {
2-
crate::config::EscalationPolicyConfig,
32
crate::eth_utils::nonce_manager::NonceManaged,
43
anyhow::{anyhow, Result},
54
backoff::ExponentialBackoff,
@@ -22,6 +21,65 @@ pub struct SubmitTxResult {
2221
pub receipt: Result<TransactionReceipt, anyhow::Error>,
2322
}
2423

24+
#[derive(Clone, Debug)]
25+
pub struct EscalationPolicy {
26+
// The keeper will perform the callback as long as the tx is within this percentage of the configured gas limit.
27+
// Default value is 110, meaning a 10% tolerance over the configured value.
28+
pub gas_limit_tolerance_pct: u64,
29+
30+
/// The initial gas multiplier to apply to the tx gas estimate
31+
pub initial_gas_multiplier_pct: u64,
32+
33+
/// The gas multiplier to apply to the tx gas estimate during backoff retries.
34+
/// The gas on each successive retry is multiplied by this value, with the maximum multiplier capped at `gas_multiplier_cap_pct`.
35+
pub gas_multiplier_pct: u64,
36+
/// The maximum gas multiplier to apply to the tx gas estimate during backoff retries.
37+
pub gas_multiplier_cap_pct: u64,
38+
39+
/// The fee multiplier to apply to the fee during backoff retries.
40+
/// The initial fee is 100% of the estimate (which itself may be padded based on our chain configuration)
41+
/// The fee on each successive retry is multiplied by this value, with the maximum multiplier capped at `fee_multiplier_cap_pct`.
42+
pub fee_multiplier_pct: u64,
43+
pub fee_multiplier_cap_pct: u64,
44+
}
45+
46+
impl EscalationPolicy {
47+
pub fn get_gas_multiplier_pct(&self, num_retries: u64) -> u64 {
48+
self.apply_escalation_policy(
49+
num_retries,
50+
self.initial_gas_multiplier_pct,
51+
self.gas_multiplier_pct,
52+
self.gas_multiplier_cap_pct,
53+
)
54+
}
55+
56+
pub fn get_fee_multiplier_pct(&self, num_retries: u64) -> u64 {
57+
self.apply_escalation_policy(
58+
num_retries,
59+
100,
60+
self.fee_multiplier_pct,
61+
self.fee_multiplier_cap_pct,
62+
)
63+
}
64+
65+
fn apply_escalation_policy(
66+
&self,
67+
num_retries: u64,
68+
initial: u64,
69+
multiplier: u64,
70+
cap: u64,
71+
) -> u64 {
72+
let mut current = initial;
73+
let mut i = 0;
74+
while i < num_retries && current < cap {
75+
current = current.saturating_mul(multiplier) / 100;
76+
i += 1;
77+
}
78+
79+
current.min(cap)
80+
}
81+
}
82+
2583
pub async fn send_and_confirm<A: Middleware>(contract_call: ContractCall<A, ()>) -> Result<()> {
2684
let call_name = contract_call.function.name.as_str();
2785
let pending_tx = contract_call
@@ -86,7 +144,7 @@ pub async fn submit_tx_with_backoff<T: Middleware + NonceManaged + 'static>(
86144
middleware: Arc<T>,
87145
call: ContractCall<T, ()>,
88146
gas_limit: U256,
89-
escalation_policy: EscalationPolicyConfig,
147+
escalation_policy: EscalationPolicy,
90148
) -> Result<SubmitTxResult> {
91149
let start_time = std::time::Instant::now();
92150

apps/fortuna/src/keeper.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ pub async fn run_keeper_threads(
8989
},
9090
contract.clone(),
9191
gas_limit,
92-
chain_eth_config.escalation_policy.clone(),
92+
chain_eth_config.escalation_policy.to_policy(),
9393
chain_state.clone(),
9494
metrics.clone(),
9595
fulfilled_requests_cache.clone(),
@@ -116,7 +116,7 @@ pub async fn run_keeper_threads(
116116
rx,
117117
Arc::clone(&contract),
118118
gas_limit,
119-
chain_eth_config.escalation_policy.clone(),
119+
chain_eth_config.escalation_policy.to_policy(),
120120
metrics.clone(),
121121
fulfilled_requests_cache.clone(),
122122
chain_eth_config.block_delays.clone(),

apps/fortuna/src/keeper/block.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use {
22
crate::{
33
api::{self, BlockchainState},
44
chain::{ethereum::InstrumentedSignablePythContract, reader::BlockNumber},
5-
config::EscalationPolicyConfig,
5+
eth_utils::utils::EscalationPolicy,
66
keeper::keeper_metrics::KeeperMetrics,
77
keeper::process_event::process_event_with_backoff,
88
},
@@ -67,7 +67,7 @@ pub async fn process_block_range(
6767
block_range: BlockRange,
6868
contract: Arc<InstrumentedSignablePythContract>,
6969
gas_limit: U256,
70-
escalation_policy: EscalationPolicyConfig,
70+
escalation_policy: EscalationPolicy,
7171
chain_state: api::BlockchainState,
7272
metrics: Arc<KeeperMetrics>,
7373
fulfilled_requests_cache: Arc<RwLock<HashSet<u64>>>,
@@ -114,7 +114,7 @@ pub async fn process_single_block_batch(
114114
block_range: BlockRange,
115115
contract: Arc<InstrumentedSignablePythContract>,
116116
gas_limit: U256,
117-
escalation_policy: EscalationPolicyConfig,
117+
escalation_policy: EscalationPolicy,
118118
chain_state: api::BlockchainState,
119119
metrics: Arc<KeeperMetrics>,
120120
fulfilled_requests_cache: Arc<RwLock<HashSet<u64>>>,
@@ -290,7 +290,7 @@ pub async fn process_new_blocks(
290290
mut rx: mpsc::Receiver<BlockRange>,
291291
contract: Arc<InstrumentedSignablePythContract>,
292292
gas_limit: U256,
293-
escalation_policy: EscalationPolicyConfig,
293+
escalation_policy: EscalationPolicy,
294294
metrics: Arc<KeeperMetrics>,
295295
fulfilled_requests_cache: Arc<RwLock<HashSet<u64>>>,
296296
block_delays: Vec<u64>,
@@ -339,7 +339,7 @@ pub async fn process_backlog(
339339
backlog_range: BlockRange,
340340
contract: Arc<InstrumentedSignablePythContract>,
341341
gas_limit: U256,
342-
escalation_policy: EscalationPolicyConfig,
342+
escalation_policy: EscalationPolicy,
343343
chain_state: BlockchainState,
344344
metrics: Arc<KeeperMetrics>,
345345
fulfilled_requests_cache: Arc<RwLock<HashSet<u64>>>,

apps/fortuna/src/keeper/process_event.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ use {
33
crate::{
44
api::BlockchainState,
55
chain::{ethereum::InstrumentedSignablePythContract, reader::RequestedWithCallbackEvent},
6-
config::EscalationPolicyConfig,
7-
eth_utils::utils::submit_tx_with_backoff,
6+
eth_utils::utils::{submit_tx_with_backoff, EscalationPolicy},
87
},
98
anyhow::{anyhow, Result},
109
ethers::types::U256,
@@ -21,7 +20,7 @@ pub async fn process_event_with_backoff(
2120
chain_state: BlockchainState,
2221
contract: Arc<InstrumentedSignablePythContract>,
2322
gas_limit: U256,
24-
escalation_policy: EscalationPolicyConfig,
23+
escalation_policy: EscalationPolicy,
2524
metrics: Arc<KeeperMetrics>,
2625
) -> Result<()> {
2726
// ignore requests that are not for the configured provider

0 commit comments

Comments
 (0)