35
35
P : Provider < Ethereum > + Clone ,
36
36
{
37
37
config : ChallengerConfig ,
38
+ challenger_address : Address ,
38
39
l2_provider : L2Provider ,
39
40
l1_provider_with_wallet : L1ProviderWithWallet < F , P > ,
40
41
factory : DisputeGameFactoryInstance < ( ) , L1ProviderWithWallet < F , P > > ,
@@ -48,13 +49,15 @@ where
48
49
{
49
50
/// Creates a new challenger instance with the provided L1 provider with wallet and factory contract instance.
50
51
pub async fn new (
52
+ challenger_address : Address ,
51
53
l1_provider_with_wallet : L1ProviderWithWallet < F , P > ,
52
54
factory : DisputeGameFactoryInstance < ( ) , L1ProviderWithWallet < F , P > > ,
53
55
) -> Result < Self > {
54
56
let config = ChallengerConfig :: from_env ( ) ?;
55
57
56
58
Ok ( Self {
57
59
config : config. clone ( ) ,
60
+ challenger_address,
58
61
l2_provider : ProviderBuilder :: default ( ) . on_http ( config. l2_rpc . clone ( ) ) ,
59
62
l1_provider_with_wallet : l1_provider_with_wallet. clone ( ) ,
60
63
factory : factory. clone ( ) ,
@@ -122,6 +125,58 @@ where
122
125
. await
123
126
}
124
127
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
+
125
180
/// Runs the challenger in an infinite loop, periodically checking for games to challenge and resolve.
126
181
async fn run ( & mut self ) -> Result < ( ) > {
127
182
tracing:: info!( "OP Succinct Challenger running..." ) ;
@@ -152,6 +207,17 @@ where
152
207
ChallengerGauge :: Errors . increment ( 1.0 ) ;
153
208
}
154
209
}
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
+ }
155
221
}
156
222
}
157
223
}
@@ -182,9 +248,13 @@ async fn main() -> Result<()> {
182
248
l1_provider_with_wallet. clone ( ) ,
183
249
) ;
184
250
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 ( ) ;
188
258
189
259
// Initialize challenger gauges.
190
260
ChallengerGauge :: register_all ( ) ;
0 commit comments