diff --git a/docs/doc_gen/rpcs/usage.rst b/docs/doc_gen/rpcs/usage.rst index 072c24cab..529b46a00 100644 --- a/docs/doc_gen/rpcs/usage.rst +++ b/docs/doc_gen/rpcs/usage.rst @@ -5,11 +5,11 @@ Usage ***** In order to interact with a Tezos node, you may use RPC calls through the -client using this command ``tezos-admin-client rpc call ``. +client using this command ``tezos-admin-client rpc post ``. For instance, if you wish to request the current balance of a given block and contract, you can call the associated RPC via the command : -``$ tezos-admin-client rpc call +``$ tezos-admin-client rpc post /blocks//proto/context/contracts//balance``. A RPC may takes an *input* and generates an *output* both in JSON @@ -19,7 +19,7 @@ input, would display on the standard output : ``{ "balance": through command-line, you will be prompted to provide the JSON input in your default configured text editor. Alternatively, you can provide the JSON input using command -``$ tezos-admin-client rpc call with ``. Don't forget to quote +``$ tezos-admin-client rpc post with ``. Don't forget to quote the JSON according to your shell rules. You can also obtain the list of RPCs on the command line with diff --git a/docs/introduction/alphanet.rst b/docs/introduction/alphanet.rst index 6b72e5a23..86c607aa7 100644 --- a/docs/introduction/alphanet.rst +++ b/docs/introduction/alphanet.rst @@ -275,7 +275,7 @@ Check out the Alphanet *constants* for this: :: - ./alphanet.sh client rpc call /blocks/head/proto/constants + ./alphanet.sh client rpc get /blocks/head/proto/constants Check for the ``endorsement_security_deposit`` and ``block_security_deposit`` keys of the JSON record. The value is in @@ -318,7 +318,10 @@ the appropriate value: $ ./alphanet.sh client list known identities my_identity: tz1iFY8aDskx9QGbgBy68SNAGgkc7AE2iG9H (public key known) (secret key known) - $ ./alphanet.sh client rpc call /blocks/head/proto/helpers/rights/baking/delegate/tz1iFY8aDskx9QGbgBy68SNAGgkc7AE2iG9H with '{}' - [ { "level": 1400.000000, "priority": 2.000000,"timestamp": "2017-05-19T03:21:52Z" }, ... ] + $ ./alphanet.sh client rpc post /blocks/head/proto/helpers/rights/baking/delegate/tz1iFY8aDskx9QGbgBy68SNAGgkc7AE2iG9H with '{}' + { "ok": + [ { "level": 1400.000000, "priority": 2.000000, + "timestamp": "2017-05-19T03:21:52Z" }, + ... ] } .. include:: alphanet_changes.rst diff --git a/docs/introduction/howto.rst b/docs/introduction/howto.rst index 770834ae1..f6f386f40 100644 --- a/docs/introduction/howto.rst +++ b/docs/introduction/howto.rst @@ -277,7 +277,7 @@ preconfigured for communicating the same-numbered node. For instance: :: - $ tezos-client rpc call blocks/head/hash + $ tezos-client rpc post blocks/head/hash { "hash": "BLockGenesisGenesisGenesisGenesisGenesisGeneskvg68z" } When you bootstrap a new network, the network is initialized with a @@ -288,11 +288,11 @@ activating the whole network. For instance: :: - $ tezos-client rpc call blocks/head/protocol + $ tezos-client rpc post blocks/head/protocol { "protocol": "ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im" } $ tezos-activate-alpha Injected BMBcK869jaHQDc - $ tezos-client rpc call blocks/head/protocol + $ tezos-client rpc post blocks/head/protocol { "protocol": "ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK" } Tune protocol alpha parameters diff --git a/scripts/alphanet.sh b/scripts/alphanet.sh index 3c3720168..52483283e 100755 --- a/scripts/alphanet.sh +++ b/scripts/alphanet.sh @@ -381,8 +381,8 @@ run_shell() { display_head() { assert_node_uptodate - exec_docker tezos-client rpc call /blocks/head with '{}' - exec_docker tezos-client rpc call /blocks/head/proto/context/level with '{}' + exec_docker tezos-client rpc post /blocks/head with '{}' + exec_docker tezos-client rpc post /blocks/head/proto/context/level with '{}' } ## Main #################################################################### diff --git a/scripts/docker/entrypoint.inc.sh b/scripts/docker/entrypoint.inc.sh index e70883498..8425ae267 100644 --- a/scripts/docker/entrypoint.inc.sh +++ b/scripts/docker/entrypoint.inc.sh @@ -19,10 +19,10 @@ configure_client() { wait_for_the_node_to_be_ready() { local count=0 - if "$client" rpc call /blocks/head/hash >/dev/null 2>&1; then return; fi + if "$client" rpc post /blocks/head/hash >/dev/null 2>&1; then return; fi printf "Waiting for the node to initialize..." sleep 1 - while ! "$client" rpc call /blocks/head/hash >/dev/null 2>&1 + while ! "$client" rpc post /blocks/head/hash >/dev/null 2>&1 do count=$((count+1)) if [ "$count" -ge 30 ]; then diff --git a/src/bin_client/client_rpc_commands.ml b/src/bin_client/client_rpc_commands.ml index aa0f80073..1a0f4a938 100644 --- a/src/bin_client/client_rpc_commands.ml +++ b/src/bin_client/client_rpc_commands.ml @@ -290,12 +290,12 @@ let list url (cctxt : #Client_context.full) = end else return () -let schema url (cctxt : #Client_context.full) = +let schema meth url (cctxt : #Client_context.full) = let args = String.split '/' url in let open RPC_description in RPC_description.describe cctxt ~recurse:false args >>=? function | Static { services } -> begin - match RPC_service.MethMap.find `POST services with + match RPC_service.MethMap.find meth services with | exception Not_found -> cctxt#message "No service found at this URL (but this is a valid prefix)\n%!" >>= fun () -> @@ -315,12 +315,12 @@ let schema url (cctxt : #Client_context.full) = "No service found at this URL (but this is a valid prefix)\n%!" >>= fun () -> return () -let format url (cctxt : #Client_context.io_rpcs) = +let format meth url (cctxt : #Client_context.io_rpcs) = let args = String.split '/' url in let open RPC_description in RPC_description.describe cctxt ~recurse:false args >>=? function | Static { services } -> begin - match RPC_service.MethMap.find `POST services with + match RPC_service.MethMap.find meth services with | exception Not_found -> cctxt#message "No service found at this URL (but this is a valid prefix)\n%!" >>= fun () -> @@ -366,18 +366,19 @@ let display_answer (cctxt : #Client_context.full) = function cctxt#message "Unexpected server answer\n%!" >>= fun () -> return () -let call raw_url (cctxt : #Client_context.full) = +let call meth raw_url (cctxt : #Client_context.full) = let uri = Uri.of_string raw_url in let args = String.split_path (Uri.path uri) in RPC_description.describe cctxt ~recurse:false args >>=? function | Static { services } -> begin - match RPC_service.MethMap.find `POST services with + match RPC_service.MethMap.find meth services with | exception Not_found -> cctxt#message - "No service found at this URL (but this is a valid prefix)\n%!" >>= fun () -> + "No service found at this URL with this method \ + (but this is a valid prefix)\n%!" >>= fun () -> return () | { input = None } -> - cctxt#generic_json_call `POST uri >>=? + cctxt#generic_json_call meth uri >>=? display_answer cctxt | { input = Some input } -> fill_in ~show_optionals:false input >>= function @@ -385,14 +386,14 @@ let call raw_url (cctxt : #Client_context.full) = cctxt#error "%s" msg >>= fun () -> return () | Ok json -> - cctxt#generic_json_call `POST ~body:json uri >>=? + cctxt#generic_json_call meth ~body:json uri >>=? display_answer cctxt end | _ -> cctxt#message "No service found at this URL\n%!" >>= fun () -> return () -let call_with_json raw_url json (cctxt: #Client_context.full) = +let call_with_json meth raw_url json (cctxt: #Client_context.full) = let uri = Uri.of_string raw_url in match Data_encoding.Json.from_string json with | exception Assert_failure _ -> @@ -404,10 +405,10 @@ let call_with_json raw_url json (cctxt: #Client_context.full) = "Failed to parse the provided json: %s\n%!" err | Ok body -> - cctxt#generic_json_call `POST ~body uri >>=? + cctxt#generic_json_call meth ~body uri >>=? display_answer cctxt -let call_with_file_or_json url maybe_file (cctxt: #Client_context.full) = +let call_with_file_or_json meth url maybe_file (cctxt: #Client_context.full) = begin match TzString.split ':' ~limit:1 maybe_file with | [ "file" ; filename] -> @@ -421,7 +422,20 @@ let call_with_file_or_json url maybe_file (cctxt: #Client_context.full) = "cannot read file (%s)" (Printexc.to_string exn)) | _ -> return maybe_file end >>=? fun json -> - call_with_json url json cctxt + call_with_json meth url json cctxt + +let meth_params ?(name = "HTTP method") ?(desc = "") params = + param ~name ~desc + (parameter ~autocomplete:(fun _ -> + return @@ + List.map String.lowercase_ascii @@ + List.map Resto.string_of_meth @@ + [ `GET ; `POST ; `DELETE ; `PUT ; `PATCH ]) + (fun _ name -> + match Resto.meth_of_string (String.uppercase_ascii name) with + | None -> failwith "Unknown HTTP method: %s" name + | Some meth -> return meth)) + params let group = { Clic.name = "rpc" ; @@ -448,32 +462,45 @@ let commands = [ command ~group ~desc: "Get the input and output JSON schemas of an RPC." no_options - (prefixes [ "rpc" ; "schema" ] @@ string ~name: "url" ~desc: "the RPC url" @@ stop) + (prefixes [ "rpc" ; "schema" ] @@ + meth_params @@ + string ~name: "url" ~desc: "the RPC url" @@ + stop) (fun () -> schema) ; command ~group ~desc: "Get the humanoid readable input and output formats of an RPC." no_options - (prefixes [ "rpc" ; "format" ] @@ string ~name: "url" ~desc: "the RPC URL" @@ stop) + (prefixes [ "rpc" ; "format"] @@ + meth_params @@ + string ~name: "url" ~desc: "the RPC URL" @@ + stop) (fun () -> format) ; command ~group - ~desc: "Call an RPC.\n\ - If input data is needed, a text editor will be popped up." + ~desc: "Call an RPC with the GET method." no_options - (prefixes [ "rpc" ; "call" ] @@ string ~name: "url" ~desc: "the RPC URL" @@ stop) - (fun () -> call) ; + (prefixes [ "rpc" ; "get" ] @@ string ~name: "url" ~desc: "the RPC URL" @@ stop) + (fun () -> call `GET) ; command ~group - ~desc: "Call an RPC providing input data via the command line." + ~desc: "Call an RPC with the POST method.\n\ + If input data is needed, a text editor will be popped up." no_options - (prefixes [ "rpc" ; "call" ] @@ string ~name: "url" ~desc: "the RPC URL" + (prefixes [ "rpc" ; "post" ] @@ string ~name: "url" ~desc: "the RPC URL" @@ stop) + (fun () -> call `POST) ; + + command ~group + ~desc: "Call an RPC with the POST method, \ + \ providing input data via the command line." + no_options + (prefixes [ "rpc" ; "post" ] @@ string ~name: "url" ~desc: "the RPC URL" @@ prefix "with" @@ string ~name:"input" ~desc:"the raw JSON input to the RPC\n\ For instance, use `{}` to send the empty document.\n\ Alternatively, use `file:path` to read the JSON data from a file." @@ stop) - (fun () -> call_with_file_or_json) + (fun () -> call_with_file_or_json `POST) ] diff --git a/src/bin_client/test/test_basic.sh b/src/bin_client/test/test_basic.sh index 4b245be3b..4bb440c5f 100755 --- a/src/bin_client/test/test_basic.sh +++ b/src/bin_client/test/test_basic.sh @@ -13,13 +13,13 @@ $client -w none config update sleep 2 #tests for the rpc service raw_context -$client rpc call '/blocks/head/raw_context/version' | assert '{ "content": "616c706861" }' -$client rpc call '/blocks/head/raw_context/non-existent' | assert 'No service found at this URL' -$client rpc call '/blocks/head/raw_context/delegates/?depth=2' | assert '{ "content": +$client rpc post '/blocks/head/raw_context/version' | assert '{ "content": "616c706861" }' +$client rpc post '/blocks/head/raw_context/non-existent' | assert 'No service found at this URL' +$client rpc post '/blocks/head/raw_context/delegates/?depth=2' | assert '{ "content": { "ed25519": { "02": null, "a9": null, "c5": null, "da": null, "e7": null } } }' -$client rpc call '/blocks/head/raw_context/non-existent?depth=-1' | assert 'No service found at this URL' -$client rpc call '/blocks/head/raw_context/non-existent?depth=0' | assert 'No service found at this URL' +$client rpc post '/blocks/head/raw_context/non-existent?depth=-1' | assert 'No service found at this URL' +$client rpc post '/blocks/head/raw_context/non-existent?depth=0' | assert 'No service found at this URL' bake diff --git a/src/bin_client/test/test_fork.sh b/src/bin_client/test/test_fork.sh index 9668eda35..4cb9f0eb9 100755 --- a/src/bin_client/test/test_fork.sh +++ b/src/bin_client/test/test_fork.sh @@ -37,7 +37,7 @@ $admin_client list protocols #these commands cannot be used in this case because the client does not #know about the new protocol #$client --protocol $protocol_short bake for bootstrap1 -max-priority 512 -#$client --protocol $protocol_version rpc call /blocks/head with {} +#$client --protocol $protocol_version rpc post /blocks/head with {} echo echo End of test diff --git a/src/bin_client/test/test_injection.sh b/src/bin_client/test/test_injection.sh index a77b26071..7b5c34a40 100755 --- a/src/bin_client/test/test_injection.sh +++ b/src/bin_client/test/test_injection.sh @@ -19,7 +19,7 @@ protocol_version="PsxS1brZfzzXCiFwirbMtQr4X5XR6SiHQ46HajpFDdk9GBXR6vy" $admin_client inject protocol "$test_dir/demo" $admin_client list protocols $client activate protocol $protocol_version with fitness 1 and key dictator and parameters $parameters_file -answ=$($client -p ProtoALphaALph rpc call /blocks/head/protocol with {} 2>/dev/null) +answ=$($client -p ProtoALphaALph rpc post /blocks/head/protocol with {} 2>/dev/null) if ! grep "$protocol_version" <<< $answ ; then exit 1 diff --git a/src/bin_client/test/test_injection_alpha.sh b/src/bin_client/test/test_injection_alpha.sh index eea41dec7..375a49aa9 100755 --- a/src/bin_client/test/test_injection_alpha.sh +++ b/src/bin_client/test/test_injection_alpha.sh @@ -37,7 +37,7 @@ $admin_client list protocols #these commands cannot be used in this case because the client does not #know about the new protocol #$client --protocol $protocol_short bake for bootstrap1 -max-priority 512 -#$client --protocol $protocol_version rpc call /blocks/head with {} +#$client --protocol $protocol_version rpc post /blocks/head with {} echo echo End of test diff --git a/src/bin_client/test/test_multinode.sh b/src/bin_client/test/test_multinode.sh index 2bee15992..18ad45481 100755 --- a/src/bin_client/test/test_multinode.sh +++ b/src/bin_client/test/test_multinode.sh @@ -40,7 +40,7 @@ assert_propagation_level() { level=$1 printf "\n\nAsserting all nodes have reached level %s\n" "$level" for client in "${client_instances[@]}"; do - ( $client rpc call /blocks/head/proto/context/level \ + ( $client rpc post /blocks/head/proto/context/level \ | assert_in_output "\"level\": $level" ) \ || exit 2 done @@ -51,7 +51,7 @@ assert_protocol() { proto=$1 printf "\n\nAsserting protocol propagation\n" for client in "${client_instances[@]}"; do - ( $client rpc call /blocks/head/protocol | assert_in_output "$proto" ) \ + ( $client rpc post /blocks/head/protocol | assert_in_output "$proto" ) \ || exit 2 done } @@ -102,7 +102,7 @@ assert_contains_operation() { hash="$1" printf "Asserting operations list contains '$hash'\n" for client in "${client_instances[@]}"; do - ( $client rpc call /blocks/head/operations with {} \ + ( $client rpc post /blocks/head/operations with {} \ | assert_in_output $hash ) \ || exit 2 done diff --git a/src/bin_client/tezos-init-sandboxed-client.sh b/src/bin_client/tezos-init-sandboxed-client.sh index dd0d900f4..97634662f 100755 --- a/src/bin_client/tezos-init-sandboxed-client.sh +++ b/src/bin_client/tezos-init-sandboxed-client.sh @@ -57,10 +57,10 @@ cleanup_clients() { wait_for_the_node_to_be_ready() { local count=0 - if $client rpc call blocks/head/hash >/dev/null 2>&1; then return; fi + if $client rpc post blocks/head/hash >/dev/null 2>&1; then return; fi printf "Waiting for the node to initialize..." sleep 1 - while ! $client rpc call blocks/head/hash >/dev/null 2>&1 + while ! $client rpc post blocks/head/hash >/dev/null 2>&1 do count=$((count+1)) if [ "$count" -ge 30 ]; then @@ -301,7 +301,7 @@ The client is now properly initialized. In the rest of this shell session, you might now run \`tezos-client\` to communicate with a tezos node launched with \`launch-sandboxed-node $1\`. For instance: - tezos-client rpc call blocks/head/protocol + tezos-client rpc post blocks/head/protocol Note: if the current protocol version, as reported by the previous command, is "ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im", you diff --git a/src/lib_shell_services/block_services.mli b/src/lib_shell_services/block_services.mli index a0653b779..089fa9f47 100644 --- a/src/lib_shell_services/block_services.mli +++ b/src/lib_shell_services/block_services.mli @@ -160,7 +160,7 @@ module S : sig block . The optional parameter controls the size of the tree, default is 1. Example: - tezos-client rpc call /blocks/head/raw_context/v1?depth=2 + tezos-client rpc post /blocks/head/raw_context/v1?depth=2 *) val raw_context: ([ `POST ], unit,