diff --git a/src/bin/cli.ml b/src/bin/cli.ml index f9b6321e5..1ad68d049 100644 --- a/src/bin/cli.ml +++ b/src/bin/cli.ml @@ -66,10 +66,18 @@ let amount = let open Arg in let info = let docv = "AMOUNT" in - let doc = "$(docv) is the amount the Michelson interpreter will use." in + let doc = "$(docv) is the amount the Michelson interpreter will use for the transaction." in info ~docv ~doc ["amount"] in value @@ opt string "0" info +let balance = + let open Arg in + let info = + let docv = "BALANCE" in + let doc = "$(docv) is the balance the Michelson interpreter will use for the contract balance." in + info ~docv ~doc ["balance"] in + value @@ opt string "0" info + let sender = let open Arg in let info = @@ -207,7 +215,7 @@ let measure_contract = (Term.ret term , Term.info ~doc cmdname) let compile_parameter = - let f source_file entry_point expression syntax amount sender source predecessor_timestamp display_format michelson_format = + let f source_file entry_point expression syntax amount balance sender source predecessor_timestamp display_format michelson_format = toplevel ~display_format @@ let%bind simplified = Compile.Of_source.compile source_file (Syntax_name syntax) in let%bind typed_prg,state = Compile.Of_simplified.compile simplified in @@ -225,18 +233,18 @@ let compile_parameter = let%bind compiled_param = Compile.Of_mini_c.aggregate_and_compile_expression mini_c_prg mini_c_param in let%bind () = Compile.Of_typed.assert_equal_contract_type Check_parameter entry_point typed_prg typed_param in let%bind () = Compile.Of_michelson.assert_equal_contract_type Check_parameter michelson_prg compiled_param in - let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; sender ; source } in + let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in let%bind value = Run.evaluate_expression ~options compiled_param.expr compiled_param.expr_ty in ok @@ Format.asprintf "%a\n" (Main.Display.michelson_pp michelson_format) value in let term = - Term.(const f $ source_file 0 $ entry_point 1 $ expression "PARAMETER" 2 $ syntax $ amount $ sender $ source $ predecessor_timestamp $ display_format $ michelson_code_format) in + Term.(const f $ source_file 0 $ entry_point 1 $ expression "PARAMETER" 2 $ syntax $ amount $ balance $ sender $ source $ predecessor_timestamp $ display_format $ michelson_code_format) in let cmdname = "compile-parameter" in let doc = "Subcommand: Compile parameters to a Michelson expression. The resulting Michelson expression can be passed as an argument in a transaction which calls a contract." in (Term.ret term , Term.info ~doc cmdname) let interpret = - let f expression init_file syntax amount sender source predecessor_timestamp display_format = + let f expression init_file syntax amount balance sender source predecessor_timestamp display_format = toplevel ~display_format @@ let%bind (decl_list,state,env) = match init_file with | Some init_file -> @@ -252,7 +260,7 @@ let interpret = let%bind (typed_exp,_) = Compile.Of_simplified.compile_expression ~env ~state simplified_exp in let%bind mini_c_exp = Compile.Of_typed.compile_expression typed_exp in let%bind compiled_exp = Compile.Of_mini_c.aggregate_and_compile_expression decl_list mini_c_exp in - let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; sender ; source } in + let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in let%bind runres = Run.run_expression ~options compiled_exp.expr compiled_exp.expr_ty in match runres with | Fail fail_res -> @@ -263,7 +271,7 @@ let interpret = ok @@ Format.asprintf "%a\n" Ast_simplified.PP.expression simplified_output in let term = - Term.(const f $ expression "EXPRESSION" 0 $ init_file $ syntax $ amount $ sender $ source $ predecessor_timestamp $ display_format ) in + Term.(const f $ expression "EXPRESSION" 0 $ init_file $ syntax $ amount $ balance $ sender $ source $ predecessor_timestamp $ display_format ) in let cmdname = "interpret" in let doc = "Subcommand: Interpret the expression in the context initialized by the provided source file." in (Term.ret term , Term.info ~doc cmdname) @@ -283,7 +291,7 @@ let temp_ligo_interpreter = (Term.ret term , Term.info ~doc cmdname) let compile_storage = - let f source_file entry_point expression syntax amount sender source predecessor_timestamp display_format michelson_format = + let f source_file entry_point expression syntax amount balance sender source predecessor_timestamp display_format michelson_format = toplevel ~display_format @@ let%bind simplified = Compile.Of_source.compile source_file (Syntax_name syntax) in let%bind typed_prg,state = Compile.Of_simplified.compile simplified in @@ -301,18 +309,18 @@ let compile_storage = let%bind compiled_param = Compile.Of_mini_c.aggregate_and_compile_expression mini_c_prg mini_c_param in let%bind () = Compile.Of_typed.assert_equal_contract_type Check_storage entry_point typed_prg typed_param in let%bind () = Compile.Of_michelson.assert_equal_contract_type Check_storage michelson_prg compiled_param in - let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; sender ; source } in + let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in let%bind value = Run.evaluate_expression ~options compiled_param.expr compiled_param.expr_ty in ok @@ Format.asprintf "%a\n" (Main.Display.michelson_pp michelson_format) value in let term = - Term.(const f $ source_file 0 $ entry_point 1 $ expression "STORAGE" 2 $ syntax $ amount $ sender $ source $ predecessor_timestamp $ display_format $ michelson_code_format) in + Term.(const f $ source_file 0 $ entry_point 1 $ expression "STORAGE" 2 $ syntax $ amount $ balance $ sender $ source $ predecessor_timestamp $ display_format $ michelson_code_format) in let cmdname = "compile-storage" in let doc = "Subcommand: Compile an initial storage in ligo syntax to a Michelson expression. The resulting Michelson expression can be passed as an argument in a transaction which originates a contract." in (Term.ret term , Term.info ~doc cmdname) let dry_run = - let f source_file entry_point storage input amount sender source predecessor_timestamp syntax display_format = + let f source_file entry_point storage input amount balance sender source predecessor_timestamp syntax display_format = toplevel ~display_format @@ let%bind simplified = Compile.Of_source.compile source_file (Syntax_name syntax) in let%bind typed_prg,state = Compile.Of_simplified.compile simplified in @@ -330,7 +338,7 @@ let dry_run = let%bind compiled_params = Compile.Of_mini_c.aggregate_and_compile_expression mini_c_prg mini_c in let%bind args_michelson = Run.evaluate_expression compiled_params.expr compiled_params.expr_ty in - let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; sender ; source } in + let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in let%bind runres = Run.run_contract ~options michelson_prg.expr michelson_prg.expr_ty args_michelson in match runres with | Fail fail_res -> @@ -341,13 +349,13 @@ let dry_run = ok @@ Format.asprintf "%a\n" Ast_simplified.PP.expression simplified_output in let term = - Term.(const f $ source_file 0 $ entry_point 1 $ expression "PARAMETER" 2 $ expression "STORAGE" 3 $ amount $ sender $ source $ predecessor_timestamp $ syntax $ display_format) in + Term.(const f $ source_file 0 $ entry_point 1 $ expression "PARAMETER" 2 $ expression "STORAGE" 3 $ amount $ balance $ sender $ source $ predecessor_timestamp $ syntax $ display_format) in let cmdname = "dry-run" in let doc = "Subcommand: Run a smart-contract with the given storage and input." in (Term.ret term , Term.info ~doc cmdname) let run_function = - let f source_file entry_point parameter amount sender source predecessor_timestamp syntax display_format = + let f source_file entry_point parameter amount balance sender source predecessor_timestamp syntax display_format = toplevel ~display_format @@ let%bind v_syntax = Helpers.syntax_to_variant (Syntax_name syntax) (Some source_file) in let%bind simplified_prg = Compile.Of_source.compile source_file (Syntax_name syntax) in @@ -362,7 +370,7 @@ let run_function = let%bind compiled_applied = Compile.Of_typed.compile_expression typed_app in let%bind michelson = Compile.Of_mini_c.aggregate_and_compile_expression mini_c_prg compiled_applied in - let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; sender ; source } in + let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in let%bind runres = Run.run_expression ~options michelson.expr michelson.expr_ty in match runres with | Fail fail_res -> @@ -373,26 +381,26 @@ let run_function = ok @@ Format.asprintf "%a\n" Ast_simplified.PP.expression simplified_output in let term = - Term.(const f $ source_file 0 $ entry_point 1 $ expression "PARAMETER" 2 $ amount $ sender $ source $ predecessor_timestamp $ syntax $ display_format) in + Term.(const f $ source_file 0 $ entry_point 1 $ expression "PARAMETER" 2 $ amount $ balance $ sender $ source $ predecessor_timestamp $ syntax $ display_format) in let cmdname = "run-function" in let doc = "Subcommand: Run a function with the given parameter." in (Term.ret term , Term.info ~doc cmdname) let evaluate_value = - let f source_file entry_point amount sender source predecessor_timestamp syntax display_format = + let f source_file entry_point amount balance sender source predecessor_timestamp syntax display_format = toplevel ~display_format @@ let%bind simplified = Compile.Of_source.compile source_file (Syntax_name syntax) in let%bind typed_prg,_ = Compile.Of_simplified.compile simplified in let%bind mini_c = Compile.Of_typed.compile typed_prg in let%bind (exp,_) = Mini_c.get_entry mini_c entry_point in let%bind compiled = Compile.Of_mini_c.aggregate_and_compile_expression mini_c exp in - let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; sender ; source } in + let%bind options = Run.make_dry_run_options {predecessor_timestamp ; amount ; balance ; sender ; source } in let%bind michelson_output = Run.run_no_failwith ~options compiled.expr compiled.expr_ty in let%bind simplified_output = Uncompile.uncompile_typed_program_entry_expression_result typed_prg entry_point michelson_output in ok @@ Format.asprintf "%a\n" Ast_simplified.PP.expression simplified_output in let term = - Term.(const f $ source_file 0 $ entry_point 1 $ amount $ sender $ source $ predecessor_timestamp $ syntax $ display_format) in + Term.(const f $ source_file 0 $ entry_point 1 $ amount $ balance $ sender $ source $ predecessor_timestamp $ syntax $ display_format) in let cmdname = "evaluate-value" in let doc = "Subcommand: Evaluate a given definition." in (Term.ret term , Term.info ~doc cmdname) diff --git a/src/bin/expect_tests/help_tests.ml b/src/bin/expect_tests/help_tests.ml index bd5824881..f13b5c078 100644 --- a/src/bin/expect_tests/help_tests.ml +++ b/src/bin/expect_tests/help_tests.ml @@ -226,7 +226,12 @@ let%expect_test _ = OPTIONS --amount=AMOUNT (absent=0) - AMOUNT is the amount the Michelson interpreter will use. + AMOUNT is the amount the Michelson interpreter will use for the + transaction. + + --balance=BALANCE (absent=0) + BALANCE is the balance the Michelson interpreter will use for the + contract balance. --format=DISPLAY_FORMAT, --display-format=DISPLAY_FORMAT (absent=human-readable) @@ -292,7 +297,12 @@ let%expect_test _ = OPTIONS --amount=AMOUNT (absent=0) - AMOUNT is the amount the Michelson interpreter will use. + AMOUNT is the amount the Michelson interpreter will use for the + transaction. + + --balance=BALANCE (absent=0) + BALANCE is the balance the Michelson interpreter will use for the + contract balance. --format=DISPLAY_FORMAT, --display-format=DISPLAY_FORMAT (absent=human-readable) @@ -359,7 +369,12 @@ let%expect_test _ = OPTIONS --amount=AMOUNT (absent=0) - AMOUNT is the amount the Michelson interpreter will use. + AMOUNT is the amount the Michelson interpreter will use for the + transaction. + + --balance=BALANCE (absent=0) + BALANCE is the balance the Michelson interpreter will use for the + contract balance. --format=DISPLAY_FORMAT, --display-format=DISPLAY_FORMAT (absent=human-readable) @@ -418,7 +433,12 @@ let%expect_test _ = OPTIONS --amount=AMOUNT (absent=0) - AMOUNT is the amount the Michelson interpreter will use. + AMOUNT is the amount the Michelson interpreter will use for the + transaction. + + --balance=BALANCE (absent=0) + BALANCE is the balance the Michelson interpreter will use for the + contract balance. --format=DISPLAY_FORMAT, --display-format=DISPLAY_FORMAT (absent=human-readable) @@ -472,7 +492,12 @@ let%expect_test _ = OPTIONS --amount=AMOUNT (absent=0) - AMOUNT is the amount the Michelson interpreter will use. + AMOUNT is the amount the Michelson interpreter will use for the + transaction. + + --balance=BALANCE (absent=0) + BALANCE is the balance the Michelson interpreter will use for the + contract balance. --format=DISPLAY_FORMAT, --display-format=DISPLAY_FORMAT (absent=human-readable) diff --git a/src/main/run/of_michelson.ml b/src/main/run/of_michelson.ml index 6e8733e0e..02e884840 100644 --- a/src/main/run/of_michelson.ml +++ b/src/main/run/of_michelson.ml @@ -31,6 +31,7 @@ type run_res = type dry_run_options = { amount : string ; + balance : string ; predecessor_timestamp : string option ; sender : string option ; source : string option } @@ -47,6 +48,9 @@ let make_dry_run_options (opts : dry_run_options) : options result = let open Proto_alpha_utils.Trace in let open Proto_alpha_utils.Memory_proto_alpha in let open Protocol.Alpha_context in + let%bind balance = match Tez.of_string opts.balance with + | None -> simple_fail "invalid amount" + | Some balance -> ok balance in let%bind amount = match Tez.of_string opts.amount with | None -> simple_fail "invalid amount" | Some amount -> ok amount in @@ -75,7 +79,7 @@ let make_dry_run_options (opts : dry_run_options) : options result = match Memory_proto_alpha.Protocol.Alpha_context.Timestamp.of_notation st with | Some t -> ok (Some t) | None -> simple_fail ("\""^st^"\" is a bad timestamp notation") in - ok @@ make_options ?predecessor_timestamp:predecessor_timestamp ~amount ?sender ?source () + ok @@ make_options ?predecessor_timestamp:predecessor_timestamp ~amount ~balance ?sender ?source () let ex_value_ty_to_michelson (v : ex_typed_value) : Michelson.t result = let (Ex_typed_value (value , ty)) = v in diff --git a/src/test/integration_tests.ml b/src/test/integration_tests.ml index 2ad0dfc8f..e6de67651 100644 --- a/src/test/integration_tests.ml +++ b/src/test/integration_tests.ml @@ -1786,24 +1786,33 @@ let religo_let_multiple () : unit result = in ok () + +let balance_test_options () = + let%bind balance = trace_option (simple_error "could not convert balance") @@ + Memory_proto_alpha.Protocol.Alpha_context.Tez.of_string "4000000" in + ok @@ Proto_alpha_utils.Memory_proto_alpha.make_options ~balance () + let balance_constant () : unit result = let%bind program = type_file "./contracts/balance_constant.ligo" in let input = e_tuple [e_unit () ; e_mutez 0] in let expected = e_tuple [e_list []; e_mutez 4000000000000] in - expect_eq program "main" input expected + let%bind options = balance_test_options () in + expect_eq ~options program "main" input expected let balance_constant_mligo () : unit result = let%bind program = mtype_file "./contracts/balance_constant.mligo" in let input = e_tuple [e_unit () ; e_mutez 0] in let expected = e_tuple [e_list []; e_mutez 4000000000000] in - expect_eq program "main" input expected + let%bind options = balance_test_options () in + expect_eq ~options program "main" input expected let balance_constant_religo () : unit result = let%bind program = retype_file "./contracts/balance_constant.religo" in let input = e_tuple [e_unit () ; e_mutez 0] in let expected = e_tuple [e_list []; e_mutez 4000000000000] in - expect_eq program "main" input expected + let%bind options = balance_test_options () in + expect_eq ~options program "main" input expected let amount () : unit result = let%bind program = type_file "./contracts/amount.ligo" in diff --git a/vendors/ligo-utils/proto-alpha-utils/x_memory_proto_alpha.ml b/vendors/ligo-utils/proto-alpha-utils/x_memory_proto_alpha.ml index d5d1b3ab7..863d19a62 100644 --- a/vendors/ligo-utils/proto-alpha-utils/x_memory_proto_alpha.ml +++ b/vendors/ligo-utils/proto-alpha-utils/x_memory_proto_alpha.ml @@ -1071,10 +1071,18 @@ let make_options ?(self = (List.nth dummy_environment.identities 0).implicit_contract) ?(source = (List.nth dummy_environment.identities 1).implicit_contract) ?(amount = Alpha_context.Tez.one) + ?(balance = Alpha_context.Tez.zero) ?(chain_id = Environment.Chain_id.zero) () = let tezos_context = { tezos_context with predecessor_timestamp } in + let tezos_context_error = + Trace.trace_alpha_tzresult_lwt (Trace.simple_error "lol") @@ + Alpha_context.Contract.set_balance tezos_context self balance + in + let tezos_context = match tezos_context_error with + | Ok (a,_) -> a + | Error _ -> tezos_context in { tezos_context ; (* yep *) diff --git a/vendors/ligo-utils/tezos-protocol-alpha/alpha_context.ml b/vendors/ligo-utils/tezos-protocol-alpha/alpha_context.ml index 5eaf19850..16ed177b8 100644 --- a/vendors/ligo-utils/tezos-protocol-alpha/alpha_context.ml +++ b/vendors/ligo-utils/tezos-protocol-alpha/alpha_context.ml @@ -158,8 +158,10 @@ module Contract = struct let init_origination_nonce = Raw_context.init_origination_nonce let unset_origination_nonce = Raw_context.unset_origination_nonce + let set_balance = Contract_storage.set_balance end + module Big_map = struct type id = Z.t diff --git a/vendors/ligo-utils/tezos-protocol-alpha/alpha_context.mli b/vendors/ligo-utils/tezos-protocol-alpha/alpha_context.mli index 17e32aa76..df38cd83e 100644 --- a/vendors/ligo-utils/tezos-protocol-alpha/alpha_context.mli +++ b/vendors/ligo-utils/tezos-protocol-alpha/alpha_context.mli @@ -706,6 +706,9 @@ module Contract : sig include BASIC_DATA type contract = t + + val set_balance : context -> + contract -> Tez.t -> context tzresult Lwt.t val rpc_arg : contract RPC_arg.arg diff --git a/vendors/ligo-utils/tezos-protocol-alpha/contract_storage.ml b/vendors/ligo-utils/tezos-protocol-alpha/contract_storage.ml index c63a9f283..ddc913b4a 100644 --- a/vendors/ligo-utils/tezos-protocol-alpha/contract_storage.ml +++ b/vendors/ligo-utils/tezos-protocol-alpha/contract_storage.ml @@ -23,6 +23,8 @@ (* *) (*****************************************************************************) +let set_balance = Storage.Contract.Balance.set + type error += | Balance_too_low of Contract_repr.contract * Tez_repr.t * Tez_repr.t | (* `Temporary *) diff --git a/vendors/ligo-utils/tezos-protocol-alpha/contract_storage.mli b/vendors/ligo-utils/tezos-protocol-alpha/contract_storage.mli index 450b58ac1..e9277bb5d 100644 --- a/vendors/ligo-utils/tezos-protocol-alpha/contract_storage.mli +++ b/vendors/ligo-utils/tezos-protocol-alpha/contract_storage.mli @@ -23,6 +23,9 @@ (* *) (*****************************************************************************) +val set_balance : Raw_context.t -> +Contract_repr.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t + type error += | Balance_too_low of Contract_repr.contract * Tez_repr.t * Tez_repr.t | (* `Temporary *)