From 2352a78301dfbaec31cb5d2ecce71c6c847ec7fe Mon Sep 17 00:00:00 2001 From: Victor Allombert Date: Wed, 24 Oct 2018 11:10:19 +0200 Subject: [PATCH] RPC: add a way to access a given block using its level --- src/lib_shell/block_directory.ml | 7 +++++++ src/lib_shell_services/block_services.ml | 17 ++++++++++++++--- src/lib_shell_services/block_services.mli | 1 + src/proto_alpha/lib_client/injection.ml | 1 + 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/lib_shell/block_directory.ml b/src/lib_shell/block_directory.ml index ea821fd49..c7cf01535 100644 --- a/src/lib_shell/block_directory.ml +++ b/src/lib_shell/block_directory.ml @@ -345,6 +345,13 @@ let get_block chain_state = function State.Block.read_exn chain_state ~pred:n (State.Block.hash head) | `Hash (hash, n) -> State.Block.read_exn chain_state ~pred:n hash + | `Level i -> + Chain.head chain_state >>= fun head -> + let target = Int32.(to_int (sub (State.Block.level head) i)) in + if target < 0 then + Lwt.fail Not_found + else + State.Block.read_exn chain_state ~pred:target (State.Block.hash head) let build_rpc_directory chain_state block = get_block chain_state block >>= fun block -> diff --git a/src/lib_shell_services/block_services.ml b/src/lib_shell_services/block_services.ml index 7d7d13f6a..4ba10b80d 100644 --- a/src/lib_shell_services/block_services.ml +++ b/src/lib_shell_services/block_services.ml @@ -57,6 +57,7 @@ type block = [ | `Genesis | `Head of int | `Hash of Block_hash.t * int + | `Level of Int32.t ] let parse_block s = @@ -65,7 +66,15 @@ let parse_block s = | ["genesis"] -> Ok `Genesis | ["head"] -> Ok (`Head 0) | ["head"; n] -> Ok (`Head (int_of_string n)) - | [h] -> Ok (`Hash (Block_hash.of_b58check_exn h, 0)) + | [hol] -> + begin + match Block_hash.of_b58check_opt hol with + Some h -> Ok (`Hash (h , 0)) + | None -> + let l = Int32.of_string s in + if Int32.(compare l (of_int 0)) < 0 then raise Exit + else Ok (`Level (Int32.of_string s)) + end | [h ; n] -> Ok (`Hash (Block_hash.of_b58check_exn h, int_of_string n)) | _ -> raise Exit with _ -> Error "Cannot parse block identifier." @@ -76,12 +85,14 @@ let to_string = function | `Head n -> Printf.sprintf "head~%d" n | `Hash (h, 0) -> Block_hash.to_b58check h | `Hash (h, n) -> Printf.sprintf "%s~%d" (Block_hash.to_b58check h) n + | `Level i -> Printf.sprintf "%d" (Int32.to_int i) let blocks_arg = let name = "block_id" in let descr = - "A block identifier. This is either a block hash in Base58Check notation \ - or a one the predefined aliases: 'genesis', 'head'. \ + "A block identifier. This is either a block hash in Base58Check notation, \ + one the predefined aliases: 'genesis', 'head' \ + or a block level (index in the chain). \ One might alse use 'head~N' or '~N' where N is an integer to \ denotes the Nth predecessors of the designated block." in let construct = to_string in diff --git a/src/lib_shell_services/block_services.mli b/src/lib_shell_services/block_services.mli index b965d7f84..f6bf9cd2e 100644 --- a/src/lib_shell_services/block_services.mli +++ b/src/lib_shell_services/block_services.mli @@ -41,6 +41,7 @@ type block = [ | `Genesis | `Head of int | `Hash of Block_hash.t * int + | `Level of Int32.t ] val parse_block: string -> (block, string) result val to_string: block -> string diff --git a/src/proto_alpha/lib_client/injection.ml b/src/proto_alpha/lib_client/injection.ml index 6bb60269d..a421c6eaa 100644 --- a/src/proto_alpha/lib_client/injection.ml +++ b/src/proto_alpha/lib_client/injection.ml @@ -35,6 +35,7 @@ let get_branch (rpc_config: #Proto_alpha.full) | `Head n -> return (`Head (n+branch)) | `Hash (h,n) -> return (`Hash (h,n+branch)) | `Genesis -> return `Genesis + | `Level i -> return (`Level i) end >>=? fun block -> Shell_services.Blocks.hash rpc_config ~chain ~block () >>=? fun hash -> Shell_services.Chain.chain_id rpc_config ~chain () >>=? fun chain_id ->