@@ -171,10 +171,35 @@ pub trait BootstrapTowardWallet {
171
171
}
172
172
173
173
/// Spend wallet receiver
174
- pub trait SpendWalletReceiver {
175
- fn coin_created ( & mut self , coin_id : & CoinString ) -> Result < ( ) , Error > ;
176
- fn coin_spent ( & mut self , coin_id : & CoinString ) -> Result < ( ) , Error > ;
177
- fn coin_timeout_reached ( & mut self , coin_id : & CoinString ) -> Result < ( ) , Error > ;
174
+ pub trait SpendWalletReceiver <
175
+ G : ToLocalUI + BootstrapTowardWallet + WalletSpendInterface + PacketSender ,
176
+ R : Rng ,
177
+ >
178
+ {
179
+ fn coin_created < ' a > (
180
+ & mut self ,
181
+ penv : & mut dyn PeerEnv < ' a , G , R > ,
182
+ coin_id : & CoinString ,
183
+ ) -> Result < ( ) , Error >
184
+ where
185
+ G : ' a ,
186
+ R : ' a ;
187
+ fn coin_spent < ' a > (
188
+ & mut self ,
189
+ penv : & mut dyn PeerEnv < ' a , G , R > ,
190
+ coin_id : & CoinString ,
191
+ ) -> Result < ( ) , Error >
192
+ where
193
+ G : ' a ,
194
+ R : ' a ;
195
+ fn coin_timeout_reached < ' a > (
196
+ & mut self ,
197
+ penv : & mut dyn PeerEnv < ' a , G , R > ,
198
+ coin_id : & CoinString ,
199
+ ) -> Result < ( ) , Error >
200
+ where
201
+ G : ' a ,
202
+ R : ' a ;
178
203
}
179
204
180
205
/// Unroll time wallet interface.
@@ -183,7 +208,7 @@ pub trait WalletSpendInterface {
183
208
fn spend_transaction_and_add_fee ( & mut self , bundle : & Spend ) -> Result < ( ) , Error > ;
184
209
/// Coin should report its lifecycle until it gets spent, then should be
185
210
/// de-registered.
186
- fn register_coin ( & mut self , coin_id : & CoinID , timeout : & Timeout ) -> Result < ( ) , Error > ;
211
+ fn register_coin ( & mut self , coin_id : & CoinString , timeout : & Timeout ) -> Result < ( ) , Error > ;
187
212
}
188
213
189
214
#[ derive( Clone , Debug , Serialize , Deserialize , Eq , PartialEq , PartialOrd , Ord ) ]
@@ -286,7 +311,7 @@ pub struct HandshakeStepInfo {
286
311
pub second_player_hs_info : HandshakeB ,
287
312
}
288
313
289
- #[ derive( Debug ) ]
314
+ #[ derive( Debug , Clone ) ]
290
315
pub struct HandshakeStepWithSpend {
291
316
#[ allow( dead_code) ]
292
317
pub info : HandshakeStepInfo ,
@@ -384,6 +409,9 @@ pub struct PotatoHandler {
384
409
their_contribution : Amount ,
385
410
386
411
reward_puzzle_hash : PuzzleHash ,
412
+
413
+ waiting_to_start : bool ,
414
+ channel_timeout : Timeout ,
387
415
}
388
416
389
417
fn init_game_id ( private_keys : & ChannelHandlerPrivateKeys ) -> Vec < u8 > {
@@ -424,6 +452,7 @@ impl PotatoHandler {
424
452
game_types : BTreeMap < GameType , Program > ,
425
453
my_contribution : Amount ,
426
454
their_contribution : Amount ,
455
+ channel_timeout : Timeout ,
427
456
reward_puzzle_hash : PuzzleHash ,
428
457
) -> PotatoHandler {
429
458
PotatoHandler {
@@ -449,9 +478,12 @@ impl PotatoHandler {
449
478
channel_initiation_transaction : None ,
450
479
channel_finished_transaction : None ,
451
480
481
+ waiting_to_start : true ,
482
+
452
483
private_keys,
453
484
my_contribution,
454
485
their_contribution,
486
+ channel_timeout,
455
487
reward_puzzle_hash,
456
488
}
457
489
}
@@ -633,6 +665,11 @@ impl PotatoHandler {
633
665
where
634
666
G : ToLocalUI + BootstrapTowardWallet + WalletSpendInterface + PacketSender + ' a ,
635
667
{
668
+ // Haven't got the channel coin yet.
669
+ if self . waiting_to_start {
670
+ return Ok ( ( ) ) ;
671
+ }
672
+
636
673
if let Some ( spend) = self . channel_finished_transaction . as_ref ( ) {
637
674
self . handshake_state = HandshakeState :: Finished ( Box :: new ( HandshakeStepWithSpend {
638
675
info : HandshakeStepInfo {
@@ -990,7 +1027,6 @@ impl PotatoHandler {
990
1027
} ;
991
1028
992
1029
let channel_coin = channel_handler. state_channel_coin ( ) ;
993
-
994
1030
let channel_puzzle_hash =
995
1031
if let Some ( ( _, puzzle_hash, _) ) = channel_coin. coin_string ( ) . to_parts ( ) {
996
1032
puzzle_hash
@@ -1005,6 +1041,8 @@ impl PotatoHandler {
1005
1041
{
1006
1042
let ( _env, system_interface) = penv. env ( ) ;
1007
1043
system_interface. channel_puzzle_hash ( & channel_puzzle_hash) ?;
1044
+ system_interface
1045
+ . register_coin ( channel_coin. coin_string ( ) , & self . channel_timeout ) ?;
1008
1046
} ;
1009
1047
1010
1048
let channel_public_key =
@@ -1125,8 +1163,25 @@ impl PotatoHandler {
1125
1163
) ) ) ;
1126
1164
} ;
1127
1165
1166
+ let channel_coin = {
1167
+ let ch = self . channel_handler ( ) ?;
1168
+ ch. state_channel_coin ( )
1169
+ } ;
1170
+
1171
+ debug ! ( "PH: channel_coin {:?}" , channel_coin. coin_string( ) ) ;
1172
+
1128
1173
{
1129
1174
let ( _env, system_interface) = penv. env ( ) ;
1175
+ if bundle. spends . is_empty ( ) {
1176
+ return Err ( Error :: StrErr (
1177
+ "No spends to draw the channel coin from" . to_string ( ) ,
1178
+ ) ) ;
1179
+ }
1180
+
1181
+ // Ensure we're watching for this coin.
1182
+ system_interface
1183
+ . register_coin ( channel_coin. coin_string ( ) , & self . channel_timeout ) ?;
1184
+
1130
1185
system_interface. received_channel_offer ( & bundle) ?;
1131
1186
}
1132
1187
@@ -1335,3 +1390,69 @@ impl<G: ToLocalUI + BootstrapTowardWallet + WalletSpendInterface + PacketSender,
1335
1390
Ok ( ( ) )
1336
1391
}
1337
1392
}
1393
+
1394
+ impl < G : ToLocalUI + BootstrapTowardWallet + WalletSpendInterface + PacketSender , R : Rng >
1395
+ SpendWalletReceiver < G , R > for PotatoHandler
1396
+ {
1397
+ fn coin_created < ' a > (
1398
+ & mut self ,
1399
+ penv : & mut dyn PeerEnv < ' a , G , R > ,
1400
+ coin : & CoinString ,
1401
+ ) -> Result < ( ) , Error >
1402
+ where
1403
+ G : ' a ,
1404
+ R : ' a ,
1405
+ {
1406
+ // When the channel coin is created, we know we can proceed in playing the game.
1407
+ if let HandshakeState :: PostStepF ( info) = & self . handshake_state {
1408
+ let channel_coin_created = self
1409
+ . channel_handler ( )
1410
+ . ok ( )
1411
+ . map ( |ch| ch. state_channel_coin ( ) . coin_string ( ) ) ;
1412
+
1413
+ debug ! ( "checking created coin {coin:?} vs expected {channel_coin_created:?}" ) ;
1414
+ if let Some ( _coin) = channel_coin_created {
1415
+ self . waiting_to_start = false ;
1416
+ self . try_complete_step_f (
1417
+ penv,
1418
+ info. first_player_hs_info . clone ( ) ,
1419
+ info. second_player_hs_info . clone ( ) ,
1420
+ ) ?;
1421
+ }
1422
+ }
1423
+
1424
+ Ok ( ( ) )
1425
+ }
1426
+
1427
+ fn coin_spent < ' a > (
1428
+ & mut self ,
1429
+ _penv : & mut dyn PeerEnv < ' a , G , R > ,
1430
+ coin_id : & CoinString ,
1431
+ ) -> Result < ( ) , Error >
1432
+ where
1433
+ G : ' a ,
1434
+ R : ' a ,
1435
+ {
1436
+ if let Some ( ch) = self . channel_handler . as_ref ( ) {
1437
+ let channel_coin = ch. state_channel_coin ( ) ;
1438
+ if coin_id == channel_coin. coin_string ( ) {
1439
+ // Channel coin was spent so we're going on chain.
1440
+ todo ! ( ) ;
1441
+ }
1442
+ }
1443
+
1444
+ Ok ( ( ) )
1445
+ }
1446
+
1447
+ fn coin_timeout_reached < ' a > (
1448
+ & mut self ,
1449
+ _penv : & mut dyn PeerEnv < ' a , G , R > ,
1450
+ _coin_id : & CoinString ,
1451
+ ) -> Result < ( ) , Error >
1452
+ where
1453
+ G : ' a ,
1454
+ R : ' a ,
1455
+ {
1456
+ todo ! ( ) ;
1457
+ }
1458
+ }
0 commit comments