Skip to content

Commit c90acf9

Browse files
committed
Give evidence a distinct type based on how it's used in the onchain referee as opposed to the coin solution. Create an object that represents the dynamic arguments to the onchain referee
1 parent 458b669 commit c90acf9

File tree

5 files changed

+103
-23
lines changed

5 files changed

+103
-23
lines changed

src/channel_handler/game_handler.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use clvmr::allocator::NodePtr;
1818
use clvmr::NO_UNKNOWN_OPS;
1919
use clvmr::{run_program, ChiaDialect};
2020

21-
use crate::channel_handler::types::{ReadableMove, ReadableUX};
21+
use crate::channel_handler::types::{ReadableMove, ReadableUX, Evidence};
2222
use crate::common::types::{
2323
atom_from_clvm, u64_from_atom, usize_from_atom, Aggsig, AllocEncoder, Amount, Error, Hash,
2424
IntoErr, Node,
@@ -151,7 +151,7 @@ fn run_code(
151151
#[derive(Debug, Clone)]
152152
pub enum TheirTurnResult {
153153
MakeMove(GameHandler, NodePtr, Vec<u8>),
154-
Slash(NodePtr, Aggsig),
154+
Slash(Evidence, Aggsig),
155155
}
156156

157157
impl GameHandler {
@@ -355,7 +355,7 @@ impl GameHandler {
355355
}
356356
let sig_bytes = allocator.allocator().atom(pl[2]).to_vec();
357357
Ok(TheirTurnResult::Slash(
358-
pl[1],
358+
Evidence::from_nodeptr(pl[1]),
359359
Aggsig::from_slice(&sig_bytes)?,
360360
))
361361
} else {

src/channel_handler/types.rs

+26
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,29 @@ pub enum CachedPotatoRegenerateLastHop {
225225
PotatoAccept(PotatoAcceptCachedData),
226226
PotatoMoveHappening(PotatoMoveCachedData),
227227
}
228+
229+
#[derive(Debug, Clone)]
230+
pub struct Evidence(NodePtr);
231+
232+
impl Evidence {
233+
pub fn from_nodeptr(n: NodePtr) -> Evidence {
234+
Evidence(n)
235+
}
236+
237+
pub fn nil(allocator: &mut AllocEncoder) -> Evidence {
238+
Evidence(allocator.allocator().null())
239+
}
240+
241+
pub fn to_nodeptr(&self) -> NodePtr {
242+
self.0
243+
}
244+
}
245+
246+
impl ToClvm<NodePtr> for Evidence {
247+
fn to_clvm(
248+
&self,
249+
_encoder: &mut impl ClvmEncoder<Node = NodePtr>,
250+
) -> Result<NodePtr, ToClvmError> {
251+
Ok(self.0)
252+
}
253+
}

src/referee.rs

+48-16
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::channel_handler::game_handler::{
1111
chia_dialect, GameHandler, MessageHandler, MessageInputs, MyTurnInputs, TheirTurnInputs,
1212
TheirTurnResult,
1313
};
14-
use crate::channel_handler::types::{GameStartInfo, ReadableMove, ReadableUX};
14+
use crate::channel_handler::types::{GameStartInfo, ReadableMove, ReadableUX, Evidence};
1515
use crate::common::constants::CREATE_COIN;
1616
use crate::common::standard_coin::{
1717
curry_and_treehash, private_to_public_key, puzzle_for_pk, puzzle_hash_for_pk, sign_agg_sig_me,
@@ -223,6 +223,34 @@ struct RefereeMakerGameState {
223223
pub previous_validation_program_hash: Hash,
224224
}
225225

226+
struct OnChainRefereeMove {
227+
// Details
228+
detauls: GameMoveDetails,
229+
mover_puzzle: Puzzle,
230+
mover_coin_spend_solution: NodePtr,
231+
}
232+
233+
struct OnChainRefereeSlash {
234+
previous_state: NodePtr,
235+
previous_validation_program: Program,
236+
mover_coin_puzzle: Puzzle,
237+
mover_coin_spend_solution: NodePtr,
238+
slash_evidence: Evidence,
239+
}
240+
241+
// onchain referee solution
242+
//
243+
// This represents the whole solution for the on chain referee.
244+
//
245+
// It is a solution itself, but the referee coin uses the mover puzzle as a
246+
// puzzle for a coin that represents the user's identity ... most likely a
247+
// standard puzzle.
248+
enum OnChainRefereeSolution {
249+
Timeout,
250+
Move(OnChainRefereeMove),
251+
Slash(OnChainRefereeSlash)
252+
}
253+
226254
// XXX break out state so we can have a previous state and easily swap them.
227255
// Referee coin has two inner puzzles.
228256
// Throughout channel handler, the one that's ours is the standard format puzzle
@@ -947,15 +975,15 @@ impl RefereeMaker {
947975
state: NodePtr,
948976
validation_program: Puzzle,
949977
slash_solution: NodePtr,
950-
coin_solution_after_slash: NodePtr
978+
evidence: Evidence
951979
) -> Result<NodePtr, Error> {
952980
(
953981
Node(state.clone()),
954982
(
955983
validation_program.clone(),
956984
(
957985
self.target_puzzle_hash_for_slash(),
958-
(Node(slash_solution), (Node(coin_solution_after_slash), ())),
986+
(Node(slash_solution), (Node(evidence.to_nodeptr()), ())),
959987
),
960988
),
961989
)
@@ -970,7 +998,7 @@ impl RefereeMaker {
970998
new_puzzle: &Puzzle,
971999
new_puzzle_hash: &PuzzleHash,
9721000
slash_solution: NodePtr,
973-
solution: NodePtr,
1001+
evidence: Evidence,
9741002
sig: &Aggsig,
9751003
) -> Result<TheirTurnCoinSpentResult, Error> {
9761004
// Probably readable_info overlaps solution.
@@ -997,7 +1025,7 @@ impl RefereeMaker {
9971025
state,
9981026
Puzzle::from_nodeptr(validation_program),
9991027
slash_solution,
1000-
solution
1028+
evidence
10011029
)?;
10021030

10031031
let coin_string_of_output_coin =
@@ -1171,14 +1199,16 @@ impl RefereeMaker {
11711199
Node(state.clone()),
11721200
(
11731201
Node(validation_program.clone()),
1174-
(new_puzzle_hash.clone(), (Node(slash_solution), (0, ()))),
1202+
// No evidence here.
1203+
(new_puzzle_hash.clone(), ((), (0, ()))),
11751204
),
11761205
)
11771206
.to_clvm(allocator)
11781207
.into_gen()?;
11791208

11801209
// Ultimately each of these cases returns some kind of
11811210
// TheirTurnCoinSpentResult.
1211+
let nil_evidence = Evidence::nil(allocator);
11821212
match full_slash_result {
11831213
Ok(_) => {
11841214
// result is NodePtr containing solution and aggsig.
@@ -1191,7 +1221,7 @@ impl RefereeMaker {
11911221
&new_puzzle,
11921222
&new_puzzle_hash,
11931223
full_slash_solution,
1194-
slash_solution,
1224+
nil_evidence,
11951225
&slash_aggsig,
11961226
)
11971227
}
@@ -1216,15 +1246,17 @@ impl RefereeMaker {
12161246
run_debug: self.run_debug,
12171247
},
12181248
)? {
1219-
TheirTurnResult::Slash(solution, sig) => self.make_slash_for_their_turn(
1220-
allocator,
1221-
coin_string,
1222-
&new_puzzle,
1223-
&new_puzzle_hash,
1224-
full_slash_solution,
1225-
solution,
1226-
&(slash_aggsig + sig),
1227-
),
1249+
TheirTurnResult::Slash(evidence, sig) => {
1250+
self.make_slash_for_their_turn(
1251+
allocator,
1252+
coin_string,
1253+
&new_puzzle,
1254+
&new_puzzle_hash,
1255+
full_slash_solution,
1256+
evidence,
1257+
&(slash_aggsig + sig),
1258+
)
1259+
}
12281260
TheirTurnResult::MakeMove(game_handler, readable_move, message) => {
12291261
// Otherwise accept move by updating our state
12301262
self.accept_this_move(

src/tests/game_handler.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ fn test_game_handler_their_move_slash() {
4545
},
4646
)
4747
.expect("should run");
48-
if let TheirTurnResult::Slash(solution, aggsig) = result {
48+
if let TheirTurnResult::Slash(evidence, aggsig) = result {
4949
// Good, check more
5050
assert_eq!(aggsig, default_aggsig);
51-
assert_eq!(disassemble(allocator.allocator(), solution, None), "(1337 () () () 0x0000000000000000000000000000000000000000000000000000000000000000 () ())");
51+
assert_eq!(disassemble(allocator.allocator(), evidence.to_nodeptr(), None), "(1337 () () () 0x0000000000000000000000000000000000000000000000000000000000000000 () ())");
5252
} else {
5353
assert!(false);
5454
}

src/tests/simulator.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use crate::common::constants::{AGG_SIG_ME_ADDITIONAL_DATA, CREATE_COIN, DEFAULT_
1515
use crate::common::standard_coin::{sign_agg_sig_me, standard_solution_partial, ChiaIdentity, calculate_synthetic_secret_key, private_to_public_key, calculate_synthetic_public_key, agg_sig_me_message};
1616
use crate::common::types::{ErrToError, Error, Puzzle, Amount, Hash, CoinString, CoinID, PuzzleHash, PrivateKey, Aggsig, Node, SpecificTransactionBundle, AllocEncoder, TransactionBundle, ToQuotedProgram, Sha256tree, Timeout, GameID};
1717

18-
use crate::channel_handler::types::GameStartInfo;
19-
18+
use crate::channel_handler::types::{GameStartInfo, ReadableMove};
19+
use crate::referee::GameMoveDetails;
2020
use crate::tests::referee::{RefereeTest, make_debug_game_handler};
2121

2222
// Allow simulator from rust.
@@ -384,4 +384,26 @@ fn test_referee_can_slash_on_chain() {
384384
their_validation_program_hash,
385385
&game_start_info,
386386
);
387+
388+
let readable_move = assemble(allocator.allocator(), "(0 . 0)").expect("should assemble");
389+
let my_move_wire_data = reftest.my_referee
390+
.my_turn_make_move(
391+
&mut rng,
392+
&mut allocator,
393+
&ReadableMove::from_nodeptr(readable_move),
394+
)
395+
.expect("should move");
396+
397+
assert!(my_move_wire_data.details.move_made.is_empty());
398+
let mut off_chain_slash_gives_error = reftest.my_referee.clone();
399+
let their_move_result = off_chain_slash_gives_error.their_turn_move_off_chain(
400+
&mut allocator,
401+
&GameMoveDetails {
402+
move_made: vec![1],
403+
validation_info_hash: my_move_wire_data.details.validation_info_hash.clone(),
404+
max_move_size: 100,
405+
mover_share: Amount::default(),
406+
},
407+
);
408+
eprintln!("their_move_result {their_move_result:?}");
387409
}

0 commit comments

Comments
 (0)