From 7e591150e0b923cd441f67a112750cd5fe9149bb Mon Sep 17 00:00:00 2001 From: Benjamin Canou Date: Mon, 25 Jun 2018 21:27:35 +0200 Subject: [PATCH] Client: add flag --dry-run to injection commands --- .../lib_client/client_proto_context.ml | 37 +++++++- .../lib_client/client_proto_context.mli | 8 ++ src/proto_alpha/lib_client/injection.ml | 92 +++++++++++-------- src/proto_alpha/lib_client/injection.mli | 2 + .../client_proto_context_commands.ml | 60 ++++++++---- 5 files changed, 136 insertions(+), 63 deletions(-) diff --git a/src/proto_alpha/lib_client/client_proto_context.ml b/src/proto_alpha/lib_client/client_proto_context.ml index 2cd0e2008..28c6d1a1e 100644 --- a/src/proto_alpha/lib_client/client_proto_context.ml +++ b/src/proto_alpha/lib_client/client_proto_context.ml @@ -26,6 +26,7 @@ let parse_expression arg = 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 () = begin match arg with @@ -38,6 +39,7 @@ let transfer (cctxt : #Proto_alpha.full) let contents = Transaction { amount ; parameters ; destination } in 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) -> Lwt.return @@ -46,6 +48,7 @@ let transfer (cctxt : #Proto_alpha.full) let reveal cctxt ~chain ~block ?confirmations + ?dry_run ?branch ~source ~src_pk ~src_sk ~fee () = Alpha_services.Contract.counter cctxt (chain, block) source >>=? fun pcounter -> @@ -62,6 +65,7 @@ let reveal cctxt gas_limit = Z.zero ; 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) -> match Apply_operation_result.pack_contents_list op result with | Apply_operation_result.Single_and_result @@ -71,10 +75,12 @@ let reveal cctxt let originate cctxt ~chain ~block ?confirmations + ?dry_run ?branch ~source ~src_pk ~src_sk ~fee ?gas_limit ?storage_limit 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) -> Lwt.return @@ -87,6 +93,7 @@ let originate let originate_account cctxt ~chain ~block ?confirmations + ?dry_run ?branch ~source ~src_pk ~src_sk ~manager_pkh ?(delegatable = false) ?delegate ~balance ~fee () = let origination = @@ -99,15 +106,18 @@ let originate_account preorigination = None } in originate cctxt ~chain ~block ?confirmations + ?dry_run ?branch ~source ~gas_limit:Z.zero ~src_pk ~src_sk ~fee origination let delegate_contract cctxt ~chain ~block ?branch ?confirmations + ?dry_run ~source ~src_pk ~src_sk ~fee delegate_opt = let operation = Delegation delegate_opt in Injection.inject_manager_operation cctxt ~chain ~block ?confirmations + ?dry_run ?branch ~source ~fee ~gas_limit:Z.zero ~storage_limit:Z.zero ~src_pk ~src_sk operation >>=? fun res -> return res @@ -152,17 +162,21 @@ let get_manager let set_delegate cctxt ~chain ~block ?confirmations + ?dry_run ~fee contract ~src_pk ~manager_sk opt_delegate = delegate_contract cctxt ~chain ~block ?confirmations + ?dry_run ~source:contract ~src_pk ~src_sk:manager_sk ~fee opt_delegate let register_as_delegate cctxt ~chain ~block ?confirmations + ?dry_run ~fee ~manager_sk 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 (Some source) @@ -179,7 +193,9 @@ let save_contract ~force cctxt alias_name contract = let originate_contract (cctxt : #Proto_alpha.full) - ~chain ~block ?confirmations ?branch + ~chain ~block ?confirmations + ?dry_run + ?branch ~fee ?gas_limit ?storage_limit @@ -207,6 +223,7 @@ let originate_contract credit = balance ; preorigination = None } in originate cctxt ~chain ~block ?confirmations + ?dry_run ?branch ~source ~src_pk ~src_sk ~fee ?gas_limit ?storage_limit origination type activation_key = @@ -275,11 +292,15 @@ let read_key key = return (pkh, pk, sk) let inject_activate_operation - cctxt ~chain ~block ?confirmations alias pkh activation_code = + cctxt ~chain ~block ?confirmations + ?dry_run + alias pkh activation_code = let contents = Single ( Activate_account { id = pkh ; activation_code } ) in Injection.inject_operation - cctxt ?confirmations ~chain ~block + cctxt ?confirmations + ?dry_run + ~chain ~block contents >>=? fun (oph, op, result) -> begin match confirmations with @@ -304,6 +325,7 @@ let inject_activate_operation let activate_account (cctxt : #Proto_alpha.full) ~chain ~block ?confirmations + ?dry_run ?(encrypted = false) ?force key name = read_key key >>=? fun (pkh, pk, sk) -> fail_unless (Signature.Public_key_hash.equal pkh (Ed25519 key.pkh)) @@ -321,15 +343,20 @@ let activate_account end >>=? fun sk_uri -> Client_keys.register_key cctxt ?force (pkh, pk_uri, sk_uri) name >>=? fun () -> inject_activate_operation cctxt - ~chain ~block ?confirmations name key.pkh key.activation_code + ~chain ~block ?confirmations + ?dry_run + name key.pkh key.activation_code let activate_existing_account (cctxt : #Proto_alpha.full) ~chain ~block ?confirmations + ?dry_run alias activation_code = Client_keys.alias_keys cctxt alias >>=? function | Some (Ed25519 pkh, _, _) -> inject_activate_operation - cctxt ~chain ~block ?confirmations alias pkh activation_code + cctxt ~chain ~block ?confirmations + ?dry_run + alias pkh activation_code | Some _ -> failwith "Only Ed25519 accounts can be activated" | None -> failwith "Unknown account" diff --git a/src/proto_alpha/lib_client/client_proto_context.mli b/src/proto_alpha/lib_client/client_proto_context.mli index a7f17da19..bebf5e91e 100644 --- a/src/proto_alpha/lib_client/client_proto_context.mli +++ b/src/proto_alpha/lib_client/client_proto_context.mli @@ -43,6 +43,7 @@ val set_delegate: chain:Shell_services.chain -> block:Shell_services.block -> ?confirmations:int -> + ?dry_run:bool -> fee:Tez.tez -> Contract.t -> src_pk:public_key -> @@ -55,6 +56,7 @@ val register_as_delegate: chain:Shell_services.chain -> block:Shell_services.block -> ?confirmations:int -> + ?dry_run:bool -> fee:Tez.tez -> manager_sk:Client_keys.sk_uri -> public_key -> @@ -72,6 +74,7 @@ val originate_account : chain:Shell_services.chain -> block:Shell_services.block -> ?confirmations:int -> + ?dry_run:bool -> ?branch:int -> source:Contract.t -> src_pk:public_key -> @@ -95,6 +98,7 @@ val originate_contract: chain:Shell_services.chain -> block:Shell_services.block -> ?confirmations:int -> + ?dry_run:bool -> ?branch:int -> fee:Tez.t -> ?gas_limit:Z.t -> @@ -116,6 +120,7 @@ val transfer : chain:Shell_services.chain -> block:Shell_services.block -> ?confirmations:int -> + ?dry_run:bool -> ?branch:int -> source:Contract.t -> src_pk:public_key -> @@ -134,6 +139,7 @@ val reveal : chain:Shell_services.chain -> block:Shell_services.block -> ?confirmations:int -> + ?dry_run:bool -> ?branch:int -> source:Contract.t -> src_pk:public_key -> @@ -157,6 +163,7 @@ val activate_account: chain:Shell_services.chain -> block:Shell_services.block -> ?confirmations:int -> + ?dry_run:bool -> ?encrypted:bool -> ?force:bool -> activation_key -> @@ -168,6 +175,7 @@ val activate_existing_account: chain:Shell_services.chain -> block:Shell_services.block -> ?confirmations:int -> + ?dry_run:bool -> string -> Blinded_public_key_hash.activation_code -> Kind.activate_account Injection.result tzresult Lwt.t diff --git a/src/proto_alpha/lib_client/injection.ml b/src/proto_alpha/lib_client/injection.ml index 9728ef073..15f0549f2 100644 --- a/src/proto_alpha/lib_client/injection.ml +++ b/src/proto_alpha/lib_client/injection.ml @@ -326,7 +326,10 @@ let may_patch_limits let inject_operation (type kind) cctxt ~chain ~block - ?confirmations ?branch ?src_sk (contents: kind contents_list) = + ?confirmations + ?(dry_run = false) + ?branch ?src_sk + (contents: kind contents_list) = Client_confirmations.wait_for_bootstrapped cctxt >>=? fun () -> may_patch_limits cctxt ~chain ~block ?branch contents >>=? fun contents -> @@ -344,43 +347,56 @@ let inject_operation let bytes = Data_encoding.Binary.to_bytes_exn Operation.encoding (Operation.pack op) in - Shell_services.Injection.operation cctxt ~chain bytes >>=? fun oph -> - cctxt#message "Operation successfully injected in the node." >>= fun () -> - cctxt#message "Operation hash is '%a'." Operation_hash.pp oph >>= fun () -> - begin - match confirmations with - | None -> return result - | Some confirmations -> - cctxt#message "Waiting for the operation to be included..." >>= fun () -> - Client_confirmations.wait_for_operation_inclusion - ~confirmations cctxt ~chain oph >>=? fun (h, i , j) -> - Alpha_block_services.Operations.operation - cctxt ~block:(`Hash (h, 0)) i j >>=? fun op' -> - match op'.receipt with - | No_operation_metadata -> - failwith "Internal error: unexpected receipt." - | Operation_metadata receipt -> - match Apply_operation_result.kind_equal_list contents receipt.contents - with - | Some Apply_operation_result.Eq -> - return (receipt : kind operation_metadata) - | None -> failwith "Internal error: unexpected receipt." - end >>=? fun result -> - cctxt#message - "@[This sequence of operations was run:@,%a@]" - Operation_result.pp_operation_result - (op.protocol_data.contents, result.contents) >>= fun () -> - Lwt.return (originated_contracts result.contents) >>=? fun contracts -> - Lwt_list.iter_s - (fun c -> - cctxt#message - "New contract %a originated." - Contract.pp c) - contracts >>= fun () -> - return (oph, op.protocol_data.contents, result.contents) + if dry_run then + let oph = Operation_hash.hash_bytes [bytes] in + cctxt#message + "@[Operation: 0x%a@,\ + Operation hash: %a@]" + MBytes.pp_hex bytes + Operation_hash.pp oph >>= fun () -> + cctxt#message + "@[Simulation result:@,%a@]" + Operation_result.pp_operation_result + (op.protocol_data.contents, result.contents) >>= fun () -> + return (oph, op.protocol_data.contents, result.contents) + else + Shell_services.Injection.operation cctxt ~chain bytes >>=? fun oph -> + cctxt#message "Operation successfully injected in the node." >>= fun () -> + cctxt#message "Operation hash: %a" Operation_hash.pp oph >>= fun () -> + begin + match confirmations with + | None -> return result + | Some confirmations -> + cctxt#message "Waiting for the operation to be included..." >>= fun () -> + Client_confirmations.wait_for_operation_inclusion + ~confirmations cctxt ~chain oph >>=? fun (h, i , j) -> + Alpha_block_services.Operations.operation + cctxt ~block:(`Hash (h, 0)) i j >>=? fun op' -> + match op'.receipt with + | No_operation_metadata -> + failwith "Internal error: unexpected receipt." + | Operation_metadata receipt -> + match Apply_operation_result.kind_equal_list contents receipt.contents + with + | Some Apply_operation_result.Eq -> + return (receipt : kind operation_metadata) + | None -> failwith "Internal error: unexpected receipt." + end >>=? fun result -> + cctxt#message + "@[This sequence of operations was run:@,%a@]" + Operation_result.pp_operation_result + (op.protocol_data.contents, result.contents) >>= fun () -> + Lwt.return (originated_contracts result.contents) >>=? fun contracts -> + Lwt_list.iter_s + (fun c -> + cctxt#message + "New contract %a originated." + Contract.pp c) + contracts >>= fun () -> + return (oph, op.protocol_data.contents, result.contents) let inject_manager_operation - cctxt ~chain ~block ?branch ?confirmations + cctxt ~chain ~block ?branch ?confirmations ?dry_run ~source ~src_pk ~src_sk ~fee ?(gas_limit = Z.minus_one) ?(storage_limit = (Z.of_int (-1))) (type kind) (operation : kind manager_operation) : (Operation_hash.t * kind Kind.manager contents * kind Kind.manager contents_result) tzresult Lwt.t = @@ -401,7 +417,7 @@ let inject_manager_operation operation = Reveal src_pk }, Single (Manager_operation { source ; fee ; counter = Z.succ counter ; gas_limit ; storage_limit ; operation })) in - inject_operation cctxt ~chain ~block ?confirmations + inject_operation cctxt ~chain ~block ?confirmations ?dry_run ?branch ~src_sk contents >>=? fun (oph, op, result) -> match pack_contents_list op result with | Cons_and_result (_, _, Single_and_result (op, result)) -> @@ -413,7 +429,7 @@ let inject_manager_operation let contents = Single (Manager_operation { source ; fee ; counter ; gas_limit ; storage_limit ; operation }) in - inject_operation cctxt ~chain ~block ?confirmations + inject_operation cctxt ~chain ~block ?confirmations ?dry_run ?branch ~src_sk contents >>=? fun (oph, op, result) -> match pack_contents_list op result with | Single_and_result (Manager_operation _ as op, result) -> diff --git a/src/proto_alpha/lib_client/injection.mli b/src/proto_alpha/lib_client/injection.mli index eb13f1840..08cfd6cf4 100644 --- a/src/proto_alpha/lib_client/injection.mli +++ b/src/proto_alpha/lib_client/injection.mli @@ -31,6 +31,7 @@ val inject_operation: chain:Shell_services.chain -> block:Shell_services.block -> ?confirmations:int -> + ?dry_run:bool -> ?branch:int -> ?src_sk:Client_keys.sk_uri -> 'kind contents_list -> @@ -45,6 +46,7 @@ val inject_manager_operation: block:Shell_services.block -> ?branch:int -> ?confirmations:int -> + ?dry_run:bool -> source:Contract.t -> src_pk:Signature.public_key -> src_sk:Client_keys.sk_uri -> 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 5e26e8226..f6d82947d 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 @@ -19,7 +19,13 @@ open Client_proto_args let encrypted_switch = Clic.switch ~long:"encrypted" - ~doc:("Encrypt the key on-disk") () + ~doc:"encrypt the key on-disk" () + +let dry_run_switch = + Clic.switch + ~long:"dry-run" + ~short:'D' + ~doc:"don't inject the operation, just display it" () let report_michelson_errors ?(no_print_source=false) ~msg (cctxt : #Client_context.printer) = function | Error errs -> @@ -148,40 +154,42 @@ let commands () = end ; command ~group ~desc: "Set the delegate of a contract." - (args1 fee_arg) + (args2 fee_arg dry_run_switch) (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 (_, contract) (_, delegate) (cctxt : Proto_alpha.full) -> + begin fun (fee, dry_run) (_, contract) (_, delegate) (cctxt : Proto_alpha.full) -> 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 _ -> return () end ; command ~group ~desc: "Withdraw the delegate from a contract." - (args1 fee_arg) + (args2 fee_arg dry_run_switch) (prefixes [ "withdraw" ; "delegate" ; "from" ] @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" @@ stop) - begin fun fee (_, contract) (cctxt : Proto_alpha.full) -> + begin fun (fee, dry_run) (_, contract) (cctxt : Proto_alpha.full) -> 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 None ~fee ~src_pk ~manager_sk >>=? fun _ -> return () end ; command ~group ~desc:"Open a new account." - (args4 fee_arg delegate_arg delegatable_switch (Client_keys.force_switch ())) + (args5 fee_arg dry_run_switch delegate_arg delegatable_switch (Client_keys.force_switch ())) (prefixes [ "originate" ; "account" ] @@ RawContractAlias.fresh_alias_param ~name: "new" ~desc: "name of the new contract" @@ -195,7 +203,7 @@ let commands () = @@ ContractAlias.destination_param ~name:"src" ~desc: "name of the source contract" @@ stop) - begin fun (fee, delegate, delegatable, force) + begin fun (fee, dry_run, delegate, delegatable, force) new_contract manager_pkh balance (_, source) (cctxt : Proto_alpha.full) -> RawContractAlias.of_fresh cctxt force new_contract >>=? fun alias_name -> source_to_keys cctxt @@ -203,15 +211,20 @@ let commands () = source >>=? fun (src_pk, src_sk) -> originate_account cctxt ~chain:`Main ~block:cctxt#block ?confirmations:cctxt#confirmations + ~dry_run ~fee ?delegate ~delegatable ~manager_pkh ~balance ~source ~src_pk ~src_sk () >>=? fun (_res, contract) -> - save_contract ~force cctxt alias_name contract >>=? fun () -> - return () + if dry_run then + return () + else + save_contract ~force cctxt alias_name contract >>=? fun () -> + return () end ; command ~group ~desc: "Launch a smart contract on the blockchain." - (args9 - fee_arg gas_limit_arg storage_limit_arg delegate_arg (Client_keys.force_switch ()) + (args10 + 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) (prefixes [ "originate" ; "contract" ] @@ RawContractAlias.fresh_alias_param @@ -230,7 +243,7 @@ let commands () = ~name:"prg" ~desc: "script of the account\n\ Combine with -init if the storage type is not unit." @@ stop) - begin fun (fee, 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) 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 } -> @@ -239,17 +252,21 @@ let commands () = source >>=? fun (src_pk, src_sk) -> 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 -> report_michelson_errors ~no_print_source ~msg:"origination simulation failed" cctxt errors >>= function | None -> return () | Some (_res, contract) -> - save_contract ~force cctxt alias_name contract >>=? fun () -> - return () + if dry_run then + return () + else + save_contract ~force cctxt alias_name contract >>=? fun () -> + return () end ; command ~group ~desc: "Transfer tokens / call a smart contract." - (args5 fee_arg gas_limit_arg storage_limit_arg arg_arg no_print_source_flag) + (args6 fee_arg dry_run_switch gas_limit_arg storage_limit_arg arg_arg no_print_source_flag) (prefixes [ "transfer" ] @@ tez_param ~name: "qty" ~desc: "amount taken from source" @@ -260,12 +277,13 @@ let commands () = @@ ContractAlias.destination_param ~name: "dst" ~desc: "name/literal of the destination contract" @@ stop) - begin fun (fee, gas_limit, storage_limit, arg, no_print_source) amount (_, source) (_, destination) cctxt -> + begin fun (fee, dry_run, gas_limit, storage_limit, arg, no_print_source) amount (_, source) (_, destination) cctxt -> source_to_keys cctxt ~chain:`Main ~block:cctxt#block source >>=? fun (src_pk, src_sk) -> 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 () >>= report_michelson_errors ~no_print_source ~msg:"transfer simulation failed" cctxt >>= function | None -> return () @@ -290,16 +308,17 @@ let commands () = end; command ~group ~desc: "Register the public key hash as a delegate." - (args1 fee_arg) + (args2 fee_arg dry_run_switch) (prefixes [ "register" ; "key" ] @@ Public_key_hash.source_param ~name: "mgr" ~desc: "the delegate key" @@ prefixes [ "as" ; "delegate" ] @@ stop) - begin fun fee src_pkh cctxt -> + begin fun (fee, dry_run) src_pkh cctxt -> Client_keys.get_key cctxt src_pkh >>=? fun (_, src_pk, src_sk) -> register_as_delegate cctxt ~chain:`Main ~block:cctxt#block ?confirmations:cctxt#confirmations + ~dry_run ~fee ~manager_sk:src_sk src_pk >>=? fun _res -> return () end; @@ -334,7 +353,7 @@ let commands () = ); command ~group ~desc:"Activate a fundraiser account." - no_options + (args1 dry_run_switch) (prefixes [ "activate" ; "fundraiser" ; "account" ] @@ Public_key_hash.alias_param @@ prefixes [ "with" ] @@ -344,9 +363,10 @@ let commands () = return (Blinded_public_key_hash.activation_code_of_hex code)))) ~desc:"Activation code obtained from the Tezos foundation." @@ stop) - (fun () (name, _pkh) code cctxt -> + (fun dry_run (name, _pkh) code cctxt -> activate_existing_account cctxt ~chain:`Main ~block:cctxt#block ?confirmations:cctxt#confirmations + ~dry_run name code >>=? fun _res -> return () );