Skip to content

Commit

Permalink
arbiter.jsligo: DisputeMove draft #2
Browse files Browse the repository at this point in the history
  • Loading branch information
utgarda committed Dec 3, 2022
1 parent 0acbfec commit 57da625
Show file tree
Hide file tree
Showing 2 changed files with 204 additions and 1 deletion.
35 changes: 34 additions & 1 deletion arbiter.jsligo
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ type game = {
key_hash_to_player_id: map<key_hash, nat>,
players: [key, key]
} ;
const disqualify = (g: game, p: key) =>
({...g, finished: true});


type storage = map<nat, game>;

Expand All @@ -27,7 +30,24 @@ type parameter =
| ["ProposeGame", address]
| ["AcceptGame", nat];

const dispute_move = ([store, signed_game_move] : [storage, signed_game_move]) => store; //TODO
const dispute_move = ([store, signed_game_move] : [storage, signed_game_move]) => {
const game_id = signed_game_move.game_move.game_id;
// const game = {
return match(Map.find_opt(game_id, store), {
Some: game => {
const player = signed_game_move.game_move.player;
//TODO check move validity
//TODO check if player in game
//TODO check signature
Map.update(
game_id,
Some(disqualify(game, player)),
store);
},
None: () => failwith("No game.")
});
};

const propose_game = ([store, rules] : [storage, address]) => store;
const accept_game = ([store, game_id] : [storage, nat]) => store;

Expand All @@ -40,3 +60,16 @@ const main = ([action, store] : [parameter, storage]) : [list <operation>, stora
AcceptGame: game_id => accept_game ([store, game_id])}))
]
};


const move_is_signed_by_mover = (signed_move: signed_game_move) => {
const player = signed_move.game_move.player;
const kh = Crypto.hash_key(player);
return match(Map.find_opt (kh, signed_move.signatures), {
Some: sig => {
const move_packed = Bytes.pack(signed_move.game_move);
Crypto.check(player, sig, move_packed);
},
None: () => false
});
};
170 changes: 170 additions & 0 deletions test-arbiter.jsligo
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#include "arbiter.jsligo"

type tic_tac_toe_board = {
cells: map<nat, nat>,
crosses_win: bool,
naughts_win: bool
};

type tic_tac_toe_move = nat;

let assert_string_failure = ([res,expected] : [test_exec_result, string]) => {
let expected_bis = Test.eval (expected) ;
match (res, {
Fail: (x: test_exec_error) => (
match (x, {
Rejected: (x:[michelson_code,address]) => assert (Test.michelson_equal (x[0], expected_bis)),
Balance_too_low: (_: { contract_too_low : address , contract_balance : tez , spend_request : tez }) => Test.failwith ("contract failed for an unknown reason"),
Other: (_:string) => Test.failwith ("contract failed for an unknown reason")
})),
Success: (_:nat) => Test.failwith ("bad price check")
} );
} ;


const test_new_account_a = Test.new_account();
const test_player_a = test_new_account_a[1];
const test_player_a_secret_key = test_new_account_a[0];

const test_emtpy_cells = Map.literal (list([
[0 as nat, 0 as nat],
[1 as nat, 0 as nat],
[2 as nat, 0 as nat],
[3 as nat, 0 as nat],
[4 as nat, 0 as nat],
[5 as nat, 0 as nat],
[6 as nat, 0 as nat],
[7 as nat, 0 as nat],
[8 as nat, 0 as nat]
])) ;
const test_empty_board = ({cells: test_emtpy_cells,
crosses_win: false,
naughts_win: false}) as tic_tac_toe_board;

const test_packed_empty_board = Bytes.pack(test_empty_board);

const test_invalid_game_move_both_states_empty = ({
game_id: 1 as nat,
nonce: 0 as nat,
player: test_player_a,
old_state: test_packed_empty_board,
new_state: test_packed_empty_board,
move: Bytes.pack(0)
}) as game_move;
const test_invalid_game_move_packed = Bytes.pack(test_invalid_game_move_both_states_empty);
const test_sig = Test.sign(
test_player_a_secret_key,
Bytes.pack(test_invalid_game_move_packed));

const test_player_a_hash = Crypto.hash_key(test_player_a);
const test_signed_invalid_game_move = ({
game_move: test_invalid_game_move_both_states_empty,
signatures: Map.literal (list([
[test_player_a_hash, test_sig]
]))
});

let test = ((_: unit): unit => {
const [player_a_secret_key, player_a] = test_new_account_a;
const [_player_b_secret_key, player_b] = Test.new_account();
const player_a_hash = Crypto.hash_key(player_a);
const player_b_hash = Crypto.hash_key(player_b);
//TODO add session keys

const tic_tac_toe_rules_address = "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" as address;
const started_game = ({
rules : tic_tac_toe_rules_address,
started: true,
finished: false,
key_hash_to_player_id: Map.literal (list([
[player_a_hash, 1 as nat],
[player_b_hash, 1 as nat]
])),
players: [player_a, player_b]
}) as game;

const player_a_disqualified_game = ({
rules : tic_tac_toe_rules_address,
started: true,
finished: true, //TODO emit events
key_hash_to_player_id: Map.literal (list([
[player_a_hash, 1 as nat],
[player_b_hash, 1 as nat]
])),
players: [player_a, player_b]
}) as game;


const init_storage = Map.literal (list([
[1 as nat, started_game]
])) ;

const [arbiter_single_game_ta, _code, _size] = Test.originate (main, init_storage, 0 as tez);
/* Convert typed_address to contract */
let arbiter_single_game_ctr = Test.to_contract (arbiter_single_game_ta);
/* Convert contract to address */
// let arbiter_single_game = Tezos.address (arbiter_single_game_ctr);

const emtpy_cells = Map.literal (list([
[0 as nat, 0 as nat],
[1 as nat, 0 as nat],
[2 as nat, 0 as nat],
[3 as nat, 0 as nat],
[4 as nat, 0 as nat],
[5 as nat, 0 as nat],
[6 as nat, 0 as nat],
[7 as nat, 0 as nat],
[8 as nat, 0 as nat]
])) ;
const empty_board = ({cells: emtpy_cells,
crosses_win: false,
naughts_win: false}) as tic_tac_toe_board;

const invalid_game_move = test_invalid_game_move_both_states_empty;

const sig = Test.sign(
player_a_secret_key,
Bytes.pack(invalid_game_move));


const signed_invalid_game_move = ({
game_move: invalid_game_move,
signatures: Map.literal (list([
[player_a_hash, sig]
]))
});

const eq_games = ([g1, g2]: [game, game]) =>
g1.rules == g2.rules &&
g1.started == g2.started &&
g1.finished == g2.finished &&
g1.key_hash_to_player_id == g2.key_hash_to_player_id &&
Crypto.hash_key(g1.players[0]) == Crypto.hash_key(g2.players[0]) &&
Crypto.hash_key(g1.players[1]) == Crypto.hash_key(g2.players[1]);


/* Auxiliary function for testing equality in maps */
let eq_in_map = ([g, m, k] : [game, storage, nat]) =>
match(Map.find_opt(k, m), {
None: () => false,
Some: (v : game) => eq_games(v, g) }) ;


let ok_case : test_exec_result = Test.transfer_to_contract (
arbiter_single_game_ctr,
DisputeMove(signed_invalid_game_move),
0 as tez) ;

let _u = match (ok_case, {
Success: (_:nat) => {
const storage = Test.get_storage (arbiter_single_game_ta) ;
assert_with_error (
eq_in_map(player_a_disqualified_game, storage, 1 as nat),
"The game should be finished"
); //TODO
},
Fail: (_: test_exec_error) => Test.failwith ("ok test case failed")
}) ;

return unit
}) ();

0 comments on commit 57da625

Please sign in to comment.