Skip to content

Commit 64689ea

Browse files
Merge pull request #9 from Chia-Network/20240805-peer-sim
20240805 peer sim
2 parents 9a2e7c4 + 8ac2d24 commit 64689ea

11 files changed

+1412
-76
lines changed

build.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ fn compile_chialisp() -> Result<(), CompileError> {
7272

7373
// Compile chialisp programs in this tree.
7474
fn main() {
75-
if let Err(e) = compile_chialisp() {
76-
panic!("error compiling chialisp: {e:?}");
75+
if std::env::var("CHIALISP_NOCOMPILE").is_err() {
76+
if let Err(e) = compile_chialisp() {
77+
panic!("error compiling chialisp: {e:?}");
78+
}
7779
}
7880
}

src/common/standard_coin.rs

+13
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,19 @@ pub fn standard_solution_partial(
483483
_ => {}
484484
}
485485
}
486+
487+
// Assume something like create coin if nothing else.
488+
if aggregated_signature.is_none() {
489+
add_signature(
490+
&mut aggregated_signature,
491+
if partial {
492+
partial_signer(private_key, aggregate_public_key, &coin_agg_sig_me_message)
493+
} else {
494+
private_key.sign(&coin_agg_sig_me_message)
495+
},
496+
);
497+
}
498+
486499
if let Some(signature) = aggregated_signature {
487500
Ok(BrokenOutCoinSpendInfo {
488501
solution,

src/common/types.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,15 @@ impl ToClvm<NodePtr> for CoinID {
5656
}
5757

5858
/// Coin String
59-
#[derive(Default, Clone, Debug, Serialize, Deserialize)]
59+
#[derive(Default, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
6060
pub struct CoinString(Vec<u8>);
6161

62+
impl std::fmt::Debug for CoinString {
63+
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
64+
writeln!(formatter, "{:?}", self.to_parts())
65+
}
66+
}
67+
6268
impl CoinString {
6369
pub fn from_parts(parent: &CoinID, puzzle_hash: &PuzzleHash, amount: &Amount) -> CoinString {
6470
let mut allocator = AllocEncoder::new();
@@ -697,14 +703,18 @@ impl Puzzle {
697703
}
698704
}
699705

700-
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
706+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
701707
pub struct Timeout(u64);
702708

703709
impl Timeout {
704710
pub fn new(t: u64) -> Self {
705711
Timeout(t)
706712
}
707713

714+
pub fn to_u64(&self) -> u64 {
715+
self.0
716+
}
717+
708718
pub fn from_clvm(allocator: &mut AllocEncoder, clvm: NodePtr) -> Result<Self, Error> {
709719
if let Some(amt) = atom_from_clvm(allocator, clvm).and_then(u64_from_atom) {
710720
Ok(Timeout::new(amt))

src/outside.rs

+128-7
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,35 @@ pub trait BootstrapTowardWallet {
171171
}
172172

173173
/// 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;
178203
}
179204

180205
/// Unroll time wallet interface.
@@ -183,7 +208,7 @@ pub trait WalletSpendInterface {
183208
fn spend_transaction_and_add_fee(&mut self, bundle: &Spend) -> Result<(), Error>;
184209
/// Coin should report its lifecycle until it gets spent, then should be
185210
/// 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>;
187212
}
188213

189214
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
@@ -286,7 +311,7 @@ pub struct HandshakeStepInfo {
286311
pub second_player_hs_info: HandshakeB,
287312
}
288313

289-
#[derive(Debug)]
314+
#[derive(Debug, Clone)]
290315
pub struct HandshakeStepWithSpend {
291316
#[allow(dead_code)]
292317
pub info: HandshakeStepInfo,
@@ -384,6 +409,9 @@ pub struct PotatoHandler {
384409
their_contribution: Amount,
385410

386411
reward_puzzle_hash: PuzzleHash,
412+
413+
waiting_to_start: bool,
414+
channel_timeout: Timeout,
387415
}
388416

389417
fn init_game_id(private_keys: &ChannelHandlerPrivateKeys) -> Vec<u8> {
@@ -424,6 +452,7 @@ impl PotatoHandler {
424452
game_types: BTreeMap<GameType, Program>,
425453
my_contribution: Amount,
426454
their_contribution: Amount,
455+
channel_timeout: Timeout,
427456
reward_puzzle_hash: PuzzleHash,
428457
) -> PotatoHandler {
429458
PotatoHandler {
@@ -449,9 +478,12 @@ impl PotatoHandler {
449478
channel_initiation_transaction: None,
450479
channel_finished_transaction: None,
451480

481+
waiting_to_start: true,
482+
452483
private_keys,
453484
my_contribution,
454485
their_contribution,
486+
channel_timeout,
455487
reward_puzzle_hash,
456488
}
457489
}
@@ -633,6 +665,11 @@ impl PotatoHandler {
633665
where
634666
G: ToLocalUI + BootstrapTowardWallet + WalletSpendInterface + PacketSender + 'a,
635667
{
668+
// Haven't got the channel coin yet.
669+
if self.waiting_to_start {
670+
return Ok(());
671+
}
672+
636673
if let Some(spend) = self.channel_finished_transaction.as_ref() {
637674
self.handshake_state = HandshakeState::Finished(Box::new(HandshakeStepWithSpend {
638675
info: HandshakeStepInfo {
@@ -990,7 +1027,6 @@ impl PotatoHandler {
9901027
};
9911028

9921029
let channel_coin = channel_handler.state_channel_coin();
993-
9941030
let channel_puzzle_hash =
9951031
if let Some((_, puzzle_hash, _)) = channel_coin.coin_string().to_parts() {
9961032
puzzle_hash
@@ -1005,6 +1041,8 @@ impl PotatoHandler {
10051041
{
10061042
let (_env, system_interface) = penv.env();
10071043
system_interface.channel_puzzle_hash(&channel_puzzle_hash)?;
1044+
system_interface
1045+
.register_coin(channel_coin.coin_string(), &self.channel_timeout)?;
10081046
};
10091047

10101048
let channel_public_key =
@@ -1125,8 +1163,25 @@ impl PotatoHandler {
11251163
)));
11261164
};
11271165

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+
11281173
{
11291174
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+
11301185
system_interface.received_channel_offer(&bundle)?;
11311186
}
11321187

@@ -1335,3 +1390,69 @@ impl<G: ToLocalUI + BootstrapTowardWallet + WalletSpendInterface + PacketSender,
13351390
Ok(())
13361391
}
13371392
}
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

Comments
 (0)