Skip to content

Commit 72c3ca7

Browse files
authored
feat: add handle_bond_claiming for fp challenger (#453)
1 parent 7db1acc commit 72c3ca7

File tree

4 files changed

+86
-3
lines changed

4 files changed

+86
-3
lines changed

book/fault_proofs/challenger.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ The challenger is configured through environment variables. Create a `.env.chall
4545
| `ENABLE_GAME_RESOLUTION` | Whether to enable automatic game resolution | `true` |
4646
| `MAX_GAMES_TO_CHECK_FOR_CHALLENGE` | Maximum number of games to scan for challenges | `100` |
4747
| `MAX_GAMES_TO_CHECK_FOR_RESOLUTION` | Maximum number of games to check for resolution | `100` |
48+
| `MAX_GAMES_TO_CHECK_FOR_BOND_CLAIMING` | Maximum number of games to check for bond claiming | `100` |
4849
| `CHALLENGER_METRICS_PORT` | The port to expose metrics on. Update prometheus.yml to use this port, if using docker compose. | `9001` |
4950

5051
```env
@@ -60,6 +61,7 @@ FETCH_INTERVAL=30 # Polling interval in seconds
6061
ENABLE_GAME_RESOLUTION=true # Whether to enable automatic game resolution
6162
MAX_GAMES_TO_CHECK_FOR_CHALLENGE=100 # Maximum number of games to scan for challenges
6263
MAX_GAMES_TO_CHECK_FOR_RESOLUTION=100 # Maximum number of games to check for resolution
64+
MAX_GAMES_TO_CHECK_FOR_BOND_CLAIMING=100 # Maximum number of games to check for bond claiming
6365
CHALLENGER_METRICS_PORT=9001 # The port to expose metrics on
6466
```
6567

fault-proof/bin/challenger.rs

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ where
3535
P: Provider<Ethereum> + Clone,
3636
{
3737
config: ChallengerConfig,
38+
challenger_address: Address,
3839
l2_provider: L2Provider,
3940
l1_provider_with_wallet: L1ProviderWithWallet<F, P>,
4041
factory: DisputeGameFactoryInstance<(), L1ProviderWithWallet<F, P>>,
@@ -48,13 +49,15 @@ where
4849
{
4950
/// Creates a new challenger instance with the provided L1 provider with wallet and factory contract instance.
5051
pub async fn new(
52+
challenger_address: Address,
5153
l1_provider_with_wallet: L1ProviderWithWallet<F, P>,
5254
factory: DisputeGameFactoryInstance<(), L1ProviderWithWallet<F, P>>,
5355
) -> Result<Self> {
5456
let config = ChallengerConfig::from_env()?;
5557

5658
Ok(Self {
5759
config: config.clone(),
60+
challenger_address,
5861
l2_provider: ProviderBuilder::default().on_http(config.l2_rpc.clone()),
5962
l1_provider_with_wallet: l1_provider_with_wallet.clone(),
6063
factory: factory.clone(),
@@ -122,6 +125,58 @@ where
122125
.await
123126
}
124127

128+
/// Handles claiming bonds from resolved games.
129+
pub async fn handle_bond_claiming(&self) -> Result<Action> {
130+
let _span = tracing::info_span!("[[Claiming Bonds]]").entered();
131+
132+
if let Some(game_address) = self
133+
.factory
134+
.get_oldest_claimable_bond_game_address(
135+
self.config.game_type,
136+
self.config.max_games_to_check_for_bond_claiming,
137+
self.challenger_address,
138+
)
139+
.await?
140+
{
141+
tracing::info!("Attempting to claim bond from game {:?}", game_address);
142+
143+
// Create a contract instance for the game
144+
let game =
145+
OPSuccinctFaultDisputeGame::new(game_address, self.l1_provider_with_wallet.clone());
146+
147+
// Create a transaction to claim credit
148+
let tx = game.claimCredit(self.challenger_address);
149+
150+
// Send the transaction
151+
match tx.send().await {
152+
Ok(pending_tx) => {
153+
let receipt = pending_tx
154+
.with_required_confirmations(NUM_CONFIRMATIONS)
155+
.with_timeout(Some(Duration::from_secs(TIMEOUT_SECONDS)))
156+
.get_receipt()
157+
.await?;
158+
159+
tracing::info!(
160+
"\x1b[1mSuccessfully claimed bond from game {:?} with tx {:?}\x1b[0m",
161+
game_address,
162+
receipt.transaction_hash
163+
);
164+
165+
Ok(Action::Performed)
166+
}
167+
Err(e) => Err(anyhow::anyhow!(
168+
"Failed to claim bond from game {:?}: {:?}",
169+
game_address,
170+
e
171+
)),
172+
}
173+
} else {
174+
tracing::info!("No new games to claim bonds from");
175+
176+
Ok(Action::Skipped)
177+
}
178+
}
179+
125180
/// Runs the challenger in an infinite loop, periodically checking for games to challenge and resolve.
126181
async fn run(&mut self) -> Result<()> {
127182
tracing::info!("OP Succinct Challenger running...");
@@ -152,6 +207,17 @@ where
152207
ChallengerGauge::Errors.increment(1.0);
153208
}
154209
}
210+
211+
match self.handle_bond_claiming().await {
212+
Ok(Action::Performed) => {
213+
ChallengerGauge::GamesBondsClaimed.increment(1.0);
214+
}
215+
Ok(Action::Skipped) => {}
216+
Err(e) => {
217+
tracing::warn!("Failed to handle bond claiming: {:?}", e);
218+
ChallengerGauge::Errors.increment(1.0);
219+
}
220+
}
155221
}
156222
}
157223
}
@@ -182,9 +248,13 @@ async fn main() -> Result<()> {
182248
l1_provider_with_wallet.clone(),
183249
);
184250

185-
let mut challenger = OPSuccinctChallenger::new(l1_provider_with_wallet, factory)
186-
.await
187-
.unwrap();
251+
let mut challenger = OPSuccinctChallenger::new(
252+
wallet.default_signer().address(),
253+
l1_provider_with_wallet,
254+
factory,
255+
)
256+
.await
257+
.unwrap();
188258

189259
// Initialize challenger gauges.
190260
ChallengerGauge::register_all();

fault-proof/src/config.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ pub struct ChallengerConfig {
119119
/// challenged up to `max_games_to_check_for_resolution` games behind the latest game.
120120
pub max_games_to_check_for_resolution: u64,
121121

122+
/// The maximum number of games to check for bond claiming.
123+
pub max_games_to_check_for_bond_claiming: u64,
124+
122125
/// The metrics port.
123126
pub metrics_port: u16,
124127
}
@@ -144,6 +147,9 @@ impl ChallengerConfig {
144147
max_games_to_check_for_resolution: env::var("MAX_GAMES_TO_CHECK_FOR_RESOLUTION")
145148
.unwrap_or("100".to_string())
146149
.parse()?,
150+
max_games_to_check_for_bond_claiming: env::var("MAX_GAMES_TO_CHECK_FOR_BOND_CLAIMING")
151+
.unwrap_or("100".to_string())
152+
.parse()?,
147153
metrics_port: env::var("CHALLENGER_METRICS_PORT")
148154
.unwrap_or("9001".to_string())
149155
.parse()?,

fault-proof/src/prometheus.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ pub enum ChallengerGauge {
6060
message = "Total number of games resolved by the challenger"
6161
)]
6262
GamesResolved,
63+
#[strum(
64+
serialize = "op_succinct_fp_challenger_games_bonds_claimed",
65+
message = "Total number of games that bonds were claimed by the challenger"
66+
)]
67+
GamesBondsClaimed,
6368
// Error metrics
6469
#[strum(
6570
serialize = "op_succinct_fp_challenger_errors",

0 commit comments

Comments
 (0)