Add command for measuring contracts

This commit is contained in:
Tom Jack 2019-11-25 17:30:12 -06:00
parent c322ca53de
commit f7ef0472be
4 changed files with 408 additions and 2 deletions

View File

@ -98,6 +98,21 @@ let compile_file =
let docs = "Subcommand: compile a contract. See `ligo " ^ cmdname ^ " --help' for a list of options specific to this subcommand." in let docs = "Subcommand: compile a contract. See `ligo " ^ cmdname ^ " --help' for a list of options specific to this subcommand." in
(term , Term.info ~docs cmdname) (term , Term.info ~docs cmdname)
let measure_contract =
let f source_file entry_point syntax display_format =
toplevel ~display_format @@
let%bind contract =
trace (simple_info "compiling contract to michelson") @@
Ligo.Compile.Of_source.compile_file_contract_entry source_file entry_point (Syntax_name syntax) in
let open Tezos_utils in
ok @@ Format.asprintf "%d bytes\n" (Michelson.measure contract)
in
let term =
Term.(const f $ source_file 0 $ entry_point 1 $ syntax $ display_format) in
let cmdname = "measure-contract" in
let doc = "Subcommand: measure a contract's compiled size in bytes." in
(term , Term.info ~doc cmdname)
let compile_parameter = let compile_parameter =
let f source_file entry_point expression syntax display_format michelson_format = let f source_file entry_point expression syntax display_format michelson_format =
toplevel ~display_format @@ toplevel ~display_format @@
@ -190,6 +205,7 @@ let compile_expression =
let run ?argv () = let run ?argv () =
Term.eval_choice ?argv main [ Term.eval_choice ?argv main [
compile_file ; compile_file ;
measure_contract ;
compile_parameter ; compile_parameter ;
compile_storage ; compile_storage ;
compile_expression ; compile_expression ;

View File

@ -3,6 +3,21 @@ open Cli_expect
let contract basename = let contract basename =
"../../test/contracts/" ^ basename "../../test/contracts/" ^ basename
let%expect_test _ =
run_ligo_good [ "measure-contract" ; contract "coase.ligo" ; "main" ] ;
[%expect {| 3098 bytes |}] ;
run_ligo_good [ "measure-contract" ; contract "multisig.ligo" ; "main" ] ;
[%expect {| 1367 bytes |}] ;
run_ligo_good [ "measure-contract" ; contract "multisig-v2.ligo" ; "main" ] ;
[%expect {| 861 bytes |}] ;
run_ligo_good [ "measure-contract" ; contract "vote.mligo" ; "main" ] ;
[%expect {| 1344 bytes |}] ;
()
let%expect_test _ = let%expect_test _ =
run_ligo_good [ "compile-contract" ; contract "coase.ligo" ; "main" ] ; run_ligo_good [ "compile-contract" ; contract "coase.ligo" ; "main" ] ;
[%expect {| [%expect {|
@ -288,4 +303,370 @@ let %expect_test _ =
DIP { DIP 6 { DUP } ; DIG 6 } ; DIP { DIP 6 { DUP } ; DIG 6 } ;
EXEC ; EXEC ;
DIP { DROP 2 } } ; DIP { DROP 2 } } ;
DIP { DROP 6 } } } |} ] ; DIP { DROP 6 } } } |} ]
let%expect_test _ =
run_ligo_good [ "compile-contract" ; contract "multisig.ligo" ; "main" ] ;
[%expect {|
{ parameter
(pair (pair (nat %counter) (lambda %message unit (list operation)))
(list %signatures (pair key_hash signature))) ;
storage
(pair (pair (list %auth key) (nat %counter)) (pair (string %id) (nat %threshold))) ;
code { DUP ;
LAMBDA
(pair (pair (pair (nat %counter) (lambda %message unit (list operation)))
(list %signatures (pair key_hash signature)))
(pair (pair (list %auth key) (nat %counter)) (pair (string %id) (nat %threshold))))
(pair (list operation)
(pair (pair (list %auth key) (nat %counter)) (pair (string %id) (nat %threshold))))
{ DUP ;
CAR ;
DIP { DUP } ;
SWAP ;
CDR ;
DIP { DUP } ;
SWAP ;
CAR ;
CDR ;
DIP 2 { DUP } ;
DIG 2 ;
CAR ;
CAR ;
DIP { DIP { DUP } ; SWAP ; CAR ; CDR } ;
COMPARE ;
NEQ ;
IF { PUSH string "Counters does not match" ; FAILWITH }
{ DUP ;
DIP { DIP 2 { DUP } ; DIG 2 ; CAR ; CAR } ;
PAIR ;
DIP { DIP { DUP } ; SWAP ; CDR ; CAR ; CHAIN_ID ; SWAP ; PAIR } ;
PAIR ;
PACK ;
PUSH nat 0 ;
DIP 3 { DUP } ;
DIG 3 ;
CAR ;
CAR ;
DIP 5 { DUP } ;
DIG 5 ;
CDR ;
DIP { DUP ; DIP { DIP { DUP } ; SWAP } ; PAIR } ;
ITER { SWAP ;
PAIR ;
DUP ;
CAR ;
DIP { DUP } ;
SWAP ;
CDR ;
DIP { DUP } ;
SWAP ;
CAR ;
IF_CONS
{ DIP { DUP } ;
SWAP ;
DIP { DIP 3 { DUP } ; DIG 3 ; CDR } ;
PAIR ;
DIP 4 { DROP } ;
DUG 3 ;
DIP 2 { DUP } ;
DIG 2 ;
CAR ;
DIP { DUP ; HASH_KEY } ;
COMPARE ;
EQ ;
IF { DUP ;
DIP { DIP 2 { DUP } ; DIG 2 ; CDR ; DIP { DIP 7 { DUP } ; DIG 7 } } ;
CHECK_SIGNATURE ;
IF { DIP 3 { DUP } ;
DIG 3 ;
CDR ;
PUSH nat 1 ;
ADD ;
DIP { DIP 3 { DUP } ; DIG 3 ; CAR } ;
SWAP ;
PAIR ;
DIP 4 { DROP } ;
DUG 3 ;
PUSH unit Unit }
{ PUSH string "Invalid signature" ; FAILWITH } }
{ PUSH unit Unit } ;
DIP { DROP 2 } }
{ PUSH unit Unit } ;
DROP ;
DIP { DUP } ;
SWAP ;
DIP { DROP 3 } } ;
DUP ;
CAR ;
DIP { DIP { DUP } ; SWAP ; DROP } ;
SWAP ;
DIP { DIP { DROP } } ;
DUP ;
CDR ;
DIP { DIP 2 { DUP } ; DIG 2 ; DROP } ;
DIP 3 { DROP } ;
DUG 2 ;
DROP ;
DIP { DUP } ;
SWAP ;
DIP { DIP 4 { DUP } ; DIG 4 ; CDR ; CDR } ;
COMPARE ;
LT ;
IF { PUSH string "Not enough signatures passed the check" ; FAILWITH }
{ DIP 4 { DUP } ;
DIG 4 ;
CAR ;
CDR ;
PUSH nat 1 ;
ADD ;
DIP { DIP 4 { DUP } ; DIG 4 ; DUP ; CDR ; SWAP ; CAR ; CAR } ;
SWAP ;
PAIR ;
PAIR ;
DIP 5 { DROP } ;
DUG 4 ;
PUSH unit Unit } ;
DIP { DROP 3 } } ;
DROP ;
DUP ;
UNIT ;
EXEC ;
DIP { DIP { DUP } ; SWAP } ;
PAIR ;
DIP { DROP 4 } } ;
SWAP ;
CAR ;
DIP 2 { DUP } ;
DIG 2 ;
CDR ;
DIP { DUP } ;
SWAP ;
DUP ;
DIP { DIP { DUP } ; SWAP } ;
PAIR ;
DIP { DIP 3 { DUP } ; DIG 3 } ;
EXEC ;
DIP { DROP 5 } } } |} ]
let%expect_test _ =
run_ligo_good [ "compile-contract" ; contract "multisig-v2.ligo" ; "main" ] ;
[%expect {|
{ parameter (lambda unit (list operation)) ;
storage
(pair (pair (set %auth address) (big_map %message_store bytes (set address)))
(nat %threshold)) ;
code { DUP ;
LAMBDA
(pair (lambda unit (list operation))
(pair (pair (set %auth address) (big_map %message_store bytes (set address)))
(nat %threshold)))
(pair (list operation)
(pair (pair (set %auth address) (big_map %message_store bytes (set address)))
(nat %threshold)))
{ DUP ;
CAR ;
DIP { DUP } ;
SWAP ;
CDR ;
DUP ;
CAR ;
CAR ;
SENDER ;
MEM ;
NOT ;
IF { PUSH string "Unauthorized address" ; FAILWITH } { PUSH unit Unit } ;
DROP ;
DIP { DUP } ;
SWAP ;
DUP ;
PACK ;
DUP ;
NIL operation ;
SWAP ;
DIP { DIP 3 { DUP } ; DIG 3 ; CAR ; CDR } ;
GET ;
IF_NONE
{ EMPTY_SET address }
{ DUP ; PUSH bool True ; SENDER ; UPDATE ; DIP { DROP } } ;
DUP ;
SIZE ;
DIP { DIP 4 { DUP } ; DIG 4 ; CDR } ;
COMPARE ;
GE ;
IF { DIP 2 { DUP } ;
DIG 2 ;
DIP { DIP 4 { DUP } ; DIG 4 ; CAR ; CDR ; NONE (set address) } ;
UPDATE ;
DIP { DIP 4 { DUP } ; DIG 4 ; DUP ; CDR ; SWAP ; CAR ; CAR } ;
SWAP ;
PAIR ;
PAIR ;
DIP 5 { DROP } ;
DUG 4 ;
DIP 3 { DUP } ;
DIG 3 ;
UNIT ;
EXEC ;
DIP { DIP { DUP } ; SWAP ; DROP } ;
SWAP ;
DIP { DIP { DROP } } ;
PUSH unit Unit }
{ DIP 2 { DUP } ;
DIG 2 ;
DIP { DUP ; SOME ; DIP { DIP 4 { DUP } ; DIG 4 ; CAR ; CDR } } ;
UPDATE ;
DIP { DIP 4 { DUP } ; DIG 4 ; DUP ; CDR ; SWAP ; CAR ; CAR } ;
SWAP ;
PAIR ;
PAIR ;
DIP 5 { DROP } ;
DUG 4 ;
PUSH unit Unit } ;
DROP ;
DIP { DUP } ;
SWAP ;
DIP { DIP 4 { DUP } ; DIG 4 } ;
PAIR ;
DIP { DROP 7 } } ;
SWAP ;
CAR ;
DIP 2 { DUP } ;
DIG 2 ;
CDR ;
DIP { DUP } ;
SWAP ;
DUP ;
DIP { DIP { DUP } ; SWAP } ;
PAIR ;
DIP { DIP 3 { DUP } ; DIG 3 } ;
EXEC ;
DIP { DROP 5 } } } |} ]
let%expect_test _ =
run_ligo_good [ "compile-contract" ; contract "vote.mligo" ; "main" ] ;
[%expect {|
{ parameter
(or (pair %init
(pair (timestamp %beginning_time) (timestamp %finish_time))
(string %title))
(string %vote)) ;
storage
(pair (pair (pair (timestamp %beginning_time) (map %candidates string int))
(pair (timestamp %finish_time) (string %title)))
(set %voters address)) ;
code { LAMBDA
(pair (pair (pair (timestamp %beginning_time) (timestamp %finish_time)) (string %title))
(pair (pair (pair (timestamp %beginning_time) (map %candidates string int))
(pair (timestamp %finish_time) (string %title)))
(set %voters address)))
(pair (list operation)
(pair (pair (pair (timestamp %beginning_time) (map %candidates string int))
(pair (timestamp %finish_time) (string %title)))
(set %voters address)))
{ DUP ;
CAR ;
PUSH int 0 ;
SOME ;
DIP { PUSH int 0 ;
SOME ;
EMPTY_MAP string int ;
SWAP ;
PUSH string "Yes" ;
UPDATE } ;
PUSH string "No" ;
UPDATE ;
DIP { DUP } ;
SWAP ;
CAR ;
CAR ;
DIP { DUP } ;
PAIR ;
DIP { DIP { DUP } ;
SWAP ;
CAR ;
CDR ;
DIP { DIP { DUP } ; SWAP ; CDR } ;
PAIR } ;
PAIR ;
EMPTY_SET address ;
SWAP ;
PAIR ;
NIL operation ;
PAIR ;
DIP { DROP 3 } } ;
LAMBDA
(pair string
(pair (pair (pair (timestamp %beginning_time) (map %candidates string int))
(pair (timestamp %finish_time) (string %title)))
(set %voters address)))
(pair (list operation)
(pair (pair (pair (timestamp %beginning_time) (map %candidates string int))
(pair (timestamp %finish_time) (string %title)))
(set %voters address)))
{ DUP ;
CAR ;
DIP { DUP } ;
SWAP ;
CDR ;
NOW ;
SOURCE ;
DIP 3 { DUP } ;
DIG 3 ;
DIP { DIP 2 { DUP } ; DIG 2 ; CAR ; CAR ; CDR } ;
GET ;
IF_NONE { PUSH string "MAP FIND" ; FAILWITH } {} ;
DIP 3 { DUP } ;
DIG 3 ;
CAR ;
CAR ;
CAR ;
DIP { DIP 4 { DUP } ;
DIG 4 ;
DIP { DUP ;
PUSH int 1 ;
ADD ;
SOME ;
DIP { DIP 3 { DUP } ; DIG 3 ; CAR ; CAR ; CDR } } ;
UPDATE } ;
PAIR ;
DIP { DIP 3 { DUP } ;
DIG 3 ;
CAR ;
CDR ;
CAR ;
DIP { DIP 3 { DUP } ; DIG 3 ; CAR ; CDR ; CDR } ;
PAIR } ;
PAIR ;
DIP { DIP { DUP } ;
SWAP ;
DIP { DIP 3 { DUP } ; DIG 3 ; CDR ; PUSH bool True } ;
UPDATE } ;
PAIR ;
NIL operation ;
PAIR ;
DIP { DROP 6 } } ;
DIP 2 { DUP } ;
DIG 2 ;
CAR ;
DIP 3 { DUP } ;
DIG 3 ;
CDR ;
DIP { DUP } ;
SWAP ;
IF_LEFT
{ DUP ;
DUP ;
DIP { DIP 2 { DUP } ; DIG 2 } ;
PAIR ;
DIP { DIP 5 { DUP } ; DIG 5 } ;
EXEC ;
DIP { DROP 2 } }
{ DUP ;
DUP ;
DIP { DIP 2 { DUP } ; DIG 2 } ;
PAIR ;
DIP { DIP 4 { DUP } ; DIG 4 } ;
EXEC ;
DIP { DROP 2 } } ;
DIP { DROP 5 } } } |}]

View File

@ -48,6 +48,10 @@ let%expect_test _ =
dry-run dry-run
COMMANDS
measure-contract
Subcommand: measure a contract's compiled size in bytes.
OPTIONS OPTIONS
--help[=FMT] (default=auto) --help[=FMT] (default=auto)
Show this help in format FMT. The value FMT must be one of `auto', Show this help in format FMT. The value FMT must be one of `auto',

View File

@ -106,3 +106,8 @@ let pp_hex ppf (michelson : michelson) =
let bytes = Tezos_data_encoding.Binary_writer.to_bytes_exn Script_repr.expr_encoding canonical in let bytes = Tezos_data_encoding.Binary_writer.to_bytes_exn Script_repr.expr_encoding canonical in
let hex = Hex.of_bytes bytes in let hex = Hex.of_bytes bytes in
Format.fprintf ppf "%a" Hex.pp hex Format.fprintf ppf "%a" Hex.pp hex
let measure (michelson : michelson) =
let canonical = strip_locations michelson in
let bytes = Tezos_data_encoding.Binary_writer.to_bytes_exn Script_repr.expr_encoding canonical in
Bytes.length bytes