From a10932b577849d762580f71582155193b70454bd Mon Sep 17 00:00:00 2001 From: Fabrice Le Fessant Date: Thu, 30 Aug 2018 21:45:56 +0200 Subject: [PATCH] Add a -counter argument to 'transfer AMOUNT from SRC to DST' Useful when you have issued a transaction on a node, and the node seems to be disconnected. You can use this option to issue the same transaction on another node with the same counter. --- src/proto_alpha/lib_client/client_proto_args.ml | 13 +++++++++++++ src/proto_alpha/lib_client/client_proto_args.mli | 1 + .../lib_client/client_proto_context.ml | 4 ++-- .../lib_client/client_proto_context.mli | 1 + src/proto_alpha/lib_client/injection.ml | 15 +++++++++++---- src/proto_alpha/lib_client/injection.mli | 1 + .../client_proto_context_commands.ml | 6 +++--- 7 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/proto_alpha/lib_client/client_proto_args.ml b/src/proto_alpha/lib_client/client_proto_args.ml index 0134ad034..4a6f4dfe4 100644 --- a/src/proto_alpha/lib_client/client_proto_args.ml +++ b/src/proto_alpha/lib_client/client_proto_args.ml @@ -224,6 +224,19 @@ let storage_limit_arg = return v with _ -> failwith "invalid storage limit (must be a positive number of bytes)")) +let counter_arg = + arg + ~long:"counter" + ~short:'C' + ~placeholder:"counter" + ~doc:"Set the counter to be used by the transaction" + (parameter (fun _ s -> + try + let v = Z.of_string s in + assert Compare.Z.(v >= Z.zero) ; + return v + with _ -> failwith "invalid counter (must be a positive number of bytes)")) + let max_priority_arg = arg ~long:"max-priority" diff --git a/src/proto_alpha/lib_client/client_proto_args.mli b/src/proto_alpha/lib_client/client_proto_args.mli index 583f08291..a2208c14d 100644 --- a/src/proto_alpha/lib_client/client_proto_args.mli +++ b/src/proto_alpha/lib_client/client_proto_args.mli @@ -30,6 +30,7 @@ val tez_sym: string val init_arg: (string, Proto_alpha.full) Clic.arg val fee_arg: (Tez.t, 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 val arg_arg: (string option, 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 328208a78..7c15cfbec 100644 --- a/src/proto_alpha/lib_client/client_proto_context.ml +++ b/src/proto_alpha/lib_client/client_proto_context.ml @@ -50,7 +50,7 @@ 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 () = + ~amount ~fee ?gas_limit ?storage_limit ?counter () = begin match arg with | Some arg -> parse_expression arg >>=? fun { expanded = arg } -> @@ -62,7 +62,7 @@ let transfer (cctxt : #Proto_alpha.full) Injection.inject_manager_operation cctxt ~chain ~block ?confirmations ?dry_run - ?branch ~source ~fee ?gas_limit ?storage_limit + ?branch ~source ~fee ?gas_limit ?storage_limit ?counter ~src_pk ~src_sk contents >>=? fun (_oph, _op, result as res) -> Lwt.return (Injection.originated_contracts (Single_result result)) >>=? fun contracts -> diff --git a/src/proto_alpha/lib_client/client_proto_context.mli b/src/proto_alpha/lib_client/client_proto_context.mli index 4a1d8e19f..423609951 100644 --- a/src/proto_alpha/lib_client/client_proto_context.mli +++ b/src/proto_alpha/lib_client/client_proto_context.mli @@ -162,6 +162,7 @@ val transfer : fee:Tez.t -> ?gas_limit:Z.t -> ?storage_limit:Z.t -> + ?counter:Z.t -> unit -> (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult Lwt.t diff --git a/src/proto_alpha/lib_client/injection.ml b/src/proto_alpha/lib_client/injection.ml index fb0b696db..6bb60269d 100644 --- a/src/proto_alpha/lib_client/injection.ml +++ b/src/proto_alpha/lib_client/injection.ml @@ -447,12 +447,19 @@ let inject_operation 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))) + ~source ~src_pk ~src_sk ~fee ?(gas_limit = Z.minus_one) ?(storage_limit = (Z.of_int (-1))) ?counter (type kind) (operation : kind manager_operation) : (Operation_hash.t * kind Kind.manager contents * kind Kind.manager contents_result) tzresult Lwt.t = - Alpha_services.Contract.counter - cctxt (chain, block) source >>=? fun pcounter -> - let counter = Z.succ pcounter in + begin + match counter with + | None -> + Alpha_services.Contract.counter + cctxt (chain, block) source >>=? fun pcounter -> + let counter = Z.succ pcounter in + return counter + | Some counter -> + return counter + end >>=? fun counter -> Alpha_services.Contract.manager_key cctxt (chain, block) source >>=? fun (_, key) -> let is_reveal : type kind. kind manager_operation -> bool = function diff --git a/src/proto_alpha/lib_client/injection.mli b/src/proto_alpha/lib_client/injection.mli index bfcab8b73..887977904 100644 --- a/src/proto_alpha/lib_client/injection.mli +++ b/src/proto_alpha/lib_client/injection.mli @@ -69,6 +69,7 @@ val inject_manager_operation: fee:Tez.t -> ?gas_limit:Z.t -> ?storage_limit:Z.t -> + ?counter:Z.t -> '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 5e8bbdd37..830ca3cca 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 @@ -329,7 +329,7 @@ let commands version () = end ; command ~group ~desc: "Transfer tokens / call a smart contract." - (args6 fee_arg dry_run_switch gas_limit_arg storage_limit_arg arg_arg no_print_source_flag) + (args7 fee_arg dry_run_switch gas_limit_arg storage_limit_arg counter_arg arg_arg no_print_source_flag) (prefixes [ "transfer" ] @@ tez_param ~name: "qty" ~desc: "amount taken from source" @@ -340,14 +340,14 @@ 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, arg, no_print_source) amount (_, source) (_, destination) cctxt -> + begin fun (fee, dry_run, gas_limit, storage_limit, counter, 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 () >>= + ~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) ->