2018-02-17 17:39:45 +04:00
|
|
|
(**************************************************************************)
|
|
|
|
(* *)
|
|
|
|
(* Copyright (c) 2014 - 2018. *)
|
|
|
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
|
|
(* *)
|
|
|
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
|
|
|
|
|
|
|
open Error_monad
|
|
|
|
|
|
|
|
module type CONTEXT = sig
|
|
|
|
type t
|
|
|
|
type key = string list
|
|
|
|
type value = MBytes.t
|
|
|
|
val mem: t -> key -> bool Lwt.t
|
|
|
|
val dir_mem: t -> key -> bool Lwt.t
|
|
|
|
val get: t -> key -> value option Lwt.t
|
|
|
|
val set: t -> key -> value -> t Lwt.t
|
2018-02-20 22:12:02 +04:00
|
|
|
val copy: t -> from:key -> to_:key -> t option Lwt.t
|
2018-02-17 17:39:45 +04:00
|
|
|
val del: t -> key -> t Lwt.t
|
|
|
|
val remove_rec: t -> key -> t Lwt.t
|
|
|
|
val fold:
|
|
|
|
t -> key -> init:'a ->
|
|
|
|
f:([ `Key of key | `Dir of key ] -> 'a -> 'a Lwt.t) ->
|
|
|
|
'a Lwt.t
|
|
|
|
val set_protocol: t -> Protocol_hash.t -> t Lwt.t
|
|
|
|
val fork_test_chain:
|
|
|
|
t -> protocol:Protocol_hash.t -> expiration:Time.t -> t Lwt.t
|
|
|
|
end
|
|
|
|
|
|
|
|
module Make (Context : CONTEXT) = struct
|
|
|
|
|
|
|
|
type validation_result = {
|
|
|
|
context: Context.t ;
|
|
|
|
fitness: Fitness.t ;
|
|
|
|
message: string option ;
|
|
|
|
max_operations_ttl: int ;
|
2018-03-13 16:19:05 +04:00
|
|
|
last_allowed_fork_level: Int32.t ;
|
2018-02-17 17:39:45 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
type quota = {
|
|
|
|
max_size: int ;
|
|
|
|
max_op: int option ;
|
|
|
|
}
|
|
|
|
|
|
|
|
type rpc_context = {
|
|
|
|
block_hash: Block_hash.t ;
|
2018-04-16 02:44:24 +04:00
|
|
|
block_header: Block_header.shell_header ;
|
2018-02-17 17:39:45 +04:00
|
|
|
context: Context.t ;
|
|
|
|
}
|
|
|
|
|
|
|
|
module type T = sig
|
|
|
|
type context
|
|
|
|
type quota
|
|
|
|
type validation_result
|
|
|
|
type rpc_context
|
|
|
|
type 'a tzresult
|
|
|
|
val max_block_length: int
|
2018-06-02 16:58:08 +04:00
|
|
|
val max_operation_data_length: int
|
2018-02-17 17:39:45 +04:00
|
|
|
val validation_passes: quota list
|
2018-04-21 01:04:33 +04:00
|
|
|
type block_header_data
|
|
|
|
val block_header_data_encoding: block_header_data Data_encoding.t
|
|
|
|
type block_header = {
|
|
|
|
shell: Block_header.shell_header ;
|
|
|
|
protocol_data: block_header_data ;
|
|
|
|
}
|
2018-04-16 02:44:20 +04:00
|
|
|
type block_header_metadata
|
|
|
|
val block_header_metadata_encoding: block_header_metadata Data_encoding.t
|
2018-04-21 01:04:33 +04:00
|
|
|
type operation_data
|
2018-04-30 21:06:06 +04:00
|
|
|
type operation_receipt
|
2018-04-21 01:04:33 +04:00
|
|
|
type operation = {
|
|
|
|
shell: Operation.shell_header ;
|
|
|
|
protocol_data: operation_data ;
|
|
|
|
}
|
2018-04-30 21:06:06 +04:00
|
|
|
val operation_data_encoding: operation_data Data_encoding.t
|
|
|
|
val operation_receipt_encoding: operation_receipt Data_encoding.t
|
|
|
|
val operation_data_and_receipt_encoding:
|
|
|
|
(operation_data * operation_receipt) Data_encoding.t
|
2018-02-17 17:39:45 +04:00
|
|
|
val acceptable_passes: operation -> int list
|
|
|
|
val compare_operations: operation -> operation -> int
|
|
|
|
type validation_state
|
|
|
|
val current_context: validation_state -> context tzresult Lwt.t
|
2018-04-09 20:18:57 +04:00
|
|
|
val begin_partial_application:
|
2018-02-17 17:39:45 +04:00
|
|
|
ancestor_context: context ->
|
2018-04-09 20:18:57 +04:00
|
|
|
predecessor_timestamp: Time.t ->
|
|
|
|
predecessor_fitness: Fitness.t ->
|
2018-04-21 01:04:33 +04:00
|
|
|
block_header ->
|
2018-04-09 20:18:57 +04:00
|
|
|
validation_state tzresult Lwt.t
|
2018-02-17 17:39:45 +04:00
|
|
|
val begin_application:
|
|
|
|
predecessor_context: context ->
|
|
|
|
predecessor_timestamp: Time.t ->
|
|
|
|
predecessor_fitness: Fitness.t ->
|
2018-04-21 01:04:33 +04:00
|
|
|
block_header ->
|
2018-02-17 17:39:45 +04:00
|
|
|
validation_state tzresult Lwt.t
|
|
|
|
val begin_construction:
|
|
|
|
predecessor_context: context ->
|
|
|
|
predecessor_timestamp: Time.t ->
|
|
|
|
predecessor_level: Int32.t ->
|
|
|
|
predecessor_fitness: Fitness.t ->
|
|
|
|
predecessor: Block_hash.t ->
|
|
|
|
timestamp: Time.t ->
|
2018-04-21 01:04:33 +04:00
|
|
|
?protocol_data: block_header_data ->
|
2018-02-17 17:39:45 +04:00
|
|
|
unit -> validation_state tzresult Lwt.t
|
|
|
|
val apply_operation:
|
2018-04-16 02:44:20 +04:00
|
|
|
validation_state -> operation ->
|
2018-04-30 21:06:06 +04:00
|
|
|
(validation_state * operation_receipt) tzresult Lwt.t
|
2018-02-17 17:39:45 +04:00
|
|
|
val finalize_block:
|
2018-04-16 02:44:20 +04:00
|
|
|
validation_state ->
|
|
|
|
(validation_result * block_header_metadata) tzresult Lwt.t
|
2018-04-23 03:21:33 +04:00
|
|
|
val rpc_services: rpc_context RPC_directory.t
|
2018-04-06 13:40:34 +04:00
|
|
|
val init:
|
|
|
|
context -> Block_header.shell_header -> validation_result tzresult Lwt.t
|
2018-02-17 17:39:45 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
module type PROTOCOL =
|
|
|
|
T with type context := Context.t
|
|
|
|
and type quota := quota
|
|
|
|
and type validation_result := validation_result
|
|
|
|
and type rpc_context := rpc_context
|
|
|
|
and type 'a tzresult := 'a Error_monad.tzresult
|
|
|
|
|
|
|
|
module type V1 = sig
|
|
|
|
|
|
|
|
include Tezos_protocol_environment_sigs.V1.T
|
|
|
|
with type Format.formatter = Format.formatter
|
|
|
|
and type 'a Data_encoding.t = 'a Data_encoding.t
|
2018-04-23 18:27:36 +04:00
|
|
|
and type 'a Data_encoding.lazy_t = 'a Data_encoding.lazy_t
|
2018-02-17 17:39:45 +04:00
|
|
|
and type 'a Lwt.t = 'a Lwt.t
|
|
|
|
and type ('a, 'b) Pervasives.result = ('a, 'b) result
|
|
|
|
and type Block_hash.t = Block_hash.t
|
|
|
|
and type Operation_hash.t = Operation_hash.t
|
|
|
|
and type Operation_list_hash.t = Operation_list_hash.t
|
|
|
|
and type Operation_list_list_hash.t = Operation_list_list_hash.t
|
|
|
|
and type Context.t = Context.t
|
|
|
|
and type Context_hash.t = Context_hash.t
|
|
|
|
and type Protocol_hash.t = Protocol_hash.t
|
|
|
|
and type Time.t = Time.t
|
|
|
|
and type MBytes.t = MBytes.t
|
|
|
|
and type Operation.shell_header = Operation.shell_header
|
|
|
|
and type Operation.t = Operation.t
|
|
|
|
and type Block_header.shell_header = Block_header.shell_header
|
|
|
|
and type Block_header.t = Block_header.t
|
|
|
|
and type 'a RPC_directory.t = 'a RPC_directory.t
|
|
|
|
and type Ed25519.Public_key_hash.t = Ed25519.Public_key_hash.t
|
|
|
|
and type Ed25519.Public_key.t = Ed25519.Public_key.t
|
2018-04-05 18:07:05 +04:00
|
|
|
and type Ed25519.t = Ed25519.t
|
2018-04-05 19:35:35 +04:00
|
|
|
and type Secp256k1.Public_key_hash.t = Secp256k1.Public_key_hash.t
|
|
|
|
and type Secp256k1.Public_key.t = Secp256k1.Public_key.t
|
|
|
|
and type Secp256k1.t = Secp256k1.t
|
|
|
|
and type Signature.public_key_hash = Signature.public_key_hash
|
|
|
|
and type Signature.public_key = Signature.public_key
|
|
|
|
and type Signature.t = Signature.t
|
2018-05-25 17:50:31 +04:00
|
|
|
and type Signature.watermark = Signature.watermark
|
2018-02-17 17:39:45 +04:00
|
|
|
and type 'a Micheline.canonical = 'a Micheline.canonical
|
|
|
|
and type ('a, 'b) RPC_path.t = ('a, 'b) RPC_path.t
|
2018-03-28 22:42:10 +04:00
|
|
|
and type Z.t = Z.t
|
2018-02-17 17:39:45 +04:00
|
|
|
and type ('a, 'b) Micheline.node = ('a, 'b) Micheline.node
|
|
|
|
and type Data_encoding.json_schema = Data_encoding.json_schema
|
|
|
|
and type RPC_service.meth = RPC_service.meth
|
|
|
|
and type (+'m,'pr,'p,'q,'i,'o) RPC_service.t = ('m,'pr,'p,'q,'i,'o) RPC_service.t
|
|
|
|
and type Error_monad.shell_error = Error_monad.error
|
2018-03-28 22:24:50 +04:00
|
|
|
and type Z.t = Z.t
|
2018-02-17 17:39:45 +04:00
|
|
|
|
2018-02-21 23:58:53 +04:00
|
|
|
type error += Ecoproto_error of Error_monad.error
|
2018-02-17 17:39:45 +04:00
|
|
|
val wrap_error : 'a Error_monad.tzresult -> 'a tzresult
|
|
|
|
|
|
|
|
module Lift (P : Updater.PROTOCOL) : PROTOCOL
|
2018-04-21 01:04:33 +04:00
|
|
|
with type block_header_data = P.block_header_data
|
|
|
|
and type block_header = P.block_header
|
|
|
|
and type operation_data = P.operation_data
|
2018-04-30 21:06:06 +04:00
|
|
|
and type operation_receipt = P.operation_receipt
|
2018-04-21 01:04:33 +04:00
|
|
|
and type operation = P.operation
|
2018-02-20 21:27:08 +04:00
|
|
|
and type validation_state = P.validation_state
|
2018-02-17 17:39:45 +04:00
|
|
|
|
2018-04-16 02:44:24 +04:00
|
|
|
class ['chain, 'block] proto_rpc_context :
|
|
|
|
Tezos_rpc.RPC_context.t -> (unit, (unit * 'chain) * 'block) RPC_path.t ->
|
|
|
|
[('chain * 'block)] RPC_context.simple
|
2018-02-17 17:39:45 +04:00
|
|
|
|
|
|
|
class ['block] proto_rpc_context_of_directory :
|
|
|
|
('block -> RPC_context.t) -> RPC_context.t RPC_directory.t ->
|
|
|
|
['block] RPC_context.simple
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
module MakeV1 (Param : sig val name: string end) () = struct
|
|
|
|
|
|
|
|
include Pervasives
|
|
|
|
module Pervasives = Pervasives
|
|
|
|
module Compare = Compare
|
|
|
|
module Array = Array
|
|
|
|
module List = List
|
|
|
|
module Bytes = struct
|
|
|
|
include Bytes
|
|
|
|
include EndianBytes.BigEndian
|
|
|
|
module LE = EndianBytes.LittleEndian
|
|
|
|
end
|
|
|
|
module String = struct
|
|
|
|
include String
|
|
|
|
include EndianString.BigEndian
|
|
|
|
module LE = EndianString.LittleEndian
|
|
|
|
end
|
|
|
|
module Set = Set
|
|
|
|
module Map = Map
|
|
|
|
module Int32 = Int32
|
|
|
|
module Int64 = Int64
|
|
|
|
module Nativeint = Nativeint
|
|
|
|
module Buffer = Buffer
|
|
|
|
module Format = Format
|
|
|
|
module Option = Option
|
2018-05-17 19:25:54 +04:00
|
|
|
module MBytes = MBytes
|
|
|
|
module Z = struct
|
|
|
|
include Z
|
|
|
|
let to_bits ?(pad_to = 0) z =
|
|
|
|
let bits = to_bits z in
|
|
|
|
let len = Pervasives.((numbits z + 7) / 8) in
|
|
|
|
let full_len = Compare.Int.max pad_to len in
|
|
|
|
if full_len = 0 then
|
|
|
|
MBytes.empty
|
|
|
|
else
|
|
|
|
let res = MBytes.make full_len '\000' in
|
|
|
|
MBytes.blit_of_string bits 0 res 0 len ;
|
|
|
|
res
|
|
|
|
let of_bits bytes =
|
|
|
|
of_bits (MBytes.to_string bytes)
|
|
|
|
end
|
2018-02-17 17:39:45 +04:00
|
|
|
module Lwt_sequence = Lwt_sequence
|
|
|
|
module Lwt = Lwt
|
|
|
|
module Lwt_list = Lwt_list
|
|
|
|
module Uri = Uri
|
|
|
|
module Data_encoding = Data_encoding
|
|
|
|
module Time = Time
|
|
|
|
module Ed25519 = Ed25519
|
2018-04-05 19:35:35 +04:00
|
|
|
module Secp256k1 = Secp256k1
|
|
|
|
module Signature = Signature
|
2018-04-03 13:44:11 +04:00
|
|
|
module S = struct
|
|
|
|
module type T = Tezos_base.S.T
|
|
|
|
module type HASHABLE = Tezos_base.S.HASHABLE
|
2018-04-05 18:07:05 +04:00
|
|
|
module type MINIMAL_HASH = S.MINIMAL_HASH
|
|
|
|
module type B58_DATA = sig
|
2018-04-03 13:44:11 +04:00
|
|
|
|
|
|
|
type t
|
|
|
|
|
2018-04-05 18:07:05 +04:00
|
|
|
val to_b58check: t -> string
|
|
|
|
val to_short_b58check: t -> string
|
2018-04-03 13:44:11 +04:00
|
|
|
|
2018-04-05 18:07:05 +04:00
|
|
|
val of_b58check_exn: string -> t
|
|
|
|
val of_b58check_opt: string -> t option
|
2018-04-03 13:44:11 +04:00
|
|
|
|
2018-04-05 18:07:05 +04:00
|
|
|
type Base58.data += Data of t
|
|
|
|
val b58check_encoding: t Base58.encoding
|
2018-04-03 13:44:11 +04:00
|
|
|
|
2018-04-05 18:07:05 +04:00
|
|
|
end
|
|
|
|
module type RAW_DATA = sig
|
|
|
|
type t
|
|
|
|
val size: int (* in bytes *)
|
2018-04-03 13:44:11 +04:00
|
|
|
val to_bytes: t -> MBytes.t
|
|
|
|
val of_bytes_opt: MBytes.t -> t option
|
|
|
|
val of_bytes_exn: MBytes.t -> t
|
2018-04-05 18:07:05 +04:00
|
|
|
end
|
|
|
|
module type ENCODER = sig
|
|
|
|
type t
|
|
|
|
val encoding: t Data_encoding.t
|
|
|
|
val rpc_arg: t RPC_arg.t
|
|
|
|
end
|
|
|
|
module type SET = Tezos_base.S.SET
|
|
|
|
module type MAP = Tezos_base.S.MAP
|
|
|
|
module type INDEXES = sig
|
2018-04-03 13:44:11 +04:00
|
|
|
|
2018-04-05 18:07:05 +04:00
|
|
|
type t
|
2018-04-03 13:44:11 +04:00
|
|
|
|
|
|
|
val to_path: t -> string list -> string list
|
|
|
|
val of_path: string list -> t option
|
|
|
|
val of_path_exn: string list -> t
|
|
|
|
|
|
|
|
val prefix_path: string -> string list
|
|
|
|
val path_length: int
|
|
|
|
|
|
|
|
module Set : sig
|
2018-04-05 18:07:05 +04:00
|
|
|
include Set.S with type elt = t
|
2018-04-03 13:44:11 +04:00
|
|
|
val encoding: t Data_encoding.t
|
|
|
|
end
|
|
|
|
|
|
|
|
module Map : sig
|
2018-04-05 18:07:05 +04:00
|
|
|
include Map.S with type key = t
|
2018-04-03 13:44:11 +04:00
|
|
|
val encoding: 'a Data_encoding.t -> 'a t Data_encoding.t
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
2018-04-05 18:07:05 +04:00
|
|
|
module type HASH = sig
|
|
|
|
include MINIMAL_HASH
|
|
|
|
include RAW_DATA with type t := t
|
|
|
|
include B58_DATA with type t := t
|
|
|
|
include ENCODER with type t := t
|
|
|
|
include INDEXES with type t := t
|
|
|
|
end
|
2018-04-03 13:44:11 +04:00
|
|
|
|
|
|
|
module type MERKLE_TREE = sig
|
|
|
|
type elt
|
|
|
|
include HASH
|
|
|
|
val compute: elt list -> t
|
|
|
|
val empty: t
|
|
|
|
type path =
|
|
|
|
| Left of path * t
|
|
|
|
| Right of t * path
|
|
|
|
| Op
|
|
|
|
val compute_path: elt list -> int -> path
|
|
|
|
val check_path: path -> elt -> t * int
|
|
|
|
val path_encoding: path Data_encoding.t
|
|
|
|
end
|
2018-04-05 18:07:05 +04:00
|
|
|
|
|
|
|
module type SIGNATURE = sig
|
|
|
|
|
|
|
|
module Public_key_hash : sig
|
|
|
|
|
|
|
|
type t
|
|
|
|
|
|
|
|
val pp: Format.formatter -> t -> unit
|
|
|
|
val pp_short: Format.formatter -> t -> unit
|
|
|
|
include Compare.S with type t := t
|
|
|
|
include RAW_DATA with type t := t
|
|
|
|
include B58_DATA with type t := t
|
|
|
|
include ENCODER with type t := t
|
|
|
|
include INDEXES with type t := t
|
|
|
|
|
2018-04-19 18:50:31 +04:00
|
|
|
val zero: t
|
|
|
|
|
2018-04-05 18:07:05 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
module Public_key : sig
|
|
|
|
|
|
|
|
type t
|
|
|
|
|
|
|
|
val pp: Format.formatter -> t -> unit
|
|
|
|
include Compare.S with type t := t
|
|
|
|
include B58_DATA with type t := t
|
|
|
|
include ENCODER with type t := t
|
|
|
|
|
|
|
|
val hash: t -> Public_key_hash.t
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
type t
|
|
|
|
|
|
|
|
val pp: Format.formatter -> t -> unit
|
|
|
|
include RAW_DATA with type t := t
|
|
|
|
include Compare.S with type t := t
|
|
|
|
include B58_DATA with type t := t
|
|
|
|
include ENCODER with type t := t
|
|
|
|
|
|
|
|
val zero: t
|
|
|
|
|
2018-05-25 17:50:31 +04:00
|
|
|
type watermark
|
|
|
|
|
2018-04-05 18:07:05 +04:00
|
|
|
(** Check a signature *)
|
2018-05-25 17:50:31 +04:00
|
|
|
val check: ?watermark:watermark -> Public_key.t -> t -> MBytes.t -> bool
|
2018-04-05 18:07:05 +04:00
|
|
|
|
|
|
|
end
|
|
|
|
|
2018-04-03 13:44:11 +04:00
|
|
|
end
|
2018-02-17 17:39:45 +04:00
|
|
|
module Error_monad = struct
|
|
|
|
type 'a shell_tzresult = 'a Error_monad.tzresult
|
|
|
|
type shell_error = Error_monad.error = ..
|
|
|
|
type error_category = [ `Branch | `Temporary | `Permanent ]
|
2018-02-21 23:58:53 +04:00
|
|
|
include Error_monad.Make(struct let id = Format.asprintf "proto.%s." Param.name end)
|
2018-02-17 17:39:45 +04:00
|
|
|
end
|
|
|
|
|
2018-02-21 23:58:53 +04:00
|
|
|
type error += Ecoproto_error of Error_monad.error
|
|
|
|
|
|
|
|
module Wrapped_error_monad = struct
|
|
|
|
type unwrapped = Error_monad.error = ..
|
|
|
|
include (Error_monad : Error_monad_sig.S with type error := unwrapped)
|
|
|
|
let unwrap = function
|
|
|
|
| Ecoproto_error ecoerror -> Some ecoerror
|
|
|
|
| _ -> None
|
|
|
|
let wrap ecoerror =
|
|
|
|
Ecoproto_error ecoerror
|
|
|
|
end
|
2018-02-17 17:39:45 +04:00
|
|
|
|
|
|
|
let () =
|
2018-02-21 23:58:53 +04:00
|
|
|
let id = Format.asprintf "proto.%s.wrapper" Param.name in
|
2018-02-17 17:39:45 +04:00
|
|
|
register_wrapped_error_kind
|
2018-02-21 23:58:53 +04:00
|
|
|
(module Wrapped_error_monad)
|
|
|
|
~id ~title: ("Error returned by protocol " ^ Param.name)
|
|
|
|
~description: ("Wrapped error for economic protocol " ^ Param.name ^ ".")
|
2018-02-17 17:39:45 +04:00
|
|
|
|
|
|
|
let wrap_error = function
|
|
|
|
| Ok _ as ok -> ok
|
2018-02-21 23:58:53 +04:00
|
|
|
| Error errors -> Error (List.map (fun error -> Ecoproto_error error) errors)
|
2018-02-17 17:39:45 +04:00
|
|
|
|
|
|
|
module Block_hash = Block_hash
|
|
|
|
module Operation_hash = Operation_hash
|
|
|
|
module Operation_list_hash = Operation_list_hash
|
|
|
|
module Operation_list_list_hash = Operation_list_list_hash
|
|
|
|
module Context_hash = Context_hash
|
|
|
|
module Protocol_hash = Protocol_hash
|
2018-04-03 13:44:11 +04:00
|
|
|
module Blake2B = Blake2B
|
2018-02-17 17:39:45 +04:00
|
|
|
module Fitness = Fitness
|
|
|
|
module Operation = Operation
|
|
|
|
module Block_header = Block_header
|
|
|
|
module Protocol = Protocol
|
|
|
|
module RPC_arg = RPC_arg
|
|
|
|
module RPC_path = RPC_path
|
|
|
|
module RPC_query = RPC_query
|
|
|
|
module RPC_service = RPC_service
|
|
|
|
module RPC_answer = struct
|
|
|
|
|
|
|
|
type 'o t =
|
|
|
|
[ `Ok of 'o (* 200 *)
|
|
|
|
| `OkStream of 'o stream (* 200 *)
|
|
|
|
| `Created of string option (* 201 *)
|
|
|
|
| `No_content (* 204 *)
|
|
|
|
| `Unauthorized of Error_monad.error list option (* 401 *)
|
|
|
|
| `Forbidden of Error_monad.error list option (* 403 *)
|
|
|
|
| `Not_found of Error_monad.error list option (* 404 *)
|
|
|
|
| `Conflict of Error_monad.error list option (* 409 *)
|
|
|
|
| `Error of Error_monad.error list option (* 500 *)
|
|
|
|
]
|
|
|
|
|
|
|
|
and 'a stream = 'a Resto_directory.Answer.stream = {
|
|
|
|
next: unit -> 'a option Lwt.t ;
|
|
|
|
shutdown: unit -> unit ;
|
|
|
|
}
|
|
|
|
|
|
|
|
let return x = Lwt.return (`Ok x)
|
|
|
|
let return_stream x = Lwt.return (`OkStream x)
|
|
|
|
let not_found = Lwt.return (`Not_found None)
|
|
|
|
|
|
|
|
let fail err = Lwt.return (`Error (Some err))
|
|
|
|
end
|
|
|
|
module RPC_directory = struct
|
|
|
|
include RPC_directory
|
|
|
|
let gen_register dir service handler =
|
|
|
|
gen_register dir service
|
|
|
|
(fun p q i ->
|
|
|
|
handler p q i >>= function
|
|
|
|
| `Ok o -> RPC_answer.return o
|
|
|
|
| `OkStream s -> RPC_answer.return_stream s
|
|
|
|
| `Created s -> Lwt.return (`Created s)
|
|
|
|
| `No_content -> Lwt.return (`No_content)
|
|
|
|
| `Unauthorized e ->
|
2018-02-21 23:58:53 +04:00
|
|
|
let e = Option.map e ~f:(List.map (fun e -> Ecoproto_error e)) in
|
2018-02-17 17:39:45 +04:00
|
|
|
Lwt.return (`Unauthorized e)
|
|
|
|
| `Forbidden e ->
|
2018-02-21 23:58:53 +04:00
|
|
|
let e = Option.map e ~f:(List.map (fun e -> Ecoproto_error e)) in
|
2018-02-17 17:39:45 +04:00
|
|
|
Lwt.return (`Forbidden e)
|
|
|
|
| `Not_found e ->
|
2018-02-21 23:58:53 +04:00
|
|
|
let e = Option.map e ~f:(List.map (fun e -> Ecoproto_error e)) in
|
2018-02-17 17:39:45 +04:00
|
|
|
Lwt.return (`Not_found e)
|
|
|
|
| `Conflict e ->
|
2018-02-21 23:58:53 +04:00
|
|
|
let e = Option.map e ~f:(List.map (fun e -> Ecoproto_error e)) in
|
2018-02-17 17:39:45 +04:00
|
|
|
Lwt.return (`Conflict e)
|
|
|
|
| `Error e ->
|
2018-02-21 23:58:53 +04:00
|
|
|
let e = Option.map e ~f:(List.map (fun e -> Ecoproto_error e)) in
|
2018-02-17 17:39:45 +04:00
|
|
|
Lwt.return (`Error e))
|
|
|
|
|
|
|
|
let register dir service handler =
|
|
|
|
gen_register dir service
|
|
|
|
(fun p q i ->
|
|
|
|
handler p q i >>= function
|
|
|
|
| Ok o -> RPC_answer.return o
|
|
|
|
| Error e -> RPC_answer.fail e)
|
|
|
|
|
2018-02-24 00:52:02 +04:00
|
|
|
let opt_register dir service handler =
|
|
|
|
gen_register dir service
|
|
|
|
(fun p q i ->
|
|
|
|
handler p q i >>= function
|
|
|
|
| Ok (Some o) -> RPC_answer.return o
|
|
|
|
| Ok None -> RPC_answer.not_found
|
|
|
|
| Error e -> RPC_answer.fail e)
|
|
|
|
|
2018-02-17 17:39:45 +04:00
|
|
|
let lwt_register dir service handler =
|
|
|
|
gen_register dir service
|
|
|
|
(fun p q i ->
|
|
|
|
handler p q i >>= fun o ->
|
|
|
|
RPC_answer.return o)
|
|
|
|
|
|
|
|
open Curry
|
|
|
|
|
|
|
|
let register0 root s f = register root s (curry Z f)
|
|
|
|
let register1 root s f = register root s (curry (S Z) f)
|
|
|
|
let register2 root s f = register root s (curry (S (S Z)) f)
|
|
|
|
let register3 root s f = register root s (curry (S (S (S Z))) f)
|
|
|
|
let register4 root s f = register root s (curry (S (S (S (S Z)))) f)
|
|
|
|
let register5 root s f = register root s (curry (S (S (S (S (S Z))))) f)
|
|
|
|
|
2018-02-24 00:52:02 +04:00
|
|
|
let opt_register0 root s f = opt_register root s (curry Z f)
|
|
|
|
let opt_register1 root s f = opt_register root s (curry (S Z) f)
|
|
|
|
let opt_register2 root s f = opt_register root s (curry (S (S Z)) f)
|
|
|
|
let opt_register3 root s f = opt_register root s (curry (S (S (S Z))) f)
|
|
|
|
let opt_register4 root s f = opt_register root s (curry (S (S (S (S Z)))) f)
|
|
|
|
let opt_register5 root s f = opt_register root s (curry (S (S (S (S (S Z))))) f)
|
|
|
|
|
2018-02-17 17:39:45 +04:00
|
|
|
let gen_register0 root s f = gen_register root s (curry Z f)
|
|
|
|
let gen_register1 root s f = gen_register root s (curry (S Z) f)
|
|
|
|
let gen_register2 root s f = gen_register root s (curry (S (S Z)) f)
|
|
|
|
let gen_register3 root s f = gen_register root s (curry (S (S (S Z))) f)
|
|
|
|
let gen_register4 root s f = gen_register root s (curry (S (S (S (S Z)))) f)
|
|
|
|
let gen_register5 root s f = gen_register root s (curry (S (S (S (S (S Z))))) f)
|
|
|
|
|
|
|
|
let lwt_register0 root s f = lwt_register root s (curry Z f)
|
|
|
|
let lwt_register1 root s f = lwt_register root s (curry (S Z) f)
|
|
|
|
let lwt_register2 root s f = lwt_register root s (curry (S (S Z)) f)
|
|
|
|
let lwt_register3 root s f = lwt_register root s (curry (S (S (S Z))) f)
|
|
|
|
let lwt_register4 root s f = lwt_register root s (curry (S (S (S (S Z)))) f)
|
|
|
|
let lwt_register5 root s f = lwt_register root s (curry (S (S (S (S (S Z))))) f)
|
|
|
|
|
|
|
|
end
|
|
|
|
module RPC_context = struct
|
|
|
|
|
2018-04-23 03:21:33 +04:00
|
|
|
type t = rpc_context
|
2018-02-17 17:39:45 +04:00
|
|
|
|
|
|
|
class type ['pr] simple = object
|
|
|
|
method call_proto_service0 :
|
|
|
|
'm 'q 'i 'o.
|
|
|
|
([< RPC_service.meth ] as 'm, t, t, 'q, 'i, 'o) RPC_service.t ->
|
|
|
|
'pr -> 'q -> 'i -> 'o Error_monad.shell_tzresult Lwt.t
|
|
|
|
method call_proto_service1 :
|
|
|
|
'm 'a 'q 'i 'o.
|
|
|
|
([< RPC_service.meth ] as 'm, t, t * 'a, 'q, 'i, 'o) RPC_service.t ->
|
|
|
|
'pr -> 'a -> 'q -> 'i -> 'o Error_monad.shell_tzresult Lwt.t
|
|
|
|
method call_proto_service2 :
|
|
|
|
'm 'a 'b 'q 'i 'o.
|
|
|
|
([< RPC_service.meth ] as 'm, t, (t * 'a) * 'b, 'q, 'i, 'o) RPC_service.t ->
|
|
|
|
'pr -> 'a -> 'b -> 'q -> 'i -> 'o Error_monad.shell_tzresult Lwt.t
|
|
|
|
method call_proto_service3 :
|
|
|
|
'm 'a 'b 'c 'q 'i 'o.
|
|
|
|
([< RPC_service.meth ] as 'm, t, ((t * 'a) * 'b) * 'c, 'q, 'i, 'o) RPC_service.t ->
|
|
|
|
'pr -> 'a -> 'b -> 'c -> 'q -> 'i -> 'o Error_monad.shell_tzresult Lwt.t
|
|
|
|
end
|
|
|
|
|
|
|
|
let make_call0 s (ctxt : _ simple) =
|
|
|
|
ctxt#call_proto_service0 s
|
|
|
|
let make_call0 = (make_call0 : _ -> _ simple -> _ :> _ -> _ #simple -> _)
|
|
|
|
|
|
|
|
let make_call1 s (ctxt: _ simple) =
|
|
|
|
ctxt#call_proto_service1 s
|
|
|
|
let make_call1 = (make_call1 : _ -> _ simple -> _ :> _ -> _ #simple -> _)
|
|
|
|
|
|
|
|
let make_call2 s (ctxt: _ simple) =
|
|
|
|
ctxt#call_proto_service2 s
|
|
|
|
let make_call2 = (make_call2 : _ -> _ simple -> _ :> _ -> _ #simple -> _)
|
|
|
|
|
|
|
|
let make_call3 s (ctxt: _ simple) =
|
|
|
|
ctxt#call_proto_service3 s
|
|
|
|
let make_call3 = (make_call3 : _ -> _ simple -> _ :> _ -> _ #simple -> _)
|
|
|
|
|
|
|
|
let make_opt_call0 s ctxt block q i =
|
|
|
|
make_call0 s ctxt block q i >>= function
|
|
|
|
| Error [RPC_context.Not_found _] -> Lwt.return (Ok None)
|
|
|
|
| Error _ as v -> Lwt.return v
|
|
|
|
| Ok v -> Lwt.return (Ok (Some v))
|
|
|
|
|
|
|
|
let make_opt_call1 s ctxt block a1 q i =
|
|
|
|
make_call1 s ctxt block a1 q i >>= function
|
|
|
|
| Error [RPC_context.Not_found _] -> Lwt.return (Ok None)
|
|
|
|
| Error _ as v -> Lwt.return v
|
|
|
|
| Ok v -> Lwt.return (Ok (Some v))
|
|
|
|
|
|
|
|
let make_opt_call2 s ctxt block a1 a2 q i =
|
|
|
|
make_call2 s ctxt block a1 a2 q i >>= function
|
|
|
|
| Error [RPC_context.Not_found _] -> Lwt.return (Ok None)
|
|
|
|
| Error _ as v -> Lwt.return v
|
|
|
|
| Ok v -> Lwt.return (Ok (Some v))
|
|
|
|
|
|
|
|
let make_opt_call3 s ctxt block a1 a2 a3 q i =
|
|
|
|
make_call3 s ctxt block a1 a2 a3 q i >>= function
|
|
|
|
| Error [RPC_context.Not_found _] -> Lwt.return (Ok None)
|
|
|
|
| Error _ as v -> Lwt.return v
|
|
|
|
| Ok v -> Lwt.return (Ok (Some v))
|
|
|
|
|
|
|
|
end
|
|
|
|
module Micheline = Micheline
|
|
|
|
module Logging = Logging.Make(Param)
|
|
|
|
|
|
|
|
module Updater = struct
|
|
|
|
|
|
|
|
type nonrec validation_result = validation_result = {
|
|
|
|
context: Context.t ;
|
|
|
|
fitness: Fitness.t ;
|
|
|
|
message: string option ;
|
|
|
|
max_operations_ttl: int ;
|
2018-03-13 16:19:05 +04:00
|
|
|
last_allowed_fork_level: Int32.t ;
|
2018-02-17 17:39:45 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
type nonrec quota = quota = {
|
|
|
|
max_size: int ;
|
|
|
|
max_op: int option ;
|
|
|
|
}
|
|
|
|
|
|
|
|
type nonrec rpc_context = rpc_context = {
|
|
|
|
block_hash: Block_hash.t ;
|
2018-04-16 02:44:24 +04:00
|
|
|
block_header: Block_header.shell_header ;
|
2018-02-17 17:39:45 +04:00
|
|
|
context: Context.t ;
|
|
|
|
}
|
|
|
|
|
|
|
|
let activate = Context.set_protocol
|
|
|
|
let fork_test_chain = Context.fork_test_chain
|
|
|
|
|
|
|
|
module type PROTOCOL =
|
|
|
|
T with type context := Context.t
|
|
|
|
and type quota := quota
|
|
|
|
and type validation_result := validation_result
|
|
|
|
and type rpc_context := rpc_context
|
|
|
|
and type 'a tzresult := 'a Error_monad.tzresult
|
|
|
|
|
|
|
|
end
|
|
|
|
module Base58 = struct
|
|
|
|
include Tezos_crypto.Base58
|
|
|
|
let simple_encode enc s = simple_encode enc s
|
|
|
|
let simple_decode enc s = simple_decode enc s
|
|
|
|
include Make(struct type context = Context.t end)
|
|
|
|
let decode s = decode s
|
|
|
|
end
|
|
|
|
module Context = struct
|
|
|
|
include Context
|
|
|
|
|
|
|
|
let fold_keys s k ~init ~f =
|
|
|
|
let rec loop k acc =
|
|
|
|
fold s k ~init:acc
|
|
|
|
~f:(fun file acc ->
|
|
|
|
match file with
|
|
|
|
| `Key k -> f k acc
|
|
|
|
| `Dir k -> loop k acc) in
|
|
|
|
loop k init
|
|
|
|
|
|
|
|
let keys t = fold_keys t ~init:[] ~f:(fun k acc -> Lwt.return (k :: acc))
|
|
|
|
|
|
|
|
let register_resolver = Base58.register_resolver
|
|
|
|
let complete ctxt s = Base58.complete ctxt s
|
|
|
|
end
|
|
|
|
|
|
|
|
module Lift(P : Updater.PROTOCOL) = struct
|
|
|
|
include P
|
2018-04-09 20:18:57 +04:00
|
|
|
let begin_partial_application
|
|
|
|
~ancestor_context ~predecessor_timestamp ~predecessor_fitness
|
2018-02-17 17:39:45 +04:00
|
|
|
raw_block =
|
2018-04-09 20:18:57 +04:00
|
|
|
begin_partial_application
|
|
|
|
~ancestor_context ~predecessor_timestamp ~predecessor_fitness
|
2018-02-17 17:39:45 +04:00
|
|
|
raw_block >|= wrap_error
|
|
|
|
let begin_application
|
|
|
|
~predecessor_context ~predecessor_timestamp
|
|
|
|
~predecessor_fitness
|
|
|
|
raw_block =
|
|
|
|
begin_application
|
|
|
|
~predecessor_context ~predecessor_timestamp
|
|
|
|
~predecessor_fitness
|
|
|
|
raw_block >|= wrap_error
|
|
|
|
let begin_construction
|
|
|
|
~predecessor_context ~predecessor_timestamp
|
|
|
|
~predecessor_level ~predecessor_fitness
|
|
|
|
~predecessor ~timestamp ?protocol_data () =
|
|
|
|
begin_construction
|
|
|
|
~predecessor_context ~predecessor_timestamp
|
|
|
|
~predecessor_level ~predecessor_fitness
|
|
|
|
~predecessor ~timestamp ?protocol_data () >|= wrap_error
|
|
|
|
let current_context c =
|
|
|
|
current_context c >|= wrap_error
|
|
|
|
let apply_operation c o =
|
|
|
|
apply_operation c o >|= wrap_error
|
|
|
|
let finalize_block c = finalize_block c >|= wrap_error
|
2018-04-06 13:40:34 +04:00
|
|
|
let init c bh = init c bh >|= wrap_error
|
2018-02-17 17:39:45 +04:00
|
|
|
end
|
|
|
|
|
2018-04-16 02:44:24 +04:00
|
|
|
class ['chain, 'block] proto_rpc_context
|
2018-02-17 17:39:45 +04:00
|
|
|
(t : Tezos_rpc.RPC_context.t)
|
2018-04-16 02:44:24 +04:00
|
|
|
(prefix : (unit, (unit * 'chain) * 'block) RPC_path.t) =
|
2018-02-17 17:39:45 +04:00
|
|
|
object
|
|
|
|
method call_proto_service0
|
|
|
|
: 'm 'q 'i 'o.
|
|
|
|
([< RPC_service.meth ] as 'm, RPC_context.t,
|
|
|
|
RPC_context.t, 'q, 'i, 'o) RPC_service.t ->
|
2018-04-16 02:44:24 +04:00
|
|
|
('chain * 'block) -> 'q -> 'i -> 'o tzresult Lwt.t
|
|
|
|
= fun s (chain, block) q i ->
|
2018-02-17 17:39:45 +04:00
|
|
|
let s = RPC_service.subst0 s in
|
|
|
|
let s = RPC_service.prefix prefix s in
|
2018-04-16 02:44:24 +04:00
|
|
|
t#call_service s (((), chain), block) q i
|
2018-02-17 17:39:45 +04:00
|
|
|
method call_proto_service1
|
|
|
|
: 'm 'a 'q 'i 'o.
|
|
|
|
([< RPC_service.meth ] as 'm, RPC_context.t,
|
|
|
|
RPC_context.t * 'a, 'q, 'i, 'o) RPC_service.t ->
|
2018-04-16 02:44:24 +04:00
|
|
|
('chain * 'block) -> 'a -> 'q -> 'i -> 'o tzresult Lwt.t
|
|
|
|
= fun s (chain, block) a1 q i ->
|
2018-02-17 17:39:45 +04:00
|
|
|
let s = RPC_service.subst1 s in
|
|
|
|
let s = RPC_service.prefix prefix s in
|
2018-04-16 02:44:24 +04:00
|
|
|
t#call_service s ((((), chain), block), a1) q i
|
2018-02-17 17:39:45 +04:00
|
|
|
method call_proto_service2
|
|
|
|
: 'm 'a 'b 'q 'i 'o.
|
|
|
|
([< RPC_service.meth ] as 'm, RPC_context.t,
|
|
|
|
(RPC_context.t * 'a) * 'b, 'q, 'i, 'o) RPC_service.t ->
|
2018-04-16 02:44:24 +04:00
|
|
|
('chain * 'block) -> 'a -> 'b -> 'q -> 'i -> 'o tzresult Lwt.t
|
|
|
|
= fun s (chain, block) a1 a2 q i ->
|
2018-02-17 17:39:45 +04:00
|
|
|
let s = RPC_service.subst2 s in
|
|
|
|
let s = RPC_service.prefix prefix s in
|
2018-04-16 02:44:24 +04:00
|
|
|
t#call_service s (((((), chain), block), a1), a2) q i
|
2018-02-17 17:39:45 +04:00
|
|
|
method call_proto_service3
|
|
|
|
: 'm 'a 'b 'c 'q 'i 'o.
|
|
|
|
([< RPC_service.meth ] as 'm, RPC_context.t,
|
|
|
|
((RPC_context.t * 'a) * 'b) * 'c,
|
|
|
|
'q, 'i, 'o) RPC_service.t ->
|
2018-04-16 02:44:24 +04:00
|
|
|
('chain * 'block) -> 'a -> 'b -> 'c -> 'q -> 'i -> 'o tzresult Lwt.t
|
|
|
|
= fun s (chain, block) a1 a2 a3 q i ->
|
2018-02-17 17:39:45 +04:00
|
|
|
let s = RPC_service.subst3 s in
|
|
|
|
let s = RPC_service.prefix prefix s in
|
2018-04-16 02:44:24 +04:00
|
|
|
t#call_service s ((((((), chain), block), a1), a2), a3) q i
|
2018-02-17 17:39:45 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
class ['block] proto_rpc_context_of_directory conv dir : ['block] RPC_context.simple =
|
|
|
|
let lookup = new Tezos_rpc.RPC_context.of_directory dir in
|
|
|
|
object
|
|
|
|
method call_proto_service0
|
|
|
|
: 'm 'q 'i 'o.
|
|
|
|
([< RPC_service.meth ] as 'm, RPC_context.t,
|
|
|
|
RPC_context.t, 'q, 'i, 'o) RPC_service.t ->
|
|
|
|
'block -> 'q -> 'i -> 'o tzresult Lwt.t
|
|
|
|
= fun s block q i ->
|
|
|
|
let rpc_context = conv block in
|
|
|
|
lookup#call_service s rpc_context q i
|
|
|
|
method call_proto_service1
|
|
|
|
: 'm 'a 'q 'i 'o.
|
|
|
|
([< RPC_service.meth ] as 'm, RPC_context.t,
|
|
|
|
RPC_context.t * 'a, 'q, 'i, 'o) RPC_service.t ->
|
|
|
|
'block -> 'a -> 'q -> 'i -> 'o tzresult Lwt.t
|
|
|
|
= fun s block a1 q i ->
|
|
|
|
let rpc_context = conv block in
|
|
|
|
lookup#call_service s (rpc_context, a1) q i
|
|
|
|
method call_proto_service2
|
|
|
|
: 'm 'a 'b 'q 'i 'o.
|
|
|
|
([< RPC_service.meth ] as 'm, RPC_context.t,
|
|
|
|
(RPC_context.t * 'a) * 'b, 'q, 'i, 'o) RPC_service.t ->
|
|
|
|
'block -> 'a -> 'b -> 'q -> 'i -> 'o tzresult Lwt.t
|
|
|
|
= fun s block a1 a2 q i ->
|
|
|
|
let rpc_context = conv block in
|
|
|
|
lookup#call_service s ((rpc_context, a1), a2) q i
|
|
|
|
method call_proto_service3
|
|
|
|
: 'm 'a 'b 'c 'q 'i 'o.
|
|
|
|
([< RPC_service.meth ] as 'm, RPC_context.t,
|
|
|
|
((RPC_context.t * 'a) * 'b) * 'c,
|
|
|
|
'q, 'i, 'o) RPC_service.t ->
|
|
|
|
'block -> 'a -> 'b -> 'c -> 'q -> 'i -> 'o tzresult Lwt.t
|
|
|
|
= fun s block a1 a2 a3 q i ->
|
|
|
|
let rpc_context = conv block in
|
|
|
|
lookup#call_service s (((rpc_context, a1), a2), a3) q i
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|