ligo/src/proto_alpha/lib_client/client_proto_programs.ml

169 lines
6.3 KiB
OCaml
Raw Normal View History

2016-09-08 21:13:10 +04:00
(**************************************************************************)
(* *)
2018-02-06 00:17:03 +04:00
(* Copyright (c) 2014 - 2018. *)
2016-09-08 21:13:10 +04:00
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* *)
(* All rights reserved. No warranty, explicit or implicit, provided. *)
(* *)
(**************************************************************************)
open Proto_alpha
open Alpha_context
open Tezos_micheline
open Michelson_v1_printer
2016-09-08 21:13:10 +04:00
module Program = Client_aliases.Alias (struct
type t = Michelson_v1_parser.parsed Micheline_parser.parsing_result
2017-07-22 02:37:33 +04:00
let encoding =
Data_encoding.conv
(fun ({ Michelson_v1_parser.source }, _) -> source)
(fun source -> Michelson_v1_parser.parse_toplevel source)
Data_encoding.string
2017-12-05 18:09:36 +04:00
let of_source source =
return (Michelson_v1_parser.parse_toplevel source)
2017-12-05 18:09:36 +04:00
let to_source ({ Michelson_v1_parser.source }, _) = return source
2016-09-08 21:13:10 +04:00
let name = "program"
end)
let print_errors (cctxt : #Client_context.printer) errs ~show_source ~parsed =
2017-11-07 20:38:11 +04:00
cctxt#warning "%a"
(Michelson_v1_error_reporter.report_errors
~details:false
~show_source
~parsed) errs >>= fun () ->
cctxt#error "error running program" >>= fun () ->
return ()
let print_big_map_diff ppf = function
| None -> ()
| Some diff ->
Format.fprintf ppf
"@[<v 2>map diff:@,%a@]@,"
(Format.pp_print_list
~pp_sep:Format.pp_print_space
(fun ppf (key, value) ->
Format.fprintf ppf "%s %s%a"
(match value with
| None -> "-"
| Some _ -> "+")
key
(fun ppf -> function
| None -> ()
| Some x -> Format.fprintf ppf "-> %a" print_expr x)
value))
diff
let print_run_result (cctxt : #Client_context.printer) ~show_source ~parsed = function
| Ok (storage, operations, maybe_diff) ->
cctxt#message "@[<v 0>@[<v 2>storage@,%a@]@,@[<v 2>emitted operations@,%a@]@,@[%a@]@]@."
2017-11-07 20:38:11 +04:00
print_expr storage
(Format.pp_print_list Operation_result.pp_internal_operation) operations
print_big_map_diff maybe_diff >>= fun () ->
2017-11-07 20:38:11 +04:00
return ()
| Error errs ->
print_errors cctxt errs ~show_source ~parsed
let print_trace_result (cctxt : #Client_context.printer) ~show_source ~parsed =
2017-11-07 20:38:11 +04:00
function
| Ok (storage, operations, trace, maybe_big_map_diff) ->
2017-11-07 20:38:11 +04:00
cctxt#message
"@[<v 0>@[<v 2>storage@,%a@]@,\
@[<v 2>emitted operations@,%a@]@,%a@[<v 2>@[<v 2>trace@,%a@]@]@."
2017-11-07 20:38:11 +04:00
print_expr storage
(Format.pp_print_list Operation_result.pp_internal_operation) operations
print_big_map_diff maybe_big_map_diff
2017-11-07 20:38:11 +04:00
(Format.pp_print_list
(fun ppf (loc, gas, stack) ->
Format.fprintf ppf
"- @[<v 0>location: %d (remaining gas: %a)@,\
2017-11-07 20:38:11 +04:00
[ @[<v 0>%a ]@]@]"
loc Gas.pp gas
2017-11-07 20:38:11 +04:00
(Format.pp_print_list print_expr)
stack))
trace >>= fun () ->
return ()
| Error errs ->
print_errors cctxt errs ~show_source ~parsed
let get_contract cctxt block contract =
match contract with
| Some contract -> return contract
| None ->
(* TODO use local contract by default *)
Alpha_services.Contract.list cctxt block >>|? List.hd
2017-11-07 20:38:11 +04:00
let run
?contract
?(amount = Tez.fifty_cents)
2017-11-07 20:38:11 +04:00
~(program : Michelson_v1_parser.parsed)
~(storage : Michelson_v1_parser.parsed)
~(input : Michelson_v1_parser.parsed)
block
(cctxt : #RPC_context.simple) =
get_contract cctxt block contract >>=? fun contract ->
Alpha_services.Helpers.run_code cctxt
block program.expanded (storage.expanded, input.expanded, amount, contract)
2017-11-07 20:38:11 +04:00
let trace
?contract
?(amount = Tez.fifty_cents)
2017-11-07 20:38:11 +04:00
~(program : Michelson_v1_parser.parsed)
~(storage : Michelson_v1_parser.parsed)
~(input : Michelson_v1_parser.parsed)
block
(cctxt : #RPC_context.simple) =
get_contract cctxt block contract >>=? fun contract ->
Alpha_services.Helpers.trace_code cctxt
block program.expanded (storage.expanded, input.expanded, amount, contract)
2017-11-07 20:38:11 +04:00
2018-02-10 07:28:32 +04:00
let hash_and_sign ?gas (data : Michelson_v1_parser.parsed) (typ : Michelson_v1_parser.parsed) sk block cctxt =
Alpha_services.Helpers.hash_data cctxt block (data.expanded, typ.expanded, gas) >>=? fun (hash, gas) ->
Client_keys.sign sk (MBytes.of_string hash) >>=? fun signature ->
return (hash, Signature.to_b58check signature, gas)
2017-11-07 20:38:11 +04:00
let typecheck_data
2018-02-10 07:28:32 +04:00
?gas
2017-11-07 20:38:11 +04:00
~(data : Michelson_v1_parser.parsed)
~(ty : Michelson_v1_parser.parsed)
block cctxt =
2018-02-10 07:28:32 +04:00
Alpha_services.Helpers.typecheck_data cctxt block (data.expanded, ty.expanded, gas)
2017-11-07 20:38:11 +04:00
2018-02-10 07:28:32 +04:00
let typecheck_program ?gas (program : Michelson_v1_parser.parsed) block cctxt =
Alpha_services.Helpers.typecheck_code cctxt block (program.expanded, gas)
2017-11-07 20:38:11 +04:00
let print_typecheck_result
~emacs ~show_types ~print_source_on_error
program res (cctxt : #Client_context.printer) =
2017-11-07 20:38:11 +04:00
if emacs then
2018-02-10 07:28:32 +04:00
let type_map, errs, _gas = match res with
| Ok (type_map, gas) -> (type_map, [], Some gas)
| Error (Alpha_environment.Ecoproto_error
(Script_tc_errors.Ill_typed_contract (_, type_map ))
2017-11-07 20:38:11 +04:00
:: _ as errs) ->
2018-02-10 07:28:32 +04:00
(type_map, errs, None)
2017-11-07 20:38:11 +04:00
| Error errs ->
2018-02-10 07:28:32 +04:00
([], errs, None) in
2017-11-07 20:38:11 +04:00
cctxt#message
"(@[<v 0>(types . %a)@ (errors . %a)@])"
Michelson_v1_emacs.print_type_map (program, type_map)
Michelson_v1_emacs.report_errors (program, errs) >>= fun () ->
return ()
else
match res with
2018-02-10 07:28:32 +04:00
| Ok (type_map, gas) ->
2017-11-07 20:38:11 +04:00
let program = Michelson_v1_printer.inject_types type_map program in
cctxt#message "@[<v 0>Well typed@,Gas remaining: %a@]"
2018-02-10 07:28:32 +04:00
Gas.pp gas >>= fun () ->
2017-11-07 20:38:11 +04:00
if show_types then
cctxt#message "%a" Micheline_printer.print_expr program >>= fun () ->
return ()
else return ()
| Error errs ->
cctxt#warning "%a"
(Michelson_v1_error_reporter.report_errors
~details: show_types
~show_source:print_source_on_error
~parsed:program) errs >>= fun () ->
cctxt#error "ill-typed program"