ligo/src/test/multisig_tests.ml

187 lines
7.8 KiB
OCaml
Raw Normal View History

2019-11-19 18:36:48 +04:00
open Trace
open Test_helpers
let file = "./contracts/multisig.ligo"
let mfile = "./contracts/multisig.mligo"
let refile = "./contracts/multisig.religo"
let type_file f s =
let%bind simplified = Ligo.Compile.Of_source.compile f (Syntax_name s) in
let%bind typed,state = Ligo.Compile.Of_simplified.compile (Contract "main") simplified in
2019-11-30 01:22:56 +04:00
ok @@ (typed,state)
2019-11-19 18:36:48 +04:00
let get_program f st =
2019-11-19 18:36:48 +04:00
let s = ref None in
fun () -> match !s with
| Some s -> ok s
| None -> (
let%bind program = type_file f st in
2019-11-19 18:36:48 +04:00
s := Some program ;
ok program
)
let compile_main f s () =
let%bind typed_prg,_ = type_file f s in
2020-01-07 01:29:07 +04:00
let%bind mini_c_prg = Ligo.Compile.Of_typed.compile typed_prg in
let%bind michelson_prg = Ligo.Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg "main" in
let%bind (_contract: Tezos_utils.Michelson.michelson) =
(* fails if the given entry point is not a valid contract *)
2019-12-18 19:34:29 +04:00
Ligo.Compile.Of_michelson.build_contract michelson_prg in
2019-11-19 18:36:48 +04:00
ok ()
open Ast_simplified
let init_storage threshold counter pkeys =
let keys = List.map
(fun el ->
let (_,pk_str,_) = str_keys el in
e_key @@ pk_str)
pkeys in
2019-12-04 21:30:52 +04:00
e_record_ez [
2019-11-20 21:17:35 +04:00
("id" , e_string "MULTISIG" ) ;
2019-11-19 18:36:48 +04:00
("counter" , e_nat counter ) ;
("threshold" , e_nat threshold) ;
("auth" , e_typed_list keys t_key ) ;
]
let empty_op_list =
(e_typed_list [] t_operation)
let empty_message = e_lambda (Var.of_name "arguments")
2019-11-19 18:36:48 +04:00
(Some t_unit) (Some (t_list t_operation))
empty_op_list
2019-11-20 21:17:35 +04:00
let chain_id_zero = e_chain_id @@ Tezos_crypto.Base58.simple_encode
Tezos_base__TzPervasives.Chain_id.b58check_encoding
Tezos_base__TzPervasives.Chain_id.zero
2019-11-19 18:36:48 +04:00
(* sign the message 'msg' with 'keys', if 'is_valid'=false the providid signature will be incorrect *)
let params counter msg keys is_validl f s =
let%bind program,_ = get_program f s () in
let aux = fun acc (key,is_valid) ->
let (_,_pk,sk) = key in
let (pkh,_,_) = str_keys key in
2019-11-20 21:17:35 +04:00
let payload = e_tuple
[ msg ;
e_nat counter ;
e_string (if is_valid then "MULTISIG" else "XX") ;
2019-11-20 21:17:35 +04:00
chain_id_zero ] in
2019-11-22 18:52:46 +04:00
let%bind signature = sign_message program payload sk in
ok @@ (e_pair (e_key_hash pkh) (e_signature signature))::acc in
let%bind signed_msgs = Trace.bind_fold_list aux [] (List.rev @@ List.combine keys is_validl) in
2019-11-19 18:36:48 +04:00
ok @@ e_constructor
"CheckMessage"
2019-12-04 21:30:52 +04:00
(e_record_ez [
2019-11-19 18:36:48 +04:00
("counter" , e_nat counter ) ;
("message" , msg) ;
("signatures" , e_typed_list signed_msgs (t_pair (t_key_hash,t_signature)) ) ;
2019-11-19 18:36:48 +04:00
])
(* Provide one valid signature when the threshold is two of two keys *)
let not_enough_1_of_2 f s () =
let%bind program,_ = get_program f s () in
2019-11-19 18:36:48 +04:00
let exp_failwith = "Not enough signatures passed the check" in
let keys = gen_keys () in
let%bind test_params = params 0 empty_message [keys] [true] f s in
2019-11-19 18:36:48 +04:00
let%bind () = expect_string_failwith
program "main" (e_pair test_params (init_storage 2 0 [keys;gen_keys()])) exp_failwith in
ok ()
let unmatching_counter f s () =
let%bind program,_ = get_program f s () in
2019-11-19 18:36:48 +04:00
let exp_failwith = "Counters does not match" in
let keys = gen_keys () in
let%bind test_params = params 1 empty_message [keys] [true] f s in
2019-11-19 18:36:48 +04:00
let%bind () = expect_string_failwith
program "main" (e_pair test_params (init_storage 1 0 [keys])) exp_failwith in
ok ()
(* Provide one invalid signature (correct key but incorrect signature)
when the threshold is one of one key *)
let invalid_1_of_1 f s () =
let%bind program,_ = get_program f s () in
2019-11-19 18:36:48 +04:00
let exp_failwith = "Invalid signature" in
let keys = [gen_keys ()] in
let%bind test_params = params 0 empty_message keys [false] f s in
2019-11-19 18:36:48 +04:00
let%bind () = expect_string_failwith
program "main" (e_pair test_params (init_storage 1 0 keys)) exp_failwith in
2019-11-19 18:36:48 +04:00
ok ()
(* Provide one valid signature when the threshold is one of one key *)
let valid_1_of_1 f s () =
let%bind program,_ = get_program f s () in
2019-11-19 18:36:48 +04:00
let keys = gen_keys () in
let%bind () = expect_eq_n_trace_aux [0;1;2] program "main"
(fun n ->
let%bind params = params n empty_message [keys] [true] f s in
2019-11-19 18:36:48 +04:00
ok @@ e_pair params (init_storage 1 n [keys])
)
(fun n ->
ok @@ e_pair empty_op_list (init_storage 1 (n+1) [keys])
) in
ok ()
(* Provive two valid signatures when the threshold is two of three keys *)
let valid_2_of_3 f s () =
let%bind program,_ = get_program f s () in
let param_keys = [gen_keys (); gen_keys ()] in
let st_keys = param_keys @ [gen_keys ()] in
2019-11-19 18:36:48 +04:00
let%bind () = expect_eq_n_trace_aux [0;1;2] program "main"
(fun n ->
let%bind params = params n empty_message param_keys [true;true] f s in
2019-11-19 18:36:48 +04:00
ok @@ e_pair params (init_storage 2 n st_keys)
)
(fun n ->
ok @@ e_pair empty_op_list (init_storage 2 (n+1) st_keys)
) in
ok ()
(* Provide one invalid signature and two valid signatures when the threshold is two of three keys *)
let invalid_3_of_3 f s () =
let%bind program,_ = get_program f s () in
2019-11-19 18:36:48 +04:00
let valid_keys = [gen_keys() ; gen_keys()] in
let invalid_key = gen_keys () in
let param_keys = valid_keys @ [invalid_key] in
let st_keys = valid_keys @ [gen_keys ()] in
let%bind test_params = params 0 empty_message param_keys [false;true;true] f s in
2019-11-19 18:36:48 +04:00
let exp_failwith = "Invalid signature" in
let%bind () = expect_string_failwith
program "main" (e_pair test_params (init_storage 2 0 st_keys)) exp_failwith in
ok ()
(* Provide two valid signatures when the threshold is three of three keys *)
let not_enough_2_of_3 f s () =
let%bind program,_ = get_program f s() in
2019-11-19 18:36:48 +04:00
let valid_keys = [gen_keys() ; gen_keys()] in
let st_keys = gen_keys () :: valid_keys in
let%bind test_params = params 0 empty_message (valid_keys) [true;true] f s in
2019-11-19 18:36:48 +04:00
let exp_failwith = "Not enough signatures passed the check" in
let%bind () = expect_string_failwith
program "main" (e_pair test_params (init_storage 3 0 st_keys)) exp_failwith in
ok ()
let main = test_suite "Multisig" [
test "compile" (compile_main file "pascaligo");
test "unmatching_counter" (unmatching_counter file "pascaligo");
test "valid_1_of_1" (valid_1_of_1 file "pascaligo");
test "invalid_1_of_1" (invalid_1_of_1 file "pascaligo");
test "not_enough_signature" (not_enough_1_of_2 file "pascaligo");
test "valid_2_of_3" (valid_2_of_3 file "pascaligo");
test "invalid_3_of_3" (invalid_3_of_3 file "pascaligo");
test "not_enough_2_of_3" (not_enough_2_of_3 file "pascaligo");
test "compile (mligo)" (compile_main mfile "cameligo");
test "unmatching_counter (mligo)" (unmatching_counter mfile "cameligo");
test "valid_1_of_1 (mligo)" (valid_1_of_1 mfile "cameligo");
test "invalid_1_of_1 (mligo)" (invalid_1_of_1 mfile "cameligo");
test "not_enough_signature (mligo)" (not_enough_1_of_2 mfile "cameligo");
test "valid_2_of_3 (mligo)" (valid_2_of_3 mfile "cameligo");
test "invalid_3_of_3 (mligo)" (invalid_3_of_3 mfile "cameligo");
test "not_enough_2_of_3 (mligo)" (not_enough_2_of_3 mfile "cameligo");
test "compile (religo)" (compile_main refile "reasonligo");
test "unmatching_counter (religo)" (unmatching_counter refile "reasonligo");
test "valid_1_of_1 (religo)" (valid_1_of_1 refile "reasonligo");
test "invalid_1_of_1 (religo)" (invalid_1_of_1 refile "reasonligo");
test "not_enough_signature (religo)" (not_enough_1_of_2 refile "reasonligo");
test "valid_2_of_3 (religo)" (valid_2_of_3 refile "reasonligo");
test "invalid_3_of_3 (religo)" (invalid_3_of_3 refile "reasonligo");
test "not_enough_2_of_3 (religo)" (not_enough_2_of_3 refile "reasonligo");
2019-11-19 18:36:48 +04:00
]