From c2049a3a18d7910cfa34b09665c61bb50fff2f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Henry?= Date: Sat, 24 Nov 2018 01:46:10 +0100 Subject: [PATCH] Client/Alpha: implements `--fee-cap` and `--burn-cap` --- src/bin_client/test/test_basic.sh | 26 +-- src/bin_client/test/test_contracts.sh | 8 +- src/bin_client/test/test_contracts_macros.sh | 42 ++-- .../test/test_contracts_mini_scenarios.sh | 26 +-- src/bin_client/test/test_contracts_opcode.sh | 44 ++-- src/bin_client/test/test_lib.inc.sh | 2 +- src/lib_clic/clic.ml | 30 +++ src/lib_clic/clic.mli | 33 +++ .../lib_client/client_proto_args.ml | 49 ++++- .../lib_client/client_proto_args.mli | 11 +- .../lib_client/client_proto_context.ml | 82 +++++--- .../lib_client/client_proto_context.mli | 18 +- src/proto_alpha/lib_client/injection.ml | 193 +++++++++++++++--- src/proto_alpha/lib_client/injection.mli | 17 +- .../client_proto_context_commands.ml | 165 ++++++++++++--- .../lib_delegate/delegate_commands.ml | 12 +- .../lib_delegate/test/proto_alpha_helpers.ml | 12 +- .../lib_delegate/test/proto_alpha_helpers.mli | 3 + 18 files changed, 602 insertions(+), 171 deletions(-) diff --git a/src/bin_client/test/test_basic.sh b/src/bin_client/test/test_basic.sh index 130c13eac..eaf6342da 100755 --- a/src/bin_client/test/test_basic.sh +++ b/src/bin_client/test/test_basic.sh @@ -37,20 +37,20 @@ $client gen keys $key3 --sig ed25519 $client list known addresses $client get balance for bootstrap1 -bake_after $client transfer 1,000 from bootstrap1 to $key1 -bake_after $client transfer 2,000 from bootstrap1 to $key2 -bake_after $client transfer 3,000 from bootstrap1 to $key3 +bake_after $client transfer 1,000 from bootstrap1 to $key1 --burn-cap 0.257 +bake_after $client transfer 2,000 from bootstrap1 to $key2 --burn-cap 0.257 +bake_after $client transfer 3,000 from bootstrap1 to $key3 --burn-cap 0.257 # bake_after $client transfer 4,000 from bootstrap1 to $key6 $client get balance for $key1 | assert "1000 ꜩ" $client get balance for $key2 | assert "2000 ꜩ" $client get balance for $key3 | assert "3000 ꜩ" -bake_after $client transfer 1,000 from $key2 to $key1 -fee 0 +bake_after $client transfer 1,000 from $key2 to $key1 --fee 0 --force-low-fee $client get balance for $key1 | assert "2000 ꜩ" $client get balance for $key2 | assert "1000 ꜩ" -bake_after $client transfer 1,000 from $key1 to $key2 +bake_after $client transfer 1,000 from $key1 to $key2 --fee 0.05 $client get balance for $key1 | assert "999.95 ꜩ" $client get balance for $key2 | assert "2000 ꜩ" @@ -63,19 +63,19 @@ $client remember script noop file:contracts/opcodes/noop.tz $client typecheck script file:contracts/opcodes/noop.tz bake_after $client originate contract noop \ for $key1 transferring 1,000 from bootstrap1 \ - running file:contracts/opcodes/noop.tz + running file:contracts/opcodes/noop.tz --burn-cap 0.295 -bake_after $client transfer 10 from bootstrap1 to noop -arg "Unit" +bake_after $client transfer 10 from bootstrap1 to noop --arg "Unit" bake_after $client originate contract hardlimit \ for $key1 transferring 1,000 from bootstrap1 \ - running file:contracts/mini_scenarios/hardlimit.tz -init "3" -bake_after $client transfer 10 from bootstrap1 to hardlimit -arg "Unit" -bake_after $client transfer 10 from bootstrap1 to hardlimit -arg "Unit" + running file:contracts/mini_scenarios/hardlimit.tz --init "3" --burn-cap 0.341 +bake_after $client transfer 10 from bootstrap1 to hardlimit --arg "Unit" +bake_after $client transfer 10 from bootstrap1 to hardlimit --arg "Unit" bake_after $client originate account free_account for $key1 \ - transferring 1,000 from bootstrap1 -delegatable + transferring 1,000 from bootstrap1 --delegatable --burn-cap 0.257 $client get delegate for free_account bake_after $client register key $key2 as delegate @@ -83,8 +83,8 @@ bake_after $client set delegate for free_account to $key2 $client get delegate for free_account $client get balance for bootstrap5 | assert "4000000 ꜩ" -bake_after $client transfer 400,000 from bootstrap5 to bootstrap1 -fee 0 -bake_after $client transfer 400,000 from bootstrap1 to bootstrap5 -fee 0 +bake_after $client transfer 400,000 from bootstrap5 to bootstrap1 --fee 0 --force-low-fee +bake_after $client transfer 400,000 from bootstrap1 to bootstrap5 --fee 0 --force-low-fee $client get balance for bootstrap5 | assert "4000000 ꜩ" bake_after $client activate account $key4 with king_commitment.json diff --git a/src/bin_client/test/test_contracts.sh b/src/bin_client/test/test_contracts.sh index 38e4435d5..28ce61827 100755 --- a/src/bin_client/test/test_contracts.sh +++ b/src/bin_client/test/test_contracts.sh @@ -46,7 +46,7 @@ tee /tmp/first_explosion.tz < arg1, arg2, arg3, arg4, arg5, spec6, spec7, spec8, spec9, spec10, spec11 } +let args12 spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12 = + Argument + { spec = spec1 >> (spec2 >> (spec3 >> (spec4 >> (spec5 >> (spec6 >> (spec7 >> (spec8 >> (spec9 >> (spec10 >> (spec11 >> (spec12 >> NoArgs))))))))))) ; + converter = fun (arg1, (arg2, (arg3, (arg4, (arg5, (spec6, (spec7, (spec8, (spec9, (spec10, (spec11, (spec12, ())))))))))))) -> + arg1, arg2, arg3, arg4, arg5, spec6, spec7, spec8, spec9, spec10, spec11, spec12 } + +let args13 spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12 spec13 = + Argument + { spec = spec1 >> (spec2 >> (spec3 >> (spec4 >> (spec5 >> (spec6 >> (spec7 >> (spec8 >> (spec9 >> (spec10 >> (spec11 >> (spec12 >> (spec13 >> NoArgs)))))))))))) ; + converter = fun (arg1, (arg2, (arg3, (arg4, (arg5, (spec6, (spec7, (spec8, (spec9, (spec10, (spec11, (spec12, (spec13, ()))))))))))))) -> + arg1, arg2, arg3, arg4, arg5, spec6, spec7, spec8, spec9, spec10, spec11, spec12, spec13 } + +let args14 spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12 spec13 spec14 = + Argument + { spec = spec1 >> (spec2 >> (spec3 >> (spec4 >> (spec5 >> (spec6 >> (spec7 >> (spec8 >> (spec9 >> (spec10 >> (spec11 >> (spec12 >> (spec13 >> (spec14 >> NoArgs))))))))))))) ; + converter = fun (arg1, (arg2, (arg3, (arg4, (arg5, (spec6, (spec7, (spec8, (spec9, (spec10, (spec11, (spec12, (spec13, (spec14, ())))))))))))))) -> + arg1, arg2, arg3, arg4, arg5, spec6, spec7, spec8, spec9, spec10, spec11, spec12, spec13, spec14 } + +let args15 spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12 spec13 spec14 spec15 = + Argument + { spec = spec1 >> (spec2 >> (spec3 >> (spec4 >> (spec5 >> (spec6 >> (spec7 >> (spec8 >> (spec9 >> (spec10 >> (spec11 >> (spec12 >> (spec13 >> (spec14 >> (spec15 >> NoArgs)))))))))))))) ; + converter = fun (arg1, (arg2, (arg3, (arg4, (arg5, (spec6, (spec7, (spec8, (spec9, (spec10, (spec11, (spec12, (spec13, (spec14, (spec15, ()))))))))))))))) -> + arg1, arg2, arg3, arg4, arg5, spec6, spec7, spec8, spec9, spec10, spec11, spec12, spec13, spec14, spec15 } + +let args16 spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12 spec13 spec14 spec15 spec16 = + Argument + { spec = spec1 >> (spec2 >> (spec3 >> (spec4 >> (spec5 >> (spec6 >> (spec7 >> (spec8 >> (spec9 >> (spec10 >> (spec11 >> (spec12 >> (spec13 >> (spec14 >> (spec15 >> (spec16 >> NoArgs))))))))))))))) ; + converter = fun (arg1, (arg2, (arg3, (arg4, (arg5, (spec6, (spec7, (spec8, (spec9, (spec10, (spec11, (spec12, (spec13, (spec14, (spec15, (spec16, ())))))))))))))))) -> + arg1, arg2, arg3, arg4, arg5, spec6, spec7, spec8, spec9, spec10, spec11, spec12, spec13, spec14, spec15, spec16 } + (* Some combinators for writing commands concisely. *) let param ~name ~desc kind next = Param (name, desc, kind, next) let seq_of_param param = diff --git a/src/lib_clic/clic.mli b/src/lib_clic/clic.mli index 3959fbfd5..9aca65a18 100644 --- a/src/lib_clic/clic.mli +++ b/src/lib_clic/clic.mli @@ -190,6 +190,39 @@ val args11 : ('a, 'ctx) arg -> ('b, 'ctx) arg -> ('c, 'ctx) arg -> ('d, 'ctx) ar ('i, 'ctx) arg -> ('j, 'ctx) arg -> ('k, 'ctx) arg -> ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h * 'i * 'j * 'k, 'ctx) options +(** Include 12 optional parameters *) +val args12 : ('a, 'ctx) arg -> ('b, 'ctx) arg -> ('c, 'ctx) arg -> ('d, 'ctx) arg -> + ('e, 'ctx) arg -> ('f, 'ctx) arg -> ('g, 'ctx) arg -> ('h, 'ctx) arg -> + ('i, 'ctx) arg -> ('j, 'ctx) arg -> ('k, 'ctx) arg -> ('l, 'ctx) arg -> + ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h * 'i * 'j * 'k * 'l, 'ctx) options + +(** Include 13 optional parameters *) +val args13 : ('a, 'ctx) arg -> ('b, 'ctx) arg -> ('c, 'ctx) arg -> ('d, 'ctx) arg -> + ('e, 'ctx) arg -> ('f, 'ctx) arg -> ('g, 'ctx) arg -> ('h, 'ctx) arg -> + ('i, 'ctx) arg -> ('j, 'ctx) arg -> ('k, 'ctx) arg -> ('l, 'ctx) arg -> ('m, 'ctx) arg -> + ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h * 'i * 'j * 'k * 'l * 'm, 'ctx) options + +(** Include 14 optional parameters *) +val args14 : ('a, 'ctx) arg -> ('b, 'ctx) arg -> ('c, 'ctx) arg -> ('d, 'ctx) arg -> + ('e, 'ctx) arg -> ('f, 'ctx) arg -> ('g, 'ctx) arg -> ('h, 'ctx) arg -> + ('i, 'ctx) arg -> ('j, 'ctx) arg -> ('k, 'ctx) arg -> ('l, 'ctx) arg -> + ('m, 'ctx) arg -> ('n, 'ctx) arg -> + ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h * 'i * 'j * 'k * 'l * 'm * 'n, 'ctx) options + +(** Include 15 optional parameters *) +val args15 : ('a, 'ctx) arg -> ('b, 'ctx) arg -> ('c, 'ctx) arg -> ('d, 'ctx) arg -> + ('e, 'ctx) arg -> ('f, 'ctx) arg -> ('g, 'ctx) arg -> ('h, 'ctx) arg -> + ('i, 'ctx) arg -> ('j, 'ctx) arg -> ('k, 'ctx) arg -> ('l, 'ctx) arg -> + ('m, 'ctx) arg -> ('n, 'ctx) arg -> ('o, 'ctx) arg -> + ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h * 'i * 'j * 'k * 'l * 'm * 'n * 'o, 'ctx) options + +(** Include 16 optional parameters *) +val args16 : ('a, 'ctx) arg -> ('b, 'ctx) arg -> ('c, 'ctx) arg -> ('d, 'ctx) arg -> + ('e, 'ctx) arg -> ('f, 'ctx) arg -> ('g, 'ctx) arg -> ('h, 'ctx) arg -> + ('i, 'ctx) arg -> ('j, 'ctx) arg -> ('k, 'ctx) arg -> ('l, 'ctx) arg -> + ('m, 'ctx) arg -> ('n, 'ctx) arg -> ('o, 'ctx) arg -> ('p, 'ctx) arg -> + ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h * 'i * 'j * 'k * 'l * 'm * 'n * 'o * 'p, 'ctx) options + (** {2 Parameter based command lines} *) (** Type of parameters for a command *) diff --git a/src/proto_alpha/lib_client/client_proto_args.ml b/src/proto_alpha/lib_client/client_proto_args.ml index 68a30effd..43738bef7 100644 --- a/src/proto_alpha/lib_client/client_proto_args.ml +++ b/src/proto_alpha/lib_client/client_proto_args.ml @@ -191,10 +191,11 @@ let tez_param ~name ~desc next = next let fee_arg = - tez_arg - ~default:"0.05" - ~parameter:"fee" + arg + ~long:"fee" + ~placeholder:"amount" ~doc:"fee in \xEA\x9C\xA9 to pay to the baker" + (tez_parameter ("--fee")) let gas_limit_arg = arg @@ -246,34 +247,70 @@ let max_priority_arg = try return (int_of_string s) with _ -> fail (Bad_max_priority s))) + +let default_minimal_fees = match Tez.of_mutez 100L with None -> assert false | Some t -> t +let default_minimal_picotez_per_gas_unit = Z.of_int 100 +let default_minimal_picotez_per_byte = Z.of_int 1000 + let minimal_fees_arg = - arg + default_arg ~long:"minimal-fees" ~placeholder:"amount" ~doc:"exclude operations with fees lower than this threshold (in tez)" + ~default:(Tez.to_string default_minimal_fees) (parameter (fun _ s -> match Tez.of_string s with | Some t -> return t | None -> fail (Bad_minimal_fees s))) let minimal_picotez_per_gas_unit_arg = - arg + default_arg ~long:"minimal-picotez-per-gas-unit" ~placeholder:"amount" ~doc:"exclude operations with fees per gas lower than this threshold (in picotez)" + ~default:(Z.to_string default_minimal_picotez_per_gas_unit) (parameter (fun _ s -> try return (Z.of_string s) with _ -> fail (Bad_minimal_fees s))) let minimal_picotez_per_byte_arg = - arg + default_arg ~long:"minimal-picotez-per-byte" ~placeholder:"amount" + ~default:(Z.to_string default_minimal_picotez_per_byte) ~doc:"exclude operations with fees per byte lower than this threshold (in tez)" (parameter (fun _ s -> try return (Z.of_string s) with _ -> fail (Bad_minimal_fees s))) +let force_low_fee_arg = + switch + ~long:"force-low-fee" + ~doc:"Don't check that the fee is lower than the estimated default value" + () + +let fee_cap_arg = + default_arg + ~long:"fee-cap" + ~placeholder:"amount" + ~default:"1.0" + ~doc:"Set the fee cap" + (parameter (fun _ s -> + match Tez.of_string s with + | Some t -> return t + | None -> failwith "Bad fee cap")) + +let burn_cap_arg = + default_arg + ~long:"burn-cap" + ~placeholder:"amount" + ~default:"0" + ~doc:"Set the burn cap" + (parameter (fun _ s -> + match Tez.of_string s with + | Some t -> return t + | None -> failwith "Bad burn cap")) + let no_waiting_for_endorsements_arg = switch ~long:"no-waiting-for-late-endorsements" diff --git a/src/proto_alpha/lib_client/client_proto_args.mli b/src/proto_alpha/lib_client/client_proto_args.mli index 696eb6117..289f30ab2 100644 --- a/src/proto_alpha/lib_client/client_proto_args.mli +++ b/src/proto_alpha/lib_client/client_proto_args.mli @@ -29,7 +29,7 @@ open Alpha_context val tez_sym: string val init_arg: (string, Proto_alpha.full) Clic.arg -val fee_arg: (Tez.t, Proto_alpha.full) Clic.arg +val fee_arg: (Tez.t option, Proto_alpha.full) Clic.arg val counter_arg: (Z.t option, Proto_alpha.full) Clic.arg val gas_limit_arg: (Z.t option, Proto_alpha.full) Clic.arg val storage_limit_arg: (Z.t option, Proto_alpha.full) Clic.arg @@ -40,9 +40,12 @@ val delegate_arg: (Signature.Public_key_hash.t option, Proto_alpha.full) Clic.ar val delegatable_switch: (bool, Proto_alpha.full) Clic.arg val spendable_switch: (bool, Proto_alpha.full) Clic.arg val max_priority_arg: (int option, Proto_alpha.full) Clic.arg -val minimal_fees_arg: (Tez.tez option, Proto_alpha.full) Clic.arg -val minimal_picotez_per_gas_unit_arg: (Z.t option, Proto_alpha.full) Clic.arg -val minimal_picotez_per_byte_arg: (Z.t option, Proto_alpha.full) Clic.arg +val minimal_fees_arg: (Tez.tez, Proto_alpha.full) Clic.arg +val minimal_picotez_per_gas_unit_arg: (Z.t, Proto_alpha.full) Clic.arg +val minimal_picotez_per_byte_arg: (Z.t, Proto_alpha.full) Clic.arg +val force_low_fee_arg: (bool, Proto_alpha.full) Clic.arg +val fee_cap_arg: (Tez.t, Proto_alpha.full) Clic.arg +val burn_cap_arg: (Tez.t, Proto_alpha.full) Clic.arg val no_waiting_for_endorsements_arg: (bool, Proto_alpha.full) Clic.arg val await_endorsements_arg: (bool, Proto_alpha.full) Clic.arg val force_switch: (bool, Proto_alpha.full) Clic.arg diff --git a/src/proto_alpha/lib_client/client_proto_context.ml b/src/proto_alpha/lib_client/client_proto_context.ml index 34d6c0aad..a0168dc8f 100644 --- a/src/proto_alpha/lib_client/client_proto_context.ml +++ b/src/proto_alpha/lib_client/client_proto_context.ml @@ -50,7 +50,9 @@ let transfer (cctxt : #Proto_alpha.full) ~chain ~block ?confirmations ?dry_run ?branch ~source ~src_pk ~src_sk ~destination ?arg - ~amount ~fee ?gas_limit ?storage_limit ?counter () = + ~amount ?fee ?gas_limit ?storage_limit ?counter + ~fee_parameter + () = begin match arg with | Some arg -> parse_expression arg >>=? fun { expanded = arg } -> @@ -62,8 +64,10 @@ let transfer (cctxt : #Proto_alpha.full) Injection.inject_manager_operation cctxt ~chain ~block ?confirmations ?dry_run - ?branch ~source ~fee ?gas_limit ?storage_limit ?counter - ~src_pk ~src_sk contents >>=? fun (_oph, _op, result as res) -> + ?branch ~source ?fee ?gas_limit ?storage_limit ?counter + ~src_pk ~src_sk + ~fee_parameter + contents >>=? fun (_oph, _op, result as res) -> Lwt.return (Injection.originated_contracts (Single_result result)) >>=? fun contracts -> return (res, contracts) @@ -71,7 +75,13 @@ let transfer (cctxt : #Proto_alpha.full) let reveal cctxt ~chain ~block ?confirmations ?dry_run - ?branch ~source ~src_pk ~src_sk ~fee () = + ?branch ~source ~src_pk ~src_sk ?fee + ~fee_parameter + () = + let compute_fee, fee = + match fee with + | None -> true, Tez.zero + | Some fee -> false, fee in Alpha_services.Contract.counter cctxt (chain, block) source >>=? fun pcounter -> let counter = Z.succ pcounter in @@ -84,11 +94,13 @@ let reveal cctxt let contents = Single (Manager_operation { source ; fee ; counter ; - gas_limit = Z.of_int 10_000 ; storage_limit = Z.zero ; + gas_limit = Z.of_int ~- 1 ; storage_limit = Z.zero ; operation = Reveal src_pk }) in Injection.inject_operation cctxt ~chain ~block ?confirmations - ?dry_run - ?branch ~src_sk contents >>=? fun (oph, op, result) -> + ?dry_run ?branch ~src_sk + ~compute_fee + ~fee_parameter + contents >>=? fun (oph, op, result) -> match Apply_results.pack_contents_list op result with | Apply_results.Single_and_result (Manager_operation _ as op, result) -> @@ -98,13 +110,17 @@ let reveal cctxt let originate cctxt ~chain ~block ?confirmations ?dry_run - ?branch ~source ~src_pk ~src_sk ~fee - ?gas_limit ?storage_limit contents = + ?branch ~source ~src_pk ~src_sk ?fee + ?gas_limit ?storage_limit + ~fee_parameter + contents = Injection.inject_manager_operation cctxt ~chain ~block ?confirmations ?dry_run - ?branch ~source ~fee ?gas_limit ?storage_limit - ~src_pk ~src_sk contents >>=? fun (_oph, _op, result as res) -> + ?branch ~source ?fee ?gas_limit ?storage_limit + ~src_pk ~src_sk + ~fee_parameter + contents >>=? fun (_oph, _op, result as res) -> Lwt.return (Injection.originated_contracts (Single_result result)) >>=? function | [ contract ] -> return (res, contract) @@ -117,7 +133,9 @@ let originate_account cctxt ~chain ~block ?confirmations ?dry_run ?branch ~source ~src_pk ~src_sk ~manager_pkh - ?(delegatable = false) ?delegate ~balance ~fee () = + ?(delegatable = false) ?delegate ~balance ?fee + ~fee_parameter + () = let origination = Origination { manager = manager_pkh ; delegate ; @@ -129,19 +147,25 @@ let originate_account originate cctxt ~chain ~block ?confirmations ?dry_run - ?branch ~source ~gas_limit:(Z.of_int 10_000) ~src_pk ~src_sk ~fee origination + ?branch ~source ~src_pk ~src_sk ?fee + ~fee_parameter + origination let delegate_contract cctxt ~chain ~block ?branch ?confirmations ?dry_run ~source ~src_pk ~src_sk - ~fee delegate_opt = + ?fee + ~fee_parameter + delegate_opt = let operation = Delegation delegate_opt in Injection.inject_manager_operation cctxt ~chain ~block ?confirmations ?dry_run - ?branch ~source ~fee ~gas_limit:(Z.of_int 10_000) ~storage_limit:Z.zero - ~src_pk ~src_sk operation >>=? fun res -> + ?branch ~source ?fee ~storage_limit:Z.zero + ~src_pk ~src_sk + ~fee_parameter + operation >>=? fun res -> return res let list_contract_labels @@ -185,21 +209,28 @@ let get_manager let set_delegate cctxt ~chain ~block ?confirmations ?dry_run - ~fee contract ~src_pk ~manager_sk opt_delegate = + ?fee contract ~src_pk ~manager_sk + ~fee_parameter + opt_delegate = delegate_contract cctxt ~chain ~block ?confirmations ?dry_run - ~source:contract ~src_pk ~src_sk:manager_sk ~fee opt_delegate + ~source:contract ~src_pk ~src_sk:manager_sk ?fee + ~fee_parameter + opt_delegate let register_as_delegate cctxt ~chain ~block ?confirmations ?dry_run - ~fee ~manager_sk src_pk = + ?fee ~manager_sk + ~fee_parameter + src_pk = let source = Signature.Public_key.hash src_pk in delegate_contract cctxt ~chain ~block ?confirmations ?dry_run - ~source:(Contract.implicit_contract source) ~src_pk ~src_sk:manager_sk ~fee + ~source:(Contract.implicit_contract source) ~src_pk ~src_sk:manager_sk ?fee + ~fee_parameter (Some source) let source_to_keys (wallet : #Proto_alpha.full) ~chain ~block source = @@ -218,7 +249,7 @@ let originate_contract ~chain ~block ?confirmations ?dry_run ?branch - ~fee + ?fee ?gas_limit ?storage_limit ~delegate @@ -231,6 +262,7 @@ let originate_contract ~src_pk ~src_sk ~code + ~fee_parameter () = Lwt.return (Michelson_v1_parser.parse_expression initial_storage) >>= fun result -> Lwt.return (Micheline_parser.no_parsing_error result) >>=? @@ -246,7 +278,9 @@ let originate_contract preorigination = None } in originate cctxt ~chain ~block ?confirmations ?dry_run - ?branch ~source ~src_pk ~src_sk ~fee ?gas_limit ?storage_limit origination + ?branch ~source ~src_pk ~src_sk ?fee ?gas_limit ?storage_limit + ~fee_parameter + origination type activation_key = { pkh : Ed25519.Public_key_hash.t ; @@ -324,6 +358,7 @@ let inject_activate_operation cctxt ?confirmations ?dry_run ~chain ~block + ~fee_parameter:Injection.dummy_fee_parameter contents >>=? fun (oph, op, result) -> begin match confirmations with @@ -349,7 +384,8 @@ let activate_account (cctxt : #Proto_alpha.full) ~chain ~block ?confirmations ?dry_run - ?(encrypted = false) ?force key name = + ?(encrypted = false) ?force + key name = read_key key >>=? fun (pkh, pk, sk) -> fail_unless (Signature.Public_key_hash.equal pkh (Ed25519 key.pkh)) (failure "@[Inconsistent activation key:@ \ diff --git a/src/proto_alpha/lib_client/client_proto_context.mli b/src/proto_alpha/lib_client/client_proto_context.mli index 6b832bea7..f17e7ddb1 100644 --- a/src/proto_alpha/lib_client/client_proto_context.mli +++ b/src/proto_alpha/lib_client/client_proto_context.mli @@ -75,10 +75,11 @@ val set_delegate: block:Shell_services.block -> ?confirmations:int -> ?dry_run:bool -> - fee:Tez.tez -> + ?fee:Tez.tez -> Contract.t -> src_pk:public_key -> manager_sk:Client_keys.sk_uri -> + fee_parameter:Injection.fee_parameter -> public_key_hash option -> Kind.delegation Kind.manager Injection.result tzresult Lwt.t @@ -88,8 +89,9 @@ val register_as_delegate: block:Shell_services.block -> ?confirmations:int -> ?dry_run:bool -> - fee:Tez.tez -> + ?fee:Tez.tez -> manager_sk:Client_keys.sk_uri -> + fee_parameter:Injection.fee_parameter -> public_key -> Kind.delegation Kind.manager Injection.result tzresult Lwt.t @@ -114,7 +116,8 @@ val originate_account : ?delegatable:bool -> ?delegate:public_key_hash -> balance:Tez.tez -> - fee:Tez.tez -> + ?fee:Tez.tez -> + fee_parameter:Injection.fee_parameter -> unit -> (Kind.origination Kind.manager Injection.result * Contract.t) tzresult Lwt.t val save_contract : @@ -131,7 +134,7 @@ val originate_contract: ?confirmations:int -> ?dry_run:bool -> ?branch:int -> - fee:Tez.t -> + ?fee:Tez.t -> ?gas_limit:Z.t -> ?storage_limit:Z.t -> delegate:public_key_hash option -> @@ -144,6 +147,7 @@ val originate_contract: src_pk:public_key -> src_sk:Client_keys.sk_uri -> code:Script.expr -> + fee_parameter:Injection.fee_parameter -> unit -> (Kind.origination Kind.manager Injection.result * Contract.t) tzresult Lwt.t val transfer : @@ -159,10 +163,11 @@ val transfer : destination:Contract.t -> ?arg:string -> amount:Tez.t -> - fee:Tez.t -> + ?fee:Tez.t -> ?gas_limit:Z.t -> ?storage_limit:Z.t -> ?counter:Z.t -> + fee_parameter:Injection.fee_parameter -> unit -> (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult Lwt.t @@ -176,7 +181,8 @@ val reveal : source:Contract.t -> src_pk:public_key -> src_sk:Client_keys.sk_uri -> - fee:Tez.t -> + ?fee:Tez.t -> + fee_parameter:Injection.fee_parameter -> unit -> Kind.reveal Kind.manager Injection.result tzresult Lwt.t type activation_key = diff --git a/src/proto_alpha/lib_client/injection.ml b/src/proto_alpha/lib_client/injection.ml index 50c63f6dc..2651386e9 100644 --- a/src/proto_alpha/lib_client/injection.ml +++ b/src/proto_alpha/lib_client/injection.ml @@ -50,8 +50,86 @@ type 'kind result_list = type 'kind result = Operation_hash.t * 'kind contents * 'kind contents_result +let get_manager_operation_gas_and_fee contents = + let open Operation in + let l = to_list (Contents_list contents) in + List.fold_left + (fun acc -> function + | Contents (Manager_operation { fee ; gas_limit ; _ }) -> begin + match acc with + | Error _ as e -> e + | Ok (total_fee, total_gas) -> + match Tez.(total_fee +? fee) with + | Ok total_fee -> Ok (total_fee, (Z.add total_gas gas_limit)) + | Error _ as e -> e + end + | _ -> acc) + (Ok (Tez.zero, Z.zero)) + l + +type fee_parameter = { + minimal_fees: Tez.t ; + minimal_picotez_per_byte: Z.t ; + minimal_picotez_per_gas_unit: Z.t ; + force_low_fee: bool ; + fee_cap: Tez.t ; + burn_cap: Tez.t ; +} + +let dummy_fee_parameter = { + minimal_fees = Tez.zero ; + minimal_picotez_per_byte = Z.zero ; + minimal_picotez_per_gas_unit = Z.zero ; + force_low_fee = false ; + fee_cap = Tez.one ; + burn_cap = Tez.zero ; +} + +let check_fees + : type t. #Proto_alpha.full -> fee_parameter -> t contents_list -> int -> unit Lwt.t + = fun cctxt config op size -> + match get_manager_operation_gas_and_fee op with + | Error _ -> assert false (* FIXME *) + | Ok (fee, gas) -> + if Tez.compare fee config.fee_cap > 0 then + cctxt#error "The proposed fee (%s%a) are higher than the configured fee cap (%s%a).@\n\ + \ Use `--fee-cap %a` to emit this operation anyway." + Client_proto_args.tez_sym Tez.pp fee + Client_proto_args.tez_sym Tez.pp config.fee_cap + Tez.pp fee >>= fun () -> + exit 1 + else begin (* *) + let fees_in_picotez = + Z.mul (Z.of_int64 (Tez.to_mutez fee)) (Z.of_int 1000) in + let minimal_fees_in_picotez = + Z.mul (Z.of_int64 (Tez.to_mutez config.minimal_fees)) (Z.of_int 1000) in + let minimal_fees_for_gas_in_picotez = + Z.mul config.minimal_picotez_per_gas_unit gas in + let minimal_fees_for_size_in_picotez = + Z.mul config.minimal_picotez_per_byte (Z.of_int size) in + let estimated_fees_in_picotez = + Z.add + minimal_fees_in_picotez + (Z.add minimal_fees_for_gas_in_picotez minimal_fees_for_size_in_picotez) in + let estimated_fees = + match Tez.of_mutez (Z.to_int64 (Z.div (Z.add (Z.of_int 999) estimated_fees_in_picotez) (Z.of_int 1000))) with + | None -> assert false + | Some fee -> fee in + if not config.force_low_fee && + Z.compare fees_in_picotez estimated_fees_in_picotez < 0 then begin + cctxt#error "The proposed fee (%s%a) are lower than the fee that baker \ + expect by default (%s%a).@\n\ + \ Use `--force-low-fee` to emit this operation anyway." + Client_proto_args.tez_sym Tez.pp fee + Client_proto_args.tez_sym Tez.pp estimated_fees >>= fun () -> + exit 1 + end else + Lwt.return_unit + end + let preapply (type t) (cctxt: #Proto_alpha.full) ~chain ~block + ?fee_parameter ?branch ?src_sk (contents : t contents_list) = get_branch cctxt ~chain ~block branch >>=? fun (chain_id, branch) -> let bytes = @@ -76,6 +154,13 @@ let preapply (type t) { shell = { branch } ; protocol_data = { contents ; signature } } in let oph = Operation.hash op in + let size = MBytes.length bytes + Signature.size in + begin + match fee_parameter with + | Some fee_parameter -> + check_fees cctxt fee_parameter contents size + | None -> Lwt.return_unit + end >>= fun () -> Alpha_block_services.Helpers.Preapply.operations cctxt ~chain ~block [Operation.pack op] >>=? function | [(Operation_data op', Operation_metadata result)] -> begin @@ -169,9 +254,10 @@ let estimated_storage_single let estimated_storage origination_size res = let rec estimated_storage : - type kind. kind Kind.manager contents_result_list -> _ = + type kind. kind contents_result_list -> _ = function - | Single_result res -> estimated_storage_single origination_size res + | Single_result (Manager_operation_result _ as res) -> estimated_storage_single origination_size res + | Single_result _ -> Ok Z.zero | Cons_result (res, rest) -> estimated_storage_single origination_size res >>? fun storage1 -> estimated_storage rest >>? fun storage2 -> @@ -252,20 +338,22 @@ let detect_script_failure : detect_script_failure rest in fun { contents } -> detect_script_failure contents - let may_patch_limits - (type kind) (cctxt : #Proto_alpha.full) ~chain ~block ?branch + (type kind) (cctxt : #Proto_alpha.full) + ~fee_parameter + ~chain ~block ?branch ?(compute_fee = false) (contents: kind contents_list) : kind contents_list tzresult Lwt.t = Alpha_services.Constants.all cctxt (chain, block) >>=? fun { parametric = { hard_gas_limit_per_operation = gas_limit ; hard_storage_limit_per_operation = storage_limit ; origination_size ; + cost_per_byte ; } } -> let may_need_patching_single : type kind. kind contents -> kind contents option = function | Manager_operation c - when c.gas_limit < Z.zero || gas_limit <= c.gas_limit + when compute_fee || c.gas_limit < Z.zero || gas_limit <= c.gas_limit || c.storage_limit < Z.zero || storage_limit <= c.storage_limit -> let gas_limit = if c.gas_limit < Z.zero || gas_limit <= c.gas_limit then @@ -297,8 +385,8 @@ let may_patch_limits end in let patch : - type kind. kind contents * kind contents_result -> kind contents tzresult Lwt.t = function - | Manager_operation c, (Manager_operation_result _ as result) -> + type kind. bool -> kind contents * kind contents_result -> kind contents tzresult Lwt.t = fun first -> function + | Manager_operation c as op, (Manager_operation_result _ as result) -> begin if c.gas_limit < Z.zero || gas_limit <= c.gas_limit then Lwt.return (estimated_gas_single result) >>=? fun gas -> @@ -329,21 +417,51 @@ let may_patch_limits end else return c.storage_limit end >>=? fun storage_limit -> - return (Manager_operation { c with gas_limit ; storage_limit }) + begin + if compute_fee then + let size = + if first then + Data_encoding.Binary.fixed_length_exn + Tezos_base.Operation.shell_header_encoding + + Data_encoding.Binary.length + Operation.contents_encoding + (Contents op) + + Signature.size + else + Data_encoding.Binary.length + Operation.contents_encoding + (Contents op) + in + let minimal_fees_in_picotez = + Z.mul (Z.of_int64 (Tez.to_mutez fee_parameter.minimal_fees)) (Z.of_int 1000) in + let minimal_fees_for_gas_in_picotez = + Z.mul fee_parameter.minimal_picotez_per_gas_unit gas_limit in + let minimal_fees_for_size_in_picotez = + Z.mul fee_parameter.minimal_picotez_per_byte (Z.of_int size) in + let fees_in_picotez = + Z.add minimal_fees_in_picotez @@ + Z.add minimal_fees_for_gas_in_picotez minimal_fees_for_size_in_picotez in + match Tez.of_mutez (Z.to_int64 (Z.div (Z.add (Z.of_int 999) fees_in_picotez) (Z.of_int 1000))) with + | None -> assert false + | Some fee -> return fee + else + return c.fee + end >>=? fun fee -> + return (Manager_operation { c with gas_limit ; storage_limit ; fee }) | (c, _) -> return c in let rec patch_list : - type kind. kind contents_and_result_list -> kind contents_list tzresult Lwt.t = - function - | Single_and_result - ((Manager_operation _ as op), (Manager_operation_result _ as res)) -> - patch (op, res) >>=? fun op -> return (Single op) - | Single_and_result (op, _) -> return (Single op) - | Cons_and_result ((Manager_operation _ as op), - (Manager_operation_result _ as res), rest) -> begin - patch (op, res) >>=? fun op -> - patch_list rest >>=? fun rest -> - return (Cons (op, rest)) - end in + type kind. bool -> kind contents_and_result_list -> kind contents_list tzresult Lwt.t = + fun first -> function + | Single_and_result + ((Manager_operation _ as op), (Manager_operation_result _ as res)) -> + patch first (op, res) >>=? fun op -> return (Single op) + | Single_and_result (op, _) -> return (Single op) + | Cons_and_result ((Manager_operation _ as op), + (Manager_operation_result _ as res), rest) -> begin + patch first (op, res) >>=? fun op -> + patch_list false rest >>=? fun rest -> + return (Cons (op, rest)) + end in match may_need_patching contents with | Some contents -> simulate cctxt ~chain ~block ?branch contents >>=? fun (_, _, result) -> @@ -356,8 +474,21 @@ let may_patch_limits (contents, result.contents) >>= fun () -> return_unit end >>=? fun () -> + begin + Lwt.return (estimated_storage (Z.of_int origination_size) result.contents) >>=? fun storage -> + Lwt.return (Alpha_environment.wrap_error Tez.(cost_per_byte *? Z.to_int64 storage)) >>=? fun burn -> + if Tez.(burn > fee_parameter.burn_cap) then + cctxt#error "The operation will burn %s%a which is higher than the configured burn cap (%s%a).@\n\ + \ Use `--burn-cap %a` to emit this operation." + Client_proto_args.tez_sym Tez.pp burn + Client_proto_args.tez_sym Tez.pp fee_parameter.burn_cap + Tez.pp burn >>= fun () -> + exit 1 + else + return_unit + end >>=? fun () -> let res = pack_contents_list contents result.contents in - patch_list res + patch_list true res | None -> return contents let inject_operation @@ -365,11 +496,16 @@ let inject_operation ?confirmations ?(dry_run = false) ?branch ?src_sk + ~fee_parameter + ?compute_fee (contents: kind contents_list) = Client_confirmations.wait_for_bootstrapped cctxt >>=? fun () -> may_patch_limits - cctxt ~chain ~block ?branch contents >>=? fun contents -> - preapply cctxt ~chain ~block + cctxt ~chain ~block ?branch + ~fee_parameter + ?compute_fee + contents >>=? fun contents -> + preapply cctxt ~chain ~block ~fee_parameter ?branch ?src_sk contents >>=? fun (_oph, op, result) -> begin match detect_script_failure result with | Ok () -> return_unit @@ -453,9 +589,10 @@ let inject_operation end >>= fun () -> return (oph, op.protocol_data.contents, result.contents) + let inject_manager_operation cctxt ~chain ~block ?branch ?confirmations ?dry_run - ~source ~src_pk ~src_sk ~fee ?(gas_limit = Z.minus_one) ?(storage_limit = (Z.of_int (-1))) ?counter + ~source ~src_pk ~src_sk ?fee ?(gas_limit = Z.minus_one) ?(storage_limit = (Z.of_int (-1))) ?counter ~fee_parameter (type kind) (operation : kind manager_operation) : (Operation_hash.t * kind Kind.manager contents * kind Kind.manager contents_result) tzresult Lwt.t = begin @@ -473,6 +610,10 @@ let inject_manager_operation let is_reveal : type kind. kind manager_operation -> bool = function | Reveal _ -> true | _ -> false in + let compute_fee, fee = + match fee with + | None -> true, Tez.zero + | Some fee -> false, fee in match key with | None when not (is_reveal operation) -> begin let contents = @@ -483,6 +624,8 @@ let inject_manager_operation Single (Manager_operation { source ; fee ; counter = Z.succ counter ; gas_limit ; storage_limit ; operation })) in inject_operation cctxt ~chain ~block ?confirmations ?dry_run + ~fee_parameter + ~compute_fee ?branch ~src_sk contents >>=? fun (oph, op, result) -> match pack_contents_list op result with | Cons_and_result (_, _, Single_and_result (op, result)) -> @@ -495,7 +638,7 @@ let inject_manager_operation Single (Manager_operation { source ; fee ; counter ; gas_limit ; storage_limit ; operation }) in inject_operation cctxt ~chain ~block ?confirmations ?dry_run - ?branch ~src_sk contents >>=? fun (oph, op, result) -> + ~compute_fee ~fee_parameter ?branch ~src_sk contents >>=? fun (oph, op, result) -> match pack_contents_list op result with | Single_and_result (Manager_operation _ as op, result) -> return (oph, op, result) diff --git a/src/proto_alpha/lib_client/injection.mli b/src/proto_alpha/lib_client/injection.mli index 887977904..e627693e5 100644 --- a/src/proto_alpha/lib_client/injection.mli +++ b/src/proto_alpha/lib_client/injection.mli @@ -30,10 +30,22 @@ open Apply_results type 'kind preapply_result = Operation_hash.t * 'kind operation * 'kind operation_metadata +type fee_parameter = { + minimal_fees: Tez.t ; + minimal_picotez_per_byte: Z.t ; + minimal_picotez_per_gas_unit: Z.t ; + force_low_fee: bool ; + fee_cap: Tez.t ; + burn_cap: Tez.t ; +} + +val dummy_fee_parameter: fee_parameter + val preapply: #Proto_alpha.full -> chain:Shell_services.chain -> block:Shell_services.block -> + ?fee_parameter:fee_parameter -> ?branch:int -> ?src_sk:Client_keys.sk_uri -> 'kind contents_list -> @@ -50,6 +62,8 @@ val inject_operation: ?dry_run:bool -> ?branch:int -> ?src_sk:Client_keys.sk_uri -> + fee_parameter:fee_parameter -> + ?compute_fee:bool -> 'kind contents_list -> 'kind result_list tzresult Lwt.t @@ -66,10 +80,11 @@ val inject_manager_operation: source:Contract.t -> src_pk:Signature.public_key -> src_sk:Client_keys.sk_uri -> - fee:Tez.t -> + ?fee:Tez.t -> ?gas_limit:Z.t -> ?storage_limit:Z.t -> ?counter:Z.t -> + fee_parameter:fee_parameter -> 'kind manager_operation -> 'kind Kind.manager result tzresult Lwt.t diff --git a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml index 9054640af..de76f51f6 100644 --- a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml +++ b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml @@ -223,42 +223,86 @@ let commands version () = end ; command ~group ~desc: "Set the delegate of a contract." - (args2 fee_arg dry_run_switch) + (args8 + fee_arg dry_run_switch + minimal_fees_arg + minimal_picotez_per_byte_arg + minimal_picotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) (prefixes [ "set" ; "delegate" ; "for" ] @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" @@ prefix "to" @@ Public_key_hash.alias_param ~name: "mgr" ~desc: "new delegate of the contract" @@ stop) - begin fun (fee, dry_run) (_, contract) (_, delegate) (cctxt : Proto_alpha.full) -> + begin fun + (fee, dry_run, minimal_fees, minimal_picotez_per_byte, + minimal_picotez_per_gas_unit, force_low_fee, fee_cap, burn_cap) + (_, contract) (_, delegate) (cctxt : Proto_alpha.full) -> + let fee_parameter = { + Injection.minimal_fees ; + minimal_picotez_per_byte ; + minimal_picotez_per_gas_unit ; + force_low_fee ; + fee_cap ; + burn_cap ; + } in source_to_keys cctxt ~chain:`Main ~block:cctxt#block contract >>=? fun (src_pk, manager_sk) -> set_delegate cctxt ~chain:`Main ~block:cctxt#block ?confirmations:cctxt#confirmations ~dry_run - contract (Some delegate) ~fee ~src_pk ~manager_sk >>=? fun _ -> + ~fee_parameter + ?fee + contract (Some delegate) ~src_pk ~manager_sk >>=? fun _ -> return_unit end ; command ~group ~desc: "Withdraw the delegate from a contract." - (args2 fee_arg dry_run_switch) + (args8 + fee_arg dry_run_switch + minimal_fees_arg + minimal_picotez_per_byte_arg + minimal_picotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) (prefixes [ "withdraw" ; "delegate" ; "from" ] @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" @@ stop) - begin fun (fee, dry_run) (_, contract) (cctxt : Proto_alpha.full) -> + begin fun (fee, dry_run, minimal_fees, minimal_picotez_per_byte, + minimal_picotez_per_gas_unit, force_low_fee, fee_cap, burn_cap) + (_, contract) (cctxt : Proto_alpha.full) -> source_to_keys cctxt ~chain:`Main ~block:cctxt#block contract >>=? fun (src_pk, manager_sk) -> + let fee_parameter = { + Injection.minimal_fees ; + minimal_picotez_per_byte ; + minimal_picotez_per_gas_unit ; + force_low_fee ; + fee_cap ; + burn_cap ; + } in set_delegate cctxt ~chain:`Main ~block:cctxt#block ?confirmations:cctxt#confirmations ~dry_run - contract None ~fee ~src_pk ~manager_sk >>=? fun _ -> + ~fee_parameter + contract None ?fee ~src_pk ~manager_sk >>=? fun _ -> return_unit end ; command ~group ~desc:"Open a new account." - (args5 fee_arg dry_run_switch delegate_arg delegatable_switch (Client_keys.force_switch ())) + (args11 fee_arg dry_run_switch delegate_arg delegatable_switch (Client_keys.force_switch ()) + minimal_fees_arg + minimal_picotez_per_byte_arg + minimal_picotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) (prefixes [ "originate" ; "account" ] @@ RawContractAlias.fresh_alias_param ~name: "new" ~desc: "name of the new contract" @@ -272,16 +316,26 @@ let commands version () = @@ ContractAlias.destination_param ~name:"src" ~desc: "name of the source contract" @@ stop) - begin fun (fee, dry_run, delegate, delegatable, force) + begin fun (fee, dry_run, delegate, delegatable, force, minimal_fees, minimal_picotez_per_byte, + minimal_picotez_per_gas_unit, force_low_fee, fee_cap, burn_cap) new_contract manager_pkh balance (_, source) (cctxt : Proto_alpha.full) -> RawContractAlias.of_fresh cctxt force new_contract >>=? fun alias_name -> source_to_keys cctxt ~chain:`Main ~block:cctxt#block source >>=? fun (src_pk, src_sk) -> + let fee_parameter = { + Injection.minimal_fees ; + minimal_picotez_per_byte ; + minimal_picotez_per_gas_unit ; + force_low_fee ; + fee_cap ; + burn_cap ; + } in originate_account cctxt ~chain:`Main ~block:cctxt#block ?confirmations:cctxt#confirmations ~dry_run - ~fee ?delegate ~delegatable ~manager_pkh ~balance + ?fee ?delegate ~delegatable ~manager_pkh ~balance + ~fee_parameter ~source ~src_pk ~src_sk () >>=? fun (_res, contract) -> if dry_run then return_unit @@ -291,10 +345,16 @@ let commands version () = end ; command ~group ~desc: "Launch a smart contract on the blockchain." - (args10 + (args16 fee_arg dry_run_switch gas_limit_arg storage_limit_arg delegate_arg (Client_keys.force_switch ()) - delegatable_switch spendable_switch init_arg no_print_source_flag) + delegatable_switch spendable_switch init_arg no_print_source_flag + minimal_fees_arg + minimal_picotez_per_byte_arg + minimal_picotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) (prefixes [ "originate" ; "contract" ] @@ RawContractAlias.fresh_alias_param ~name: "new" ~desc: "name of the new contract" @@ -312,18 +372,28 @@ let commands version () = ~name:"prg" ~desc: "script of the account\n\ Combine with -init if the storage type is not unit." @@ stop) - begin fun (fee, dry_run, gas_limit, storage_limit, delegate, force, delegatable, spendable, initial_storage, no_print_source) + begin fun (fee, dry_run, gas_limit, storage_limit, delegate, force, delegatable, spendable, initial_storage, no_print_source, minimal_fees, minimal_picotez_per_byte, minimal_picotez_per_gas_unit, force_low_fee, fee_cap, burn_cap) alias_name manager balance (_, source) program (cctxt : Proto_alpha.full) -> RawContractAlias.of_fresh cctxt force alias_name >>=? fun alias_name -> Lwt.return (Micheline_parser.no_parsing_error program) >>=? fun { expanded = code } -> source_to_keys cctxt ~chain:`Main ~block:cctxt#block source >>=? fun (src_pk, src_sk) -> + let fee_parameter = { + Injection.minimal_fees ; + minimal_picotez_per_byte ; + minimal_picotez_per_gas_unit ; + force_low_fee ; + fee_cap ; + burn_cap ; + } in originate_contract cctxt ~chain:`Main ~block:cctxt#block ?confirmations:cctxt#confirmations ~dry_run - ~fee ?gas_limit ?storage_limit ~delegate ~delegatable ~spendable ~initial_storage - ~manager ~balance ~source ~src_pk ~src_sk ~code () >>= fun errors -> + ?fee ?gas_limit ?storage_limit ~delegate ~delegatable ~spendable ~initial_storage + ~manager ~balance ~source ~src_pk ~src_sk ~code + ~fee_parameter + () >>= fun errors -> report_michelson_errors ~no_print_source ~msg:"origination simulation failed" cctxt errors >>= function | None -> return_unit | Some (_res, contract) -> @@ -335,7 +405,13 @@ let commands version () = end ; command ~group ~desc: "Transfer tokens / call a smart contract." - (args7 fee_arg dry_run_switch gas_limit_arg storage_limit_arg counter_arg arg_arg no_print_source_flag) + (args13 fee_arg dry_run_switch gas_limit_arg storage_limit_arg counter_arg arg_arg no_print_source_flag + minimal_fees_arg + minimal_picotez_per_byte_arg + minimal_picotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) (prefixes [ "transfer" ] @@ tez_param ~name: "qty" ~desc: "amount taken from source" @@ -346,14 +422,23 @@ let commands version () = @@ ContractAlias.destination_param ~name: "dst" ~desc: "name/literal of the destination contract" @@ stop) - begin fun (fee, dry_run, gas_limit, storage_limit, counter, arg, no_print_source) amount (_, source) (_, destination) cctxt -> + begin fun (fee, dry_run, gas_limit, storage_limit, counter, arg, no_print_source, minimal_fees, minimal_picotez_per_byte, minimal_picotez_per_gas_unit, force_low_fee, fee_cap, burn_cap) amount (_, source) (_, destination) cctxt -> source_to_keys cctxt ~chain:`Main ~block:cctxt#block source >>=? fun (src_pk, src_sk) -> + let fee_parameter = { + Injection.minimal_fees ; + minimal_picotez_per_byte ; + minimal_picotez_per_gas_unit ; + force_low_fee ; + fee_cap ; + burn_cap ; + } in transfer cctxt ~chain:`Main ~block:cctxt#block ?confirmations:cctxt#confirmations ~dry_run - ~source ~fee ~src_pk ~src_sk ~destination ?arg ~amount ?gas_limit ?storage_limit ?counter () >>= + ~fee_parameter + ~source ?fee ~src_pk ~src_sk ~destination ?arg ~amount ?gas_limit ?storage_limit ?counter () >>= report_michelson_errors ~no_print_source ~msg:"transfer simulation failed" cctxt >>= function | None -> return_unit | Some (_res, _contracts) -> @@ -361,34 +446,66 @@ let commands version () = end; command ~group ~desc: "Reveal the public key of the contract manager." - (args1 fee_arg) + (args7 fee_arg + minimal_fees_arg + minimal_picotez_per_byte_arg + minimal_picotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) (prefixes [ "reveal" ; "key" ; "for" ] @@ ContractAlias.alias_param ~name: "src" ~desc: "name of the source contract" @@ stop) - begin fun fee (_, source) cctxt -> + begin fun (fee, minimal_fees, minimal_picotez_per_byte, + minimal_picotez_per_gas_unit, force_low_fee, fee_cap, burn_cap) (_, source) cctxt -> source_to_keys cctxt ~chain:`Main ~block:cctxt#block source >>=? fun (src_pk, src_sk) -> + let fee_parameter = { + Injection.minimal_fees ; + minimal_picotez_per_byte ; + minimal_picotez_per_gas_unit ; + force_low_fee ; + fee_cap ; + burn_cap ; + } in reveal cctxt ~chain:`Main ~block:cctxt#block ?confirmations:cctxt#confirmations - ~source ~fee ~src_pk ~src_sk () >>=? fun _res -> + ~source ?fee ~src_pk ~src_sk + ~fee_parameter + () >>=? fun _res -> return_unit end; command ~group ~desc: "Register the public key hash as a delegate." - (args2 fee_arg dry_run_switch) + (args8 fee_arg dry_run_switch + minimal_fees_arg + minimal_picotez_per_byte_arg + minimal_picotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) (prefixes [ "register" ; "key" ] @@ Public_key_hash.source_param ~name: "mgr" ~desc: "the delegate key" @@ prefixes [ "as" ; "delegate" ] @@ stop) - begin fun (fee, dry_run) src_pkh cctxt -> + begin fun (fee, dry_run, minimal_fees, minimal_picotez_per_byte, + minimal_picotez_per_gas_unit, force_low_fee, fee_cap, burn_cap) src_pkh cctxt -> Client_keys.get_key cctxt src_pkh >>=? fun (_, src_pk, src_sk) -> + let fee_parameter = { + Injection.minimal_fees ; + minimal_picotez_per_byte ; + minimal_picotez_per_gas_unit ; + force_low_fee ; + fee_cap ; + burn_cap ; + } in register_as_delegate cctxt ~chain:`Main ~block:cctxt#block ?confirmations:cctxt#confirmations - ~dry_run - ~fee ~manager_sk:src_sk src_pk >>=? fun _res -> + ~dry_run ~fee_parameter + ?fee ~manager_sk:src_sk src_pk >>=? fun _res -> return_unit end; ] @ diff --git a/src/proto_alpha/lib_delegate/delegate_commands.ml b/src/proto_alpha/lib_delegate/delegate_commands.ml index a34b1b698..db6aa2cca 100644 --- a/src/proto_alpha/lib_delegate/delegate_commands.ml +++ b/src/proto_alpha/lib_delegate/delegate_commands.ml @@ -75,9 +75,9 @@ let delegate_commands () = minimal_timestamp, mempool, context_path) delegate cctxt -> bake_block cctxt cctxt#block - ?minimal_fees - ?minimal_picotez_per_gas_unit - ?minimal_picotez_per_byte + ~minimal_fees + ~minimal_picotez_per_gas_unit + ~minimal_picotez_per_byte ~await_endorsements ~force ?max_priority ~minimal_timestamp ?mempool ?context_path delegate) ; @@ -128,9 +128,9 @@ let baker_commands () = Tezos_signer_backends.Encrypted.decrypt_list cctxt (List.map fst delegates) >>=? fun () -> Client_daemon.Baker.run cctxt - ?minimal_fees - ?minimal_picotez_per_gas_unit - ?minimal_picotez_per_byte + ~minimal_fees + ~minimal_picotez_per_gas_unit + ~minimal_picotez_per_byte ?max_priority ~await_endorsements:(not no_waiting_for_endorsements) ~context_path:(Filename.concat node_path "context") diff --git a/src/proto_alpha/lib_delegate/test/proto_alpha_helpers.ml b/src/proto_alpha/lib_delegate/test/proto_alpha_helpers.ml index e71dc48f6..00fdd6b6f 100644 --- a/src/proto_alpha/lib_delegate/test/proto_alpha_helpers.ml +++ b/src/proto_alpha/lib_delegate/test/proto_alpha_helpers.ml @@ -266,7 +266,9 @@ module Account = struct ?(fee = Tez.fifty_cents) ~(account:t) ~destination - ~amount () = + ~amount + ?(fee_parameter = Injection.dummy_fee_parameter) + () = let src_sk = Tezos_signer_backends.Unencrypted.make_sk account.sk in Client_proto_context.transfer @@ -278,7 +280,9 @@ module Account = struct ~src_sk ~destination ~amount - ~fee () >>=? fun ((oph, _, _), contracts) -> + ~fee + ~fee_parameter + () >>=? fun ((oph, _, _), contracts) -> return (oph, contracts) let originate @@ -288,6 +292,7 @@ module Account = struct ~(src:t) ~manager_pkh ~balance + ?(fee_parameter = Injection.dummy_fee_parameter) () = let delegatable, delegate = match delegate with | None -> false, None @@ -306,6 +311,7 @@ module Account = struct ~delegatable ?delegate ~fee + ~fee_parameter () >>=? fun ((oph, _, _), contracts) -> return (oph, contracts) @@ -315,6 +321,7 @@ module Account = struct ~contract ~manager_sk ~src_pk + ?(fee_parameter = Injection.dummy_fee_parameter) delegate_opt = Client_proto_context.set_delegate (new wrap_full (no_write_context ~block !rpc_config)) @@ -324,6 +331,7 @@ module Account = struct contract ~src_pk ~manager_sk + ~fee_parameter delegate_opt >>=? fun (oph, _, _) -> return oph diff --git a/src/proto_alpha/lib_delegate/test/proto_alpha_helpers.mli b/src/proto_alpha/lib_delegate/test/proto_alpha_helpers.mli index 54807fe2a..4cdcd072c 100644 --- a/src/proto_alpha/lib_delegate/test/proto_alpha_helpers.mli +++ b/src/proto_alpha/lib_delegate/test/proto_alpha_helpers.mli @@ -85,6 +85,7 @@ module Account : sig account:t -> destination:Contract.t -> amount: Tez.t -> + ?fee_parameter:Injection.fee_parameter -> unit -> (Operation_hash.t * Contract.t list) tzresult Lwt.t @@ -95,6 +96,7 @@ module Account : sig src:t -> manager_pkh:public_key_hash -> balance: Tez.t -> + ?fee_parameter:Injection.fee_parameter -> unit -> (Operation_hash.t * Contract.t) tzresult Lwt.t val set_delegate : @@ -103,6 +105,7 @@ module Account : sig contract:Contract.t -> manager_sk:Client_keys.sk_uri -> src_pk:public_key -> + ?fee_parameter:Injection.fee_parameter -> public_key_hash option -> Operation_hash.t tzresult Lwt.t