diff --git a/src/channel_handler/mod.rs b/src/channel_handler/mod.rs index 6803fcd..4ce5640 100644 --- a/src/channel_handler/mod.rs +++ b/src/channel_handler/mod.rs @@ -91,6 +91,7 @@ pub struct ChannelHandler { have_potato: bool, initiated_on_chain: bool, // Specifies the time lock that should be used in the unroll coin's conditions. + #[allow(dead_code)] unroll_advance_timeout: Timeout, cached_last_action: Option, @@ -1165,7 +1166,7 @@ impl ChannelHandler { )); } - self.get_create_unroll_coin_transaction(env, &full_coin, true) + self.get_create_unroll_coin_transaction(env, full_coin, true) } } } diff --git a/src/common/types.rs b/src/common/types.rs index 5eb9196..1cd292c 100644 --- a/src/common/types.rs +++ b/src/common/types.rs @@ -1070,16 +1070,16 @@ pub fn divmod(a: BigInt, b: BigInt) -> (BigInt, BigInt) { #[test] fn test_local_divmod() { assert_eq!( - divmod(-7.to_bigint().unwrap(), 2.to_bigint().unwrap()), - (-4.to_bigint().unwrap(), 1.to_bigint().unwrap()) + divmod((-7).to_bigint().unwrap(), 2.to_bigint().unwrap()), + ((-4).to_bigint().unwrap(), 1.to_bigint().unwrap()) ); assert_eq!( - divmod(7.to_bigint().unwrap(), -2.to_bigint().unwrap()), - (-4.to_bigint().unwrap(), -1.to_bigint().unwrap()) + divmod(7.to_bigint().unwrap(), (-2).to_bigint().unwrap()), + ((-4).to_bigint().unwrap(), (-1).to_bigint().unwrap()) ); assert_eq!( - divmod(-7.to_bigint().unwrap(), -2.to_bigint().unwrap()), - (3.to_bigint().unwrap(), -1.to_bigint().unwrap()) + divmod((-7).to_bigint().unwrap(), (-2).to_bigint().unwrap()), + (3.to_bigint().unwrap(), (-1).to_bigint().unwrap()) ); assert_eq!( divmod(7.to_bigint().unwrap(), 2.to_bigint().unwrap()), diff --git a/src/peer_container.rs b/src/peer_container.rs index 36b63ed..dfac054 100644 --- a/src/peer_container.rs +++ b/src/peer_container.rs @@ -19,7 +19,8 @@ use crate::common::types::{ }; use crate::potato_handler::{ BootstrapTowardGame, BootstrapTowardWallet, FromLocalUI, GameStart, GameType, PacketSender, - PeerEnv, PeerMessage, PotatoHandler, SpendWalletReceiver, ToLocalUI, WalletSpendInterface, + PeerEnv, PeerMessage, PotatoHandler, PotatoHandlerInit, SpendWalletReceiver, ToLocalUI, + WalletSpendInterface, }; #[derive(Default)] @@ -352,16 +353,16 @@ impl SynchronousGameCradle { shutdown: None, on_chain_game_coins: Vec::default(), }, - peer: PotatoHandler::new( - config.have_potato, + peer: PotatoHandler::new(PotatoHandlerInit { + have_potato: config.have_potato, private_keys, - config.game_types, - config.my_contribution, - config.their_contribution, - config.channel_timeout, - config.unroll_timeout, - config.reward_puzzle_hash, - ), + game_types: config.game_types, + my_contribution: config.my_contribution, + their_contribution: config.their_contribution, + channel_timeout: config.channel_timeout, + unroll_timeout: config.unroll_timeout, + reward_puzzle_hash: config.reward_puzzle_hash, + }), } } } @@ -655,7 +656,7 @@ impl SynchronousGameCradle { // Get timeouts let mut timed_out = HashSet::new(); for (k, w) in self.state.watching_coins.iter_mut() { - if let Some(t) = w.timeout_at.clone() { + if let Some(t) = w.timeout_at { if t <= block { debug!("filter: timeout on coin: {w:?}"); w.timeout_at = None; diff --git a/src/potato_handler.rs b/src/potato_handler.rs index ee339e0..8f1c06a 100644 --- a/src/potato_handler.rs +++ b/src/potato_handler.rs @@ -14,17 +14,17 @@ use serde::{Deserialize, Serialize}; use crate::channel_handler::game_handler::chia_dialect; use crate::channel_handler::types::{ ChannelCoinSpendInfo, ChannelHandlerEnv, ChannelHandlerInitiationData, - ChannelHandlerPrivateKeys, FlatGameStartInfo, GameStartInfo, MoveResult, OnChainGameCoin, - PotatoSignatures, PrintableGameStartInfo, ReadableMove, + ChannelHandlerPrivateKeys, FlatGameStartInfo, GameStartInfo, MoveResult, PotatoSignatures, + PrintableGameStartInfo, ReadableMove, }; use crate::channel_handler::ChannelHandler; use crate::common::standard_coin::{ private_to_public_key, puzzle_for_synthetic_public_key, puzzle_hash_for_pk, }; use crate::common::types::{ - usize_from_atom, Aggsig, AllocEncoder, Amount, CoinCondition, CoinID, CoinSpend, CoinString, - Error, GameID, Hash, IntoErr, Node, Program, PublicKey, Puzzle, PuzzleHash, Sha256Input, - Sha256tree, Spend, SpendBundle, Timeout, + Aggsig, AllocEncoder, Amount, CoinCondition, CoinID, CoinSpend, CoinString, Error, GameID, + Hash, IntoErr, Node, Program, PublicKey, Puzzle, PuzzleHash, Sha256Input, Sha256tree, Spend, + SpendBundle, Timeout, }; use clvm_tools_rs::classic::clvm::sexp::proper_list; @@ -426,6 +426,17 @@ enum GameAction { Shutdown(NodePtr), } +pub struct PotatoHandlerInit { + pub have_potato: bool, + pub private_keys: ChannelHandlerPrivateKeys, + pub game_types: BTreeMap, + pub my_contribution: Amount, + pub their_contribution: Amount, + pub channel_timeout: Timeout, + pub unroll_timeout: Timeout, + pub reward_puzzle_hash: PuzzleHash, +} + /// Handle potato in flight when I request potato: /// /// Every time i send the potato, if i have stuff i want to do, then i also send @@ -522,31 +533,22 @@ fn init_game_id(private_keys: &ChannelHandlerPrivateKeys) -> Vec { /// /// once this object knows the channel puzzle hash they should register the coin. impl PotatoHandler { - pub fn new( - have_potato: bool, - private_keys: ChannelHandlerPrivateKeys, - game_types: BTreeMap, - my_contribution: Amount, - their_contribution: Amount, - channel_timeout: Timeout, - unroll_timeout: Timeout, - reward_puzzle_hash: PuzzleHash, - ) -> PotatoHandler { + pub fn new(phi: PotatoHandlerInit) -> PotatoHandler { PotatoHandler { - initiator: have_potato, - have_potato: if have_potato { + initiator: phi.have_potato, + have_potato: if phi.have_potato { PotatoState::Present } else { PotatoState::Absent }, - handshake_state: if have_potato { + handshake_state: if phi.have_potato { HandshakeState::StepA } else { HandshakeState::StepB }, next_game_id: Vec::new(), - game_types, + game_types: phi.game_types, their_start_queue: VecDeque::default(), my_start_queue: VecDeque::default(), @@ -558,12 +560,12 @@ impl PotatoHandler { waiting_to_start: true, - private_keys, - my_contribution, - their_contribution, - channel_timeout, - unroll_timeout, - reward_puzzle_hash, + private_keys: phi.private_keys, + my_contribution: phi.my_contribution, + their_contribution: phi.their_contribution, + channel_timeout: phi.channel_timeout, + unroll_timeout: phi.unroll_timeout, + reward_puzzle_hash: phi.reward_puzzle_hash, } } @@ -840,7 +842,7 @@ impl PotatoHandler { first_player_hs_info, second_player_hs_info, }, - spend: spend, + spend, })); } @@ -1716,7 +1718,7 @@ impl PotatoHandler { + finished_unroll_coin.coin.get_unroll_coin_signature()?; assert!(aggregate_unroll_signature.verify( &player_ch.get_aggregate_unroll_public_key(), - &unroll_puzzle_solution_hash.bytes() + unroll_puzzle_solution_hash.bytes() )); debug!("{} SPEND: AGGREGATE UNROLL hash {unroll_puzzle_solution_hash:?} {aggregate_unroll_signature:?}", player_ch.is_initial_potato()); @@ -1827,7 +1829,6 @@ impl PotatoHandler { )); }; - let ch = self.channel_handler_mut()?; let (env, system_interface) = penv.env(); let run_puzzle = puzzle.to_nodeptr(env.allocator)?; let run_args = solution.to_nodeptr(env.allocator)?; @@ -1843,24 +1844,6 @@ impl PotatoHandler { // XXX If I wasn't the one who initiated the on chain transition, determine whether // to bump the unroll coin. let channel_conditions = CoinCondition::from_nodeptr(env.allocator, conditions.1); - let channel_sequence_number = if let Some(rem) = channel_conditions - .iter() - .filter_map(|c| { - if let CoinCondition::Rem(data) = c { - return data.first().and_then(|a| usize_from_atom(a)); - } - - None - }) - .next() - { - rem - } else { - return Err(Error::StrErr( - "channel conditions didn't include a rem".to_string(), - )); - }; - let unroll_coin = if let Some(coin_id) = channel_conditions .iter() .filter_map(|c| { @@ -1892,9 +1875,9 @@ impl PotatoHandler { // matches the state system given so on chain play can proceed. fn finish_on_chain_transition<'a, G, R: Rng + 'a>( &mut self, - penv: &mut dyn PeerEnv<'a, G, R>, - coin_id: &CoinString, - puzzle_and_solution: Option<(&Program, &Program)>, + _penv: &mut dyn PeerEnv<'a, G, R>, + _coin_id: &CoinString, + _puzzle_and_solution: Option<(&Program, &Program)>, ) -> Result<(), Error> where G: ToLocalUI + BootstrapTowardWallet + WalletSpendInterface + PacketSender + 'a, @@ -2151,7 +2134,7 @@ impl, + _name: Option<&'static str>, ) -> Result<(), Error> { self.registered_coins .insert(coin_id.clone(), timeout.clone()); @@ -413,16 +414,16 @@ fn test_peer_smoke() { let reward_puzzle_hash1 = puzzle_hash_for_pk(allocator, &reward_public_key1).expect("should work"); - PotatoHandler::new( + PotatoHandler::new(PotatoHandlerInit { have_potato, - private_keys1, - game_type_map.clone(), - Amount::new(100), - Amount::new(100), - Timeout::new(1000), - Timeout::new(5), - reward_puzzle_hash1.clone(), - ) + private_keys: private_keys1, + game_types: game_type_map.clone(), + my_contribution: Amount::new(100), + their_contribution: Amount::new(100), + channel_timeout: Timeout::new(1000), + unroll_timeout: Timeout::new(5), + reward_puzzle_hash: reward_puzzle_hash1.clone(), + }) }; let parent_private_key: PrivateKey = rng.gen(); diff --git a/src/tests/peer/potato_handler_sim.rs b/src/tests/peer/potato_handler_sim.rs index 13e02f1..5bfe7aa 100644 --- a/src/tests/peer/potato_handler_sim.rs +++ b/src/tests/peer/potato_handler_sim.rs @@ -1,4 +1,4 @@ -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use clvm_traits::ToClvm; use log::debug; @@ -23,7 +23,7 @@ use crate::peer_container::{ }; use crate::potato_handler::{ BootstrapTowardGame, BootstrapTowardWallet, FromLocalUI, GameStart, GameType, PacketSender, - PeerEnv, PeerMessage, PotatoHandler, ToLocalUI, WalletSpendInterface, + PeerEnv, PeerMessage, PotatoHandler, PotatoHandlerInit, ToLocalUI, WalletSpendInterface, }; use crate::simulator::Simulator; @@ -477,16 +477,16 @@ fn run_calpoker_test_with_action_list(allocator: &mut AllocEncoder, moves: &[Gam let reward_puzzle_hash1 = puzzle_hash_for_pk(allocator, &reward_public_key1).expect("should work"); - PotatoHandler::new( + PotatoHandler::new(PotatoHandlerInit { have_potato, - private_keys1, - game_type_map.clone(), - Amount::new(100), - Amount::new(100), - Timeout::new(1000), - Timeout::new(5), - reward_puzzle_hash1.clone(), - ) + private_keys: private_keys1, + game_types: game_type_map.clone(), + my_contribution: Amount::new(100), + their_contribution: Amount::new(100), + channel_timeout: Timeout::new(1000), + unroll_timeout: Timeout::new(5), + reward_puzzle_hash: reward_puzzle_hash1.clone(), + }) }; let ph1 = new_peer(allocator, &mut rng, false); @@ -696,10 +696,12 @@ impl ToLocalUI for LocalTestUIReceiver { } } +type GameRunEarlySuccessPredicate<'a> = Option<&'a dyn Fn(&[SynchronousGameCradle]) -> bool>; + fn run_calpoker_container_with_action_list_with_success_predicate( allocator: &mut AllocEncoder, moves: &[GameAction], - pred: Option<&dyn Fn(&[SynchronousGameCradle]) -> bool>, + pred: GameRunEarlySuccessPredicate, ) { // Coinset adapter for each side. let mut rng = ChaCha8Rng::from_seed([0; 32]); @@ -1019,6 +1021,6 @@ fn sim_test_with_peer_container_piss_off_peer() { run_calpoker_container_with_action_list_with_success_predicate( &mut allocator, &moves, - Some(&mut |cradles| cradles[0].is_on_chain() && cradles[1].is_on_chain()), + Some(&|cradles| cradles[0].is_on_chain() && cradles[1].is_on_chain()), ); } diff --git a/src/tests/simenv.rs b/src/tests/simenv.rs index 92cf927..ef8e2da 100644 --- a/src/tests/simenv.rs +++ b/src/tests/simenv.rs @@ -219,7 +219,7 @@ impl<'a, R: Rng> SimulatorEnvironment<'a, R> { let finished_unroll_coin = player_ch.get_finished_unroll_coin(); let pre_unroll_data = player_ch.get_create_unroll_coin_transaction( &mut self.env, - &finished_unroll_coin, + finished_unroll_coin, true, )?; @@ -302,7 +302,7 @@ impl<'a, R: Rng> SimulatorEnvironment<'a, R> { let finished_unroll_coin = player_ch.get_finished_unroll_coin(); let post_unroll_data = player_ch.get_create_unroll_coin_transaction( &mut self.env, - &finished_unroll_coin, + finished_unroll_coin, true, )?; debug!("post_unroll_data {post_unroll_data:?}");