Proto: export Data_encoding.t
for block headers and operationss
Previously we were only exporting parsing function. This will allow to move out of the protocol some `helpers` RPCs.
This commit is contained in:
parent
afa335ff48
commit
c85e27605b
@ -7,15 +7,25 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
type operation = Operation_hash.t
|
type block_header_data = MBytes.t
|
||||||
let max_operation_data_length = 42
|
type block_header = {
|
||||||
|
shell : Block_header.shell_header ;
|
||||||
|
protocol_data : block_header_data ;
|
||||||
|
}
|
||||||
|
let block_header_data_encoding =
|
||||||
|
Data_encoding.(obj1 (req "random_data" Variable.bytes))
|
||||||
|
|
||||||
|
type operation_data = unit
|
||||||
|
type operation = {
|
||||||
|
shell : Operation.shell_header ;
|
||||||
|
protocol_data : operation_data ;
|
||||||
|
}
|
||||||
|
let operation_data_encoding = Data_encoding.unit
|
||||||
|
|
||||||
let max_block_length = 42
|
let max_block_length = 42
|
||||||
let validation_passes = []
|
let validation_passes = []
|
||||||
let acceptable_passes _op = []
|
let acceptable_passes _op = []
|
||||||
|
|
||||||
let parse_operation h _ = Ok h
|
|
||||||
|
|
||||||
let compare_operations _ _ = 0
|
let compare_operations _ _ = 0
|
||||||
|
|
||||||
type validation_state = {
|
type validation_state = {
|
||||||
@ -57,16 +67,15 @@ end
|
|||||||
let precheck_block
|
let precheck_block
|
||||||
~ancestor_context:_
|
~ancestor_context:_
|
||||||
~ancestor_timestamp:_
|
~ancestor_timestamp:_
|
||||||
raw_block =
|
(_raw_block : block_header) =
|
||||||
Fitness.to_int64 raw_block.Block_header.shell.fitness >>=? fun _ ->
|
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let begin_application
|
let begin_application
|
||||||
~predecessor_context:context
|
~predecessor_context:context
|
||||||
~predecessor_timestamp:_
|
~predecessor_timestamp:_
|
||||||
~predecessor_fitness:_
|
~predecessor_fitness:_
|
||||||
raw_block =
|
(raw_block : block_header) =
|
||||||
Fitness.to_int64 raw_block.Block_header.shell.fitness >>=? fun fitness ->
|
Fitness.to_int64 raw_block.shell.fitness >>=? fun fitness ->
|
||||||
return { context ; fitness }
|
return { context ; fitness }
|
||||||
|
|
||||||
let begin_construction
|
let begin_construction
|
||||||
|
@ -20,8 +20,8 @@ sleep 2
|
|||||||
dictator_secret="unencrypted:edsk31vznjHSSpGExDMHYASz45VZqXN4DPxvsa4hAyY8dHM28cZzp6"
|
dictator_secret="unencrypted:edsk31vznjHSSpGExDMHYASz45VZqXN4DPxvsa4hAyY8dHM28cZzp6"
|
||||||
|
|
||||||
# autogenerated from the demo source
|
# autogenerated from the demo source
|
||||||
protocol_version="Ps1ZDZdgRP4PFDkzmFpiYtE7gJHioavCMxC96i9zJsK6URwSXSJ"
|
protocol_version="PsbyjqSF59ENfaQxUcRqVa4DXjzUG8gP2NVEGiXpN3GntcXrV8Q"
|
||||||
protocol_short="Ps1ZDZdgRP4PFD"
|
protocol_short="PsbyjqSF59ENfa"
|
||||||
|
|
||||||
bake
|
bake
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ show_logs="no"
|
|||||||
sleep 2
|
sleep 2
|
||||||
|
|
||||||
# autogenerated from the demo source
|
# autogenerated from the demo source
|
||||||
protocol_version="PsxS1brZfzzXCiFwirbMtQr4X5XR6SiHQ46HajpFDdk9GBXR6vy"
|
protocol_version="PsbyjqSF59ENfaQxUcRqVa4DXjzUG8gP2NVEGiXpN3GntcXrV8Q"
|
||||||
|
|
||||||
$admin_client inject protocol "$test_dir/demo"
|
$admin_client inject protocol "$test_dir/demo"
|
||||||
$admin_client list protocols
|
$admin_client list protocols
|
||||||
|
@ -20,8 +20,8 @@ sleep 2
|
|||||||
dictator_secret="unencrypted:edsk31vznjHSSpGExDMHYASz45VZqXN4DPxvsa4hAyY8dHM28cZzp6"
|
dictator_secret="unencrypted:edsk31vznjHSSpGExDMHYASz45VZqXN4DPxvsa4hAyY8dHM28cZzp6"
|
||||||
|
|
||||||
# autogenerated from the demo source
|
# autogenerated from the demo source
|
||||||
protocol_version="Ps1ZDZdgRP4PFDkzmFpiYtE7gJHioavCMxC96i9zJsK6URwSXSJ"
|
protocol_version="PsbyjqSF59ENfaQxUcRqVa4DXjzUG8gP2NVEGiXpN3GntcXrV8Q"
|
||||||
protocol_short="Ps1ZDZdgRP4PFD"
|
protocol_short="PsbyjqSF59ENfa"
|
||||||
|
|
||||||
bake
|
bake
|
||||||
|
|
||||||
|
@ -67,13 +67,29 @@ module type PROTOCOL = sig
|
|||||||
operation's quota for each pass. *)
|
operation's quota for each pass. *)
|
||||||
val validation_passes: quota list
|
val validation_passes: quota list
|
||||||
|
|
||||||
(** The version specific type of operations. *)
|
(** The version specific type of blocks. *)
|
||||||
type operation
|
type block_header_data
|
||||||
|
|
||||||
(** The parsing / preliminary validation function for
|
(** Encoding for version specific part of block headers. *)
|
||||||
operations. Similar to {!parse_block}. *)
|
val block_header_data_encoding: block_header_data Data_encoding.t
|
||||||
val parse_operation:
|
|
||||||
Operation_hash.t -> Operation.t -> operation tzresult
|
(** A fully parsed block header. *)
|
||||||
|
type block_header = {
|
||||||
|
shell: Block_header.shell_header ;
|
||||||
|
protocol_data: block_header_data ;
|
||||||
|
}
|
||||||
|
|
||||||
|
(** The version specific type of operations. *)
|
||||||
|
type operation_data
|
||||||
|
|
||||||
|
(** Encoding for version specific part of operations. *)
|
||||||
|
val operation_data_encoding: operation_data Data_encoding.t
|
||||||
|
|
||||||
|
(** A fully parsed operation. *)
|
||||||
|
type operation = {
|
||||||
|
shell: Operation.shell_header ;
|
||||||
|
protocol_data: operation_data ;
|
||||||
|
}
|
||||||
|
|
||||||
(** The Validation passes in which an operation can appear.
|
(** The Validation passes in which an operation can appear.
|
||||||
For instance [[0]] if it only belongs to the first pass.
|
For instance [[0]] if it only belongs to the first pass.
|
||||||
@ -106,7 +122,7 @@ module type PROTOCOL = sig
|
|||||||
val precheck_block:
|
val precheck_block:
|
||||||
ancestor_context: Context.t ->
|
ancestor_context: Context.t ->
|
||||||
ancestor_timestamp: Time.t ->
|
ancestor_timestamp: Time.t ->
|
||||||
Block_header.t ->
|
block_header ->
|
||||||
unit tzresult Lwt.t
|
unit tzresult Lwt.t
|
||||||
|
|
||||||
(** The first step in a block validation sequence. Initializes a
|
(** The first step in a block validation sequence. Initializes a
|
||||||
@ -119,7 +135,7 @@ module type PROTOCOL = sig
|
|||||||
predecessor_context: Context.t ->
|
predecessor_context: Context.t ->
|
||||||
predecessor_timestamp: Time.t ->
|
predecessor_timestamp: Time.t ->
|
||||||
predecessor_fitness: Fitness.t ->
|
predecessor_fitness: Fitness.t ->
|
||||||
Block_header.t ->
|
block_header ->
|
||||||
validation_state tzresult Lwt.t
|
validation_state tzresult Lwt.t
|
||||||
|
|
||||||
(** Initializes a validation context for constructing a new block
|
(** Initializes a validation context for constructing a new block
|
||||||
@ -138,7 +154,7 @@ module type PROTOCOL = sig
|
|||||||
predecessor_fitness: Fitness.t ->
|
predecessor_fitness: Fitness.t ->
|
||||||
predecessor: Block_hash.t ->
|
predecessor: Block_hash.t ->
|
||||||
timestamp: Time.t ->
|
timestamp: Time.t ->
|
||||||
?protocol_data: MBytes.t ->
|
?protocol_data: block_header_data ->
|
||||||
unit -> validation_state tzresult Lwt.t
|
unit -> validation_state tzresult Lwt.t
|
||||||
|
|
||||||
(** Called after {!begin_application} (or {!begin_construction}) and
|
(** Called after {!begin_application} (or {!begin_construction}) and
|
||||||
|
@ -61,9 +61,18 @@ module Make (Context : CONTEXT) = struct
|
|||||||
type 'a tzresult
|
type 'a tzresult
|
||||||
val max_block_length: int
|
val max_block_length: int
|
||||||
val validation_passes: quota list
|
val validation_passes: quota list
|
||||||
type operation
|
type block_header_data
|
||||||
val parse_operation:
|
val block_header_data_encoding: block_header_data Data_encoding.t
|
||||||
Operation_hash.t -> Operation.t -> operation tzresult
|
type block_header = {
|
||||||
|
shell: Block_header.shell_header ;
|
||||||
|
protocol_data: block_header_data ;
|
||||||
|
}
|
||||||
|
type operation_data
|
||||||
|
val operation_data_encoding: operation_data Data_encoding.t
|
||||||
|
type operation = {
|
||||||
|
shell: Operation.shell_header ;
|
||||||
|
protocol_data: operation_data ;
|
||||||
|
}
|
||||||
val acceptable_passes: operation -> int list
|
val acceptable_passes: operation -> int list
|
||||||
val compare_operations: operation -> operation -> int
|
val compare_operations: operation -> operation -> int
|
||||||
type validation_state
|
type validation_state
|
||||||
@ -71,13 +80,13 @@ module Make (Context : CONTEXT) = struct
|
|||||||
val precheck_block:
|
val precheck_block:
|
||||||
ancestor_context: context ->
|
ancestor_context: context ->
|
||||||
ancestor_timestamp: Time.t ->
|
ancestor_timestamp: Time.t ->
|
||||||
Block_header.t ->
|
block_header ->
|
||||||
unit tzresult Lwt.t
|
unit tzresult Lwt.t
|
||||||
val begin_application:
|
val begin_application:
|
||||||
predecessor_context: context ->
|
predecessor_context: context ->
|
||||||
predecessor_timestamp: Time.t ->
|
predecessor_timestamp: Time.t ->
|
||||||
predecessor_fitness: Fitness.t ->
|
predecessor_fitness: Fitness.t ->
|
||||||
Block_header.t ->
|
block_header ->
|
||||||
validation_state tzresult Lwt.t
|
validation_state tzresult Lwt.t
|
||||||
val begin_construction:
|
val begin_construction:
|
||||||
predecessor_context: context ->
|
predecessor_context: context ->
|
||||||
@ -86,7 +95,7 @@ module Make (Context : CONTEXT) = struct
|
|||||||
predecessor_fitness: Fitness.t ->
|
predecessor_fitness: Fitness.t ->
|
||||||
predecessor: Block_hash.t ->
|
predecessor: Block_hash.t ->
|
||||||
timestamp: Time.t ->
|
timestamp: Time.t ->
|
||||||
?protocol_data: MBytes.t ->
|
?protocol_data: block_header_data ->
|
||||||
unit -> validation_state tzresult Lwt.t
|
unit -> validation_state tzresult Lwt.t
|
||||||
val apply_operation:
|
val apply_operation:
|
||||||
validation_state -> operation -> validation_state tzresult Lwt.t
|
validation_state -> operation -> validation_state tzresult Lwt.t
|
||||||
@ -150,7 +159,10 @@ module Make (Context : CONTEXT) = struct
|
|||||||
val wrap_error : 'a Error_monad.tzresult -> 'a tzresult
|
val wrap_error : 'a Error_monad.tzresult -> 'a tzresult
|
||||||
|
|
||||||
module Lift (P : Updater.PROTOCOL) : PROTOCOL
|
module Lift (P : Updater.PROTOCOL) : PROTOCOL
|
||||||
with type operation = P.operation
|
with type block_header_data = P.block_header_data
|
||||||
|
and type block_header = P.block_header
|
||||||
|
and type operation_data = P.operation_data
|
||||||
|
and type operation = P.operation
|
||||||
and type validation_state = P.validation_state
|
and type validation_state = P.validation_state
|
||||||
|
|
||||||
class ['block] proto_rpc_context :
|
class ['block] proto_rpc_context :
|
||||||
@ -642,7 +654,6 @@ module Make (Context : CONTEXT) = struct
|
|||||||
let apply_operation c o =
|
let apply_operation c o =
|
||||||
apply_operation c o >|= wrap_error
|
apply_operation c o >|= wrap_error
|
||||||
let finalize_block c = finalize_block c >|= wrap_error
|
let finalize_block c = finalize_block c >|= wrap_error
|
||||||
let parse_operation h b = parse_operation h b |> wrap_error
|
|
||||||
let init c bh = init c bh >|= wrap_error
|
let init c bh = init c bh >|= wrap_error
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,9 +54,18 @@ module Make (Context : CONTEXT) : sig
|
|||||||
type 'a tzresult
|
type 'a tzresult
|
||||||
val max_block_length: int
|
val max_block_length: int
|
||||||
val validation_passes: quota list
|
val validation_passes: quota list
|
||||||
type operation
|
type block_header_data
|
||||||
val parse_operation:
|
val block_header_data_encoding: block_header_data Data_encoding.t
|
||||||
Operation_hash.t -> Operation.t -> operation tzresult
|
type block_header = {
|
||||||
|
shell: Block_header.shell_header ;
|
||||||
|
protocol_data: block_header_data ;
|
||||||
|
}
|
||||||
|
type operation_data
|
||||||
|
val operation_data_encoding: operation_data Data_encoding.t
|
||||||
|
type operation = {
|
||||||
|
shell: Operation.shell_header ;
|
||||||
|
protocol_data: operation_data ;
|
||||||
|
}
|
||||||
val acceptable_passes: operation -> int list
|
val acceptable_passes: operation -> int list
|
||||||
val compare_operations: operation -> operation -> int
|
val compare_operations: operation -> operation -> int
|
||||||
type validation_state
|
type validation_state
|
||||||
@ -64,13 +73,13 @@ module Make (Context : CONTEXT) : sig
|
|||||||
val precheck_block:
|
val precheck_block:
|
||||||
ancestor_context: context ->
|
ancestor_context: context ->
|
||||||
ancestor_timestamp: Time.t ->
|
ancestor_timestamp: Time.t ->
|
||||||
Block_header.t ->
|
block_header ->
|
||||||
unit tzresult Lwt.t
|
unit tzresult Lwt.t
|
||||||
val begin_application:
|
val begin_application:
|
||||||
predecessor_context: context ->
|
predecessor_context: context ->
|
||||||
predecessor_timestamp: Time.t ->
|
predecessor_timestamp: Time.t ->
|
||||||
predecessor_fitness: Fitness.t ->
|
predecessor_fitness: Fitness.t ->
|
||||||
Block_header.t ->
|
block_header ->
|
||||||
validation_state tzresult Lwt.t
|
validation_state tzresult Lwt.t
|
||||||
val begin_construction:
|
val begin_construction:
|
||||||
predecessor_context: context ->
|
predecessor_context: context ->
|
||||||
@ -79,7 +88,7 @@ module Make (Context : CONTEXT) : sig
|
|||||||
predecessor_fitness: Fitness.t ->
|
predecessor_fitness: Fitness.t ->
|
||||||
predecessor: Block_hash.t ->
|
predecessor: Block_hash.t ->
|
||||||
timestamp: Time.t ->
|
timestamp: Time.t ->
|
||||||
?protocol_data: MBytes.t ->
|
?protocol_data: block_header_data ->
|
||||||
unit -> validation_state tzresult Lwt.t
|
unit -> validation_state tzresult Lwt.t
|
||||||
val apply_operation:
|
val apply_operation:
|
||||||
validation_state -> operation -> validation_state tzresult Lwt.t
|
validation_state -> operation -> validation_state tzresult Lwt.t
|
||||||
@ -143,7 +152,10 @@ module Make (Context : CONTEXT) : sig
|
|||||||
val wrap_error : 'a Error_monad.tzresult -> 'a tzresult
|
val wrap_error : 'a Error_monad.tzresult -> 'a tzresult
|
||||||
|
|
||||||
module Lift (P : Updater.PROTOCOL) : PROTOCOL
|
module Lift (P : Updater.PROTOCOL) : PROTOCOL
|
||||||
with type operation = P.operation
|
with type block_header_data = P.block_header_data
|
||||||
|
and type block_header = P.block_header
|
||||||
|
and type operation_data = P.operation_data
|
||||||
|
and type operation = P.operation
|
||||||
and type validation_state = P.validation_state
|
and type validation_state = P.validation_state
|
||||||
|
|
||||||
class ['block] proto_rpc_context :
|
class ['block] proto_rpc_context :
|
||||||
|
@ -142,15 +142,31 @@ let apply_block
|
|||||||
operations Proto.validation_passes >>=? fun () ->
|
operations Proto.validation_passes >>=? fun () ->
|
||||||
let operation_hashes = List.map (List.map Operation.hash) operations in
|
let operation_hashes = List.map (List.map Operation.hash) operations in
|
||||||
check_liveness chain_state pred hash operation_hashes operations >>=? fun () ->
|
check_liveness chain_state pred hash operation_hashes operations >>=? fun () ->
|
||||||
mapi2_s (fun pass -> map2_s begin fun op_hash raw ->
|
begin
|
||||||
Lwt.return (Proto.parse_operation op_hash raw)
|
match
|
||||||
|> trace (invalid_block hash (Cannot_parse_operation op_hash)) >>=? fun op ->
|
Data_encoding.Binary.of_bytes
|
||||||
let allowed_pass = Proto.acceptable_passes op in
|
Proto.block_header_data_encoding
|
||||||
fail_unless (List.mem pass allowed_pass)
|
header.protocol_data with
|
||||||
(invalid_block hash
|
| None ->
|
||||||
(Unallowed_pass { operation = op_hash ;
|
fail (invalid_block hash Cannot_parse_block_header)
|
||||||
pass ; allowed_pass } )) >>=? fun () ->
|
| Some protocol_data ->
|
||||||
return op
|
return ({ shell = header.shell ; protocol_data } : Proto.block_header)
|
||||||
|
end >>=? fun header ->
|
||||||
|
mapi2_s (fun pass -> map2_s begin fun op_hash op ->
|
||||||
|
match
|
||||||
|
Data_encoding.Binary.of_bytes
|
||||||
|
Proto.operation_data_encoding
|
||||||
|
op.Operation.proto with
|
||||||
|
| None ->
|
||||||
|
fail (invalid_block hash (Cannot_parse_operation op_hash))
|
||||||
|
| Some protocol_data ->
|
||||||
|
let op = { Proto.shell = op.shell ; protocol_data } in
|
||||||
|
let allowed_pass = Proto.acceptable_passes op in
|
||||||
|
fail_unless (List.mem pass allowed_pass)
|
||||||
|
(invalid_block hash
|
||||||
|
(Unallowed_pass { operation = op_hash ;
|
||||||
|
pass ; allowed_pass } )) >>=? fun () ->
|
||||||
|
return op
|
||||||
end)
|
end)
|
||||||
operation_hashes
|
operation_hashes
|
||||||
operations >>=? fun parsed_operations ->
|
operations >>=? fun parsed_operations ->
|
||||||
|
@ -82,6 +82,18 @@ let start_prevalidation
|
|||||||
Context.reset_test_chain
|
Context.reset_test_chain
|
||||||
predecessor_context predecessor
|
predecessor_context predecessor
|
||||||
timestamp >>= fun predecessor_context ->
|
timestamp >>= fun predecessor_context ->
|
||||||
|
begin
|
||||||
|
match protocol_data with
|
||||||
|
| None -> return None
|
||||||
|
| Some protocol_data ->
|
||||||
|
match
|
||||||
|
Data_encoding.Binary.of_bytes
|
||||||
|
Proto.block_header_data_encoding
|
||||||
|
protocol_data
|
||||||
|
with
|
||||||
|
| None -> failwith "Invalid block header"
|
||||||
|
| Some protocol_data -> return (Some protocol_data)
|
||||||
|
end >>=? fun protocol_data ->
|
||||||
Proto.begin_construction
|
Proto.begin_construction
|
||||||
~predecessor_context
|
~predecessor_context
|
||||||
~predecessor_timestamp
|
~predecessor_timestamp
|
||||||
@ -105,7 +117,13 @@ let prevalidate
|
|||||||
let ops =
|
let ops =
|
||||||
List.map
|
List.map
|
||||||
(fun (h, op) ->
|
(fun (h, op) ->
|
||||||
(h, op, Proto.parse_operation h op |> record_trace Parse_error))
|
let parsed_op =
|
||||||
|
match Data_encoding.Binary.of_bytes
|
||||||
|
Proto.operation_data_encoding
|
||||||
|
op.Operation.proto with
|
||||||
|
| None -> error Parse_error
|
||||||
|
| Some protocol_data -> Ok ({ shell = op.shell ; protocol_data }: Proto.operation) in
|
||||||
|
(h, op, parsed_op))
|
||||||
ops in
|
ops in
|
||||||
let invalid_ops =
|
let invalid_ops =
|
||||||
List.filter_map
|
List.filter_map
|
||||||
|
@ -76,6 +76,13 @@ let block _state ?(context = Context_hash.zero) ?(operations = []) (pred: State.
|
|||||||
protocol_data = MBytes.of_string name ;
|
protocol_data = MBytes.of_string name ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let parsed_block ({ shell ; protocol_data } : Block_header.t) =
|
||||||
|
let protocol_data =
|
||||||
|
Data_encoding.Binary.of_bytes_exn
|
||||||
|
Proto.block_header_data_encoding
|
||||||
|
protocol_data in
|
||||||
|
({ shell ; protocol_data } : Proto.block_header)
|
||||||
|
|
||||||
let build_valid_chain state vtbl pred names =
|
let build_valid_chain state vtbl pred names =
|
||||||
Lwt_list.fold_left_s
|
Lwt_list.fold_left_s
|
||||||
(fun pred name ->
|
(fun pred name ->
|
||||||
@ -91,7 +98,7 @@ let build_valid_chain state vtbl pred names =
|
|||||||
~predecessor_context
|
~predecessor_context
|
||||||
~predecessor_timestamp: pred_header.shell.timestamp
|
~predecessor_timestamp: pred_header.shell.timestamp
|
||||||
~predecessor_fitness: pred_header.shell.fitness
|
~predecessor_fitness: pred_header.shell.fitness
|
||||||
block >>=? fun vstate ->
|
(parsed_block block) >>=? fun vstate ->
|
||||||
(* no operations *)
|
(* no operations *)
|
||||||
Proto.finalize_block vstate
|
Proto.finalize_block vstate
|
||||||
end >>=? fun ctxt ->
|
end >>=? fun ctxt ->
|
||||||
@ -404,5 +411,5 @@ let wrap (n, f) =
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
let tests =List.map wrap tests
|
let tests = List.map wrap tests
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ type block_error =
|
|||||||
| Unallowed_pass of { operation: Operation_hash.t ;
|
| Unallowed_pass of { operation: Operation_hash.t ;
|
||||||
pass: int ;
|
pass: int ;
|
||||||
allowed_pass: int list }
|
allowed_pass: int list }
|
||||||
|
| Cannot_parse_block_header
|
||||||
|
|
||||||
let block_error_encoding =
|
let block_error_encoding =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
@ -213,6 +214,8 @@ let pp_block_error ppf = function
|
|||||||
\ while only the following passes are allowed: @[<h>%a@]"
|
\ while only the following passes are allowed: @[<h>%a@]"
|
||||||
Operation_hash.pp_short operation pass
|
Operation_hash.pp_short operation pass
|
||||||
Format.(pp_print_list pp_print_int) allowed_pass
|
Format.(pp_print_list pp_print_int) allowed_pass
|
||||||
|
| Cannot_parse_block_header ->
|
||||||
|
Format.fprintf ppf "Failed to parse the block header."
|
||||||
|
|
||||||
type error +=
|
type error +=
|
||||||
| Invalid_block of
|
| Invalid_block of
|
||||||
|
@ -30,6 +30,7 @@ type block_error =
|
|||||||
| Unallowed_pass of { operation: Operation_hash.t ;
|
| Unallowed_pass of { operation: Operation_hash.t ;
|
||||||
pass: int ;
|
pass: int ;
|
||||||
allowed_pass: int list }
|
allowed_pass: int list }
|
||||||
|
| Cannot_parse_block_header
|
||||||
|
|
||||||
type error +=
|
type error +=
|
||||||
| Invalid_block of
|
| Invalid_block of
|
||||||
|
@ -27,10 +27,13 @@ let forge_block_header
|
|||||||
cctxt block >>=? fun stamp_threshold ->
|
cctxt block >>=? fun stamp_threshold ->
|
||||||
let rec loop () =
|
let rec loop () =
|
||||||
let proof_of_work_nonce = generate_proof_of_work_nonce () in
|
let proof_of_work_nonce = generate_proof_of_work_nonce () in
|
||||||
let protocol_data : Block_header.protocol_data =
|
let contents =
|
||||||
{ priority ; seed_nonce_hash ; proof_of_work_nonce } in
|
{ Block_header.priority ; seed_nonce_hash ; proof_of_work_nonce } in
|
||||||
if Baking.check_header_proof_of_work_stamp shell protocol_data stamp_threshold then
|
if Baking.check_header_proof_of_work_stamp shell contents stamp_threshold then
|
||||||
let unsigned_header = Block_header.forge_unsigned shell protocol_data in
|
let unsigned_header =
|
||||||
|
Data_encoding.Binary.to_bytes_exn
|
||||||
|
Alpha_context.Block_header.unsigned_encoding
|
||||||
|
(shell, contents) in
|
||||||
Client_keys.append delegate_sk ~watermark:Block_header unsigned_header
|
Client_keys.append delegate_sk ~watermark:Block_header unsigned_header
|
||||||
else
|
else
|
||||||
loop () in
|
loop () in
|
||||||
@ -41,9 +44,11 @@ let empty_proof_of_work_nonce =
|
|||||||
(String.make Constants_repr.proof_of_work_nonce_size '\000')
|
(String.make Constants_repr.proof_of_work_nonce_size '\000')
|
||||||
|
|
||||||
let forge_faked_protocol_data ~priority ~seed_nonce_hash =
|
let forge_faked_protocol_data ~priority ~seed_nonce_hash =
|
||||||
Alpha_context.Block_header.forge_unsigned_protocol_data
|
Data_encoding.Binary.to_bytes_exn
|
||||||
{ priority ; seed_nonce_hash ;
|
Alpha_context.Block_header.protocol_data_encoding
|
||||||
proof_of_work_nonce = empty_proof_of_work_nonce }
|
{ contents = { priority ; seed_nonce_hash ;
|
||||||
|
proof_of_work_nonce = empty_proof_of_work_nonce } ;
|
||||||
|
signature = Signature.zero }
|
||||||
|
|
||||||
let assert_valid_operations_hash shell_header operations =
|
let assert_valid_operations_hash shell_header operations =
|
||||||
let operations_hash =
|
let operations_hash =
|
||||||
@ -95,13 +100,14 @@ let () =
|
|||||||
let classify_operations (ops: Operation.raw list) =
|
let classify_operations (ops: Operation.raw list) =
|
||||||
let t = Array.make (List.length Proto_alpha.Main.validation_passes) [] in
|
let t = Array.make (List.length Proto_alpha.Main.validation_passes) [] in
|
||||||
List.iter
|
List.iter
|
||||||
(fun op ->
|
(fun (op: Operation.raw) ->
|
||||||
match Operation.parse op with
|
match Data_encoding.Binary.of_bytes Operation.protocol_data_encoding op.proto with
|
||||||
| Ok o ->
|
| Some o ->
|
||||||
List.iter
|
List.iter
|
||||||
(fun pass -> t.(pass) <- op :: t.(pass))
|
(fun pass -> t.(pass) <- op :: t.(pass))
|
||||||
(Proto_alpha.Main.acceptable_passes o)
|
(Proto_alpha.Main.acceptable_passes
|
||||||
| Error _ -> ())
|
{ shell = op.shell ; protocol_data = o })
|
||||||
|
| None -> ())
|
||||||
ops ;
|
ops ;
|
||||||
Array.fold_right (fun ops acc -> List.rev ops :: acc) t []
|
Array.fold_right (fun ops acc -> List.rev ops :: acc) t []
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ let preapply
|
|||||||
get_branch cctxt block branch >>=? fun branch ->
|
get_branch cctxt block branch >>=? fun branch ->
|
||||||
let bytes =
|
let bytes =
|
||||||
Data_encoding.Binary.to_bytes_exn
|
Data_encoding.Binary.to_bytes_exn
|
||||||
Operation.unsigned_operation_encoding
|
Operation.unsigned_encoding
|
||||||
({ branch }, contents) in
|
({ branch }, contents) in
|
||||||
let watermark =
|
let watermark =
|
||||||
match contents with
|
match contents with
|
||||||
@ -49,8 +49,7 @@ let preapply
|
|||||||
end >>=? fun signature ->
|
end >>=? fun signature ->
|
||||||
let op =
|
let op =
|
||||||
{ shell = { branch } ;
|
{ shell = { branch } ;
|
||||||
contents ;
|
protocol_data = { contents ; signature } } in
|
||||||
signature } in
|
|
||||||
let oph = Operation.hash op in
|
let oph = Operation.hash op in
|
||||||
Block_services.hash cctxt block >>=? fun bh ->
|
Block_services.hash cctxt block >>=? fun bh ->
|
||||||
Alpha_services.Helpers.apply_operation cctxt
|
Alpha_services.Helpers.apply_operation cctxt
|
||||||
|
@ -18,7 +18,7 @@ val preapply:
|
|||||||
Block_services.block ->
|
Block_services.block ->
|
||||||
?branch:int ->
|
?branch:int ->
|
||||||
?src_sk:Client_keys.sk_uri ->
|
?src_sk:Client_keys.sk_uri ->
|
||||||
proto_operation ->
|
Operation.contents ->
|
||||||
result tzresult Lwt.t
|
result tzresult Lwt.t
|
||||||
|
|
||||||
val inject_operation:
|
val inject_operation:
|
||||||
@ -27,7 +27,7 @@ val inject_operation:
|
|||||||
?confirmations:int ->
|
?confirmations:int ->
|
||||||
?branch:int ->
|
?branch:int ->
|
||||||
?src_sk:Client_keys.sk_uri ->
|
?src_sk:Client_keys.sk_uri ->
|
||||||
proto_operation ->
|
Operation.contents ->
|
||||||
result tzresult Lwt.t
|
result tzresult Lwt.t
|
||||||
|
|
||||||
val originated_contracts: operation_result -> Contract.t list tzresult
|
val originated_contracts: operation_result -> Contract.t list tzresult
|
||||||
|
@ -134,7 +134,8 @@ let pp_balance_updates ppf = function
|
|||||||
Format.fprintf ppf "@[<v 0>%a@]"
|
Format.fprintf ppf "@[<v 0>%a@]"
|
||||||
(Format.pp_print_list pp_one) balance_updates
|
(Format.pp_print_list pp_one) balance_updates
|
||||||
|
|
||||||
let pp_operation_result ppf ({ contents ; _ }, operation_result) =
|
let pp_operation_result ppf
|
||||||
|
({ protocol_data = { contents ; _ } }, operation_result) =
|
||||||
Format.fprintf ppf "@[<v 0>" ;
|
Format.fprintf ppf "@[<v 0>" ;
|
||||||
begin match contents, operation_result with
|
begin match contents, operation_result with
|
||||||
| Anonymous_operations ops, Anonymous_operations_result rs ->
|
| Anonymous_operations ops, Anonymous_operations_result rs ->
|
||||||
|
@ -27,7 +27,11 @@ end
|
|||||||
|
|
||||||
include Operation_repr
|
include Operation_repr
|
||||||
module Operation = struct
|
module Operation = struct
|
||||||
type t = operation
|
type t = operation = {
|
||||||
|
shell: Operation.shell_header ;
|
||||||
|
protocol_data: protocol_data ;
|
||||||
|
}
|
||||||
|
let unsigned_encoding = unsigned_operation_encoding
|
||||||
include Operation_repr
|
include Operation_repr
|
||||||
end
|
end
|
||||||
module Block_header = Block_header_repr
|
module Block_header = Block_header_repr
|
||||||
|
@ -683,10 +683,14 @@ module Block_header : sig
|
|||||||
type t = {
|
type t = {
|
||||||
shell: Block_header.shell_header ;
|
shell: Block_header.shell_header ;
|
||||||
protocol_data: protocol_data ;
|
protocol_data: protocol_data ;
|
||||||
signature: Signature.t ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
and protocol_data = {
|
and protocol_data = {
|
||||||
|
contents: contents ;
|
||||||
|
signature: Signature.t ;
|
||||||
|
}
|
||||||
|
|
||||||
|
and contents = {
|
||||||
priority: int ;
|
priority: int ;
|
||||||
seed_nonce_hash: Nonce_hash.t option ;
|
seed_nonce_hash: Nonce_hash.t option ;
|
||||||
proof_of_work_nonce: MBytes.t ;
|
proof_of_work_nonce: MBytes.t ;
|
||||||
@ -702,39 +706,27 @@ module Block_header : sig
|
|||||||
|
|
||||||
val encoding: block_header Data_encoding.encoding
|
val encoding: block_header Data_encoding.encoding
|
||||||
val raw_encoding: raw Data_encoding.t
|
val raw_encoding: raw Data_encoding.t
|
||||||
|
val contents_encoding: contents Data_encoding.t
|
||||||
|
val unsigned_encoding: (shell_header * contents) Data_encoding.t
|
||||||
val protocol_data_encoding: protocol_data Data_encoding.encoding
|
val protocol_data_encoding: protocol_data Data_encoding.encoding
|
||||||
val shell_header_encoding: shell_header Data_encoding.encoding
|
val shell_header_encoding: shell_header Data_encoding.encoding
|
||||||
|
|
||||||
val max_header_length: int
|
val max_header_length: int
|
||||||
(** The maximum size of block headers in bytes *)
|
(** The maximum size of block headers in bytes *)
|
||||||
|
|
||||||
val parse: Block_header.t -> block_header tzresult
|
|
||||||
(** Parse the protocol-specific part of a block header. *)
|
|
||||||
|
|
||||||
val parse_unsigned_protocol_data: MBytes.t -> protocol_data tzresult
|
|
||||||
(** Parse the (unsigned) protocol-specific part of a block header. *)
|
|
||||||
|
|
||||||
val forge_unsigned_protocol_data: protocol_data -> MBytes.t
|
|
||||||
(** [forge_header proto_hdr] is the binary serialization
|
|
||||||
(using [protocol_data_encoding]) of the protocol-specific part
|
|
||||||
of a block header, without the signature. *)
|
|
||||||
|
|
||||||
val forge_unsigned:
|
|
||||||
Block_header.shell_header -> protocol_data -> MBytes.t
|
|
||||||
(** [forge_header shell_hdr proto_hdr] is the binary serialization
|
|
||||||
(using [unsigned_header_encoding]) of a block header,
|
|
||||||
comprising both the shell and the protocol part of the header,
|
|
||||||
without the signature. *)
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
type operation = {
|
type operation = {
|
||||||
shell: Operation.shell_header ;
|
shell: Operation.shell_header ;
|
||||||
contents: proto_operation ;
|
protocol_data: protocol_data ;
|
||||||
signature: signature option ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
and proto_operation =
|
and protocol_data = {
|
||||||
|
contents: contents ;
|
||||||
|
signature: Signature.t option ;
|
||||||
|
}
|
||||||
|
|
||||||
|
and contents =
|
||||||
| Anonymous_operations of anonymous_operation list
|
| Anonymous_operations of anonymous_operation list
|
||||||
| Sourced_operation of sourced_operation
|
| Sourced_operation of sourced_operation
|
||||||
|
|
||||||
@ -822,37 +814,35 @@ type internal_operation = {
|
|||||||
|
|
||||||
module Operation : sig
|
module Operation : sig
|
||||||
|
|
||||||
|
type nonrec contents = contents
|
||||||
|
val contents_encoding: contents Data_encoding.t
|
||||||
|
|
||||||
|
type nonrec protocol_data = protocol_data
|
||||||
|
val protocol_data_encoding: protocol_data Data_encoding.t
|
||||||
|
val unsigned_encoding: (Operation.shell_header * contents) Data_encoding.t
|
||||||
|
|
||||||
type raw = Operation.t = {
|
type raw = Operation.t = {
|
||||||
shell: Operation.shell_header ;
|
shell: Operation.shell_header ;
|
||||||
proto: MBytes.t ;
|
proto: MBytes.t ;
|
||||||
}
|
}
|
||||||
val raw_encoding: raw Data_encoding.t
|
val raw_encoding: raw Data_encoding.t
|
||||||
|
|
||||||
type t = operation
|
type t = operation = {
|
||||||
|
shell: Operation.shell_header ;
|
||||||
|
protocol_data: protocol_data ;
|
||||||
|
}
|
||||||
val encoding: operation Data_encoding.t
|
val encoding: operation Data_encoding.t
|
||||||
|
|
||||||
val hash: operation -> Operation_hash.t
|
val hash: operation -> Operation_hash.t
|
||||||
val hash_raw: raw -> Operation_hash.t
|
val hash_raw: raw -> Operation_hash.t
|
||||||
|
|
||||||
type error += Cannot_parse_operation (* `Branch *)
|
|
||||||
val parse: Operation.t -> operation tzresult
|
|
||||||
val acceptable_passes: operation -> int list
|
val acceptable_passes: operation -> int list
|
||||||
|
|
||||||
val parse_proto:
|
|
||||||
MBytes.t -> (proto_operation * signature option) tzresult Lwt.t
|
|
||||||
|
|
||||||
type error += Missing_signature (* `Permanent *)
|
type error += Missing_signature (* `Permanent *)
|
||||||
type error += Invalid_signature (* `Permanent *)
|
type error += Invalid_signature (* `Permanent *)
|
||||||
|
|
||||||
val check_signature: public_key -> operation -> unit tzresult Lwt.t
|
val check_signature: public_key -> operation -> unit tzresult Lwt.t
|
||||||
|
|
||||||
val forge: Operation.shell_header -> proto_operation -> MBytes.t
|
|
||||||
|
|
||||||
val proto_operation_encoding: proto_operation Data_encoding.t
|
|
||||||
|
|
||||||
val unsigned_operation_encoding:
|
|
||||||
(Operation.shell_header * proto_operation) Data_encoding.t
|
|
||||||
|
|
||||||
val internal_operation_encoding: internal_operation Data_encoding.t
|
val internal_operation_encoding: internal_operation Data_encoding.t
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -51,6 +51,25 @@ module S = struct
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let parse_operation (op: Operation.raw) =
|
||||||
|
match Data_encoding.Binary.of_bytes
|
||||||
|
Operation.protocol_data_encoding
|
||||||
|
op.proto with
|
||||||
|
| Some protocol_data ->
|
||||||
|
ok { shell = op.shell ; protocol_data }
|
||||||
|
| None -> error Helpers_services.Cannot_parse_operation
|
||||||
|
|
||||||
|
let parse_block_header
|
||||||
|
({ shell ; protocol_data } : Block_header.raw) : Block_header.t tzresult =
|
||||||
|
match
|
||||||
|
Data_encoding.Binary.of_bytes
|
||||||
|
Block_header.protocol_data_encoding
|
||||||
|
protocol_data
|
||||||
|
with
|
||||||
|
| None -> Error [Helpers_services.Cant_parse_block_header]
|
||||||
|
| Some protocol_data -> Ok { shell ; protocol_data }
|
||||||
|
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
let open Services_registration in
|
let open Services_registration in
|
||||||
register0_fullctxt S.operations begin fun ctxt () () ->
|
register0_fullctxt S.operations begin fun ctxt () () ->
|
||||||
@ -58,21 +77,21 @@ let () =
|
|||||||
ctxt.operations () >>= fun operations ->
|
ctxt.operations () >>= fun operations ->
|
||||||
map2_s
|
map2_s
|
||||||
(map2_s (fun h op ->
|
(map2_s (fun h op ->
|
||||||
Lwt.return (Operation.parse op) >>=? fun op ->
|
Lwt.return (parse_operation op) >>=? fun op ->
|
||||||
return (h, op)))
|
return (h, op)))
|
||||||
operation_hashes operations
|
operation_hashes operations
|
||||||
end ;
|
end ;
|
||||||
register0_fullctxt S.header begin fun { block_header ; _ } () () ->
|
register0_fullctxt S.header begin fun { block_header ; _ } () () ->
|
||||||
Lwt.return (Block_header.parse block_header) >>=? fun block_header ->
|
Lwt.return (parse_block_header block_header) >>=? fun block_header ->
|
||||||
return block_header
|
return block_header
|
||||||
end ;
|
end ;
|
||||||
register0_fullctxt S.priority begin fun { block_header ; _ } () () ->
|
register0_fullctxt S.priority begin fun { block_header ; _ } () () ->
|
||||||
Lwt.return (Block_header.parse block_header) >>=? fun block_header ->
|
Lwt.return (parse_block_header block_header) >>=? fun block_header ->
|
||||||
return block_header.protocol_data.priority
|
return block_header.protocol_data.contents.priority
|
||||||
end ;
|
end ;
|
||||||
opt_register0_fullctxt S.seed_nonce_hash begin fun { block_header ; _ } () ( )->
|
opt_register0_fullctxt S.seed_nonce_hash begin fun { block_header ; _ } () ( )->
|
||||||
Lwt.return (Block_header.parse block_header) >>=? fun block_header ->
|
Lwt.return (parse_block_header block_header) >>=? fun block_header ->
|
||||||
return block_header.protocol_data.seed_nonce_hash
|
return block_header.protocol_data.contents.seed_nonce_hash
|
||||||
end
|
end
|
||||||
|
|
||||||
let operations ctxt block =
|
let operations ctxt block =
|
||||||
|
@ -625,7 +625,7 @@ let apply_anonymous_operation ctxt kind =
|
|||||||
add_rewards ctxt seed_nonce_revelation_tip >>=? fun ctxt ->
|
add_rewards ctxt seed_nonce_revelation_tip >>=? fun ctxt ->
|
||||||
return (ctxt, Seed_nonce_revelation_result [(* FIXME *)])
|
return (ctxt, Seed_nonce_revelation_result [(* FIXME *)])
|
||||||
| Double_endorsement_evidence { op1 ; op2 } -> begin
|
| Double_endorsement_evidence { op1 ; op2 } -> begin
|
||||||
match op1.contents, op2.contents with
|
match op1.protocol_data.contents, op2.protocol_data.contents with
|
||||||
| Sourced_operation (Consensus_operation (Endorsements e1)),
|
| Sourced_operation (Consensus_operation (Endorsements e1)),
|
||||||
Sourced_operation (Consensus_operation (Endorsements e2))
|
Sourced_operation (Consensus_operation (Endorsements e2))
|
||||||
when Raw_level.(e1.level = e2.level) &&
|
when Raw_level.(e1.level = e2.level) &&
|
||||||
@ -682,10 +682,10 @@ let apply_anonymous_operation ctxt kind =
|
|||||||
last = oldest_level }) >>=? fun () ->
|
last = oldest_level }) >>=? fun () ->
|
||||||
let level = Level.from_raw ctxt raw_level in
|
let level = Level.from_raw ctxt raw_level in
|
||||||
Roll.baking_rights_owner
|
Roll.baking_rights_owner
|
||||||
ctxt level ~priority:bh1.protocol_data.priority >>=? fun delegate1 ->
|
ctxt level ~priority:bh1.protocol_data.contents.priority >>=? fun delegate1 ->
|
||||||
Baking.check_signature bh1 delegate1 >>=? fun () ->
|
Baking.check_signature bh1 delegate1 >>=? fun () ->
|
||||||
Roll.baking_rights_owner
|
Roll.baking_rights_owner
|
||||||
ctxt level ~priority:bh2.protocol_data.priority >>=? fun delegate2 ->
|
ctxt level ~priority:bh2.protocol_data.contents.priority >>=? fun delegate2 ->
|
||||||
Baking.check_signature bh2 delegate2 >>=? fun () ->
|
Baking.check_signature bh2 delegate2 >>=? fun () ->
|
||||||
fail_unless
|
fail_unless
|
||||||
(Signature.Public_key.equal delegate1 delegate2)
|
(Signature.Public_key.equal delegate1 delegate2)
|
||||||
@ -717,7 +717,7 @@ let apply_anonymous_operation ctxt kind =
|
|||||||
|
|
||||||
let apply_operation ctxt mode pred_block hash operation =
|
let apply_operation ctxt mode pred_block hash operation =
|
||||||
let ctxt = Contract.init_origination_nonce ctxt hash in
|
let ctxt = Contract.init_origination_nonce ctxt hash in
|
||||||
begin match operation.contents with
|
begin match operation.protocol_data.contents with
|
||||||
| Anonymous_operations ops ->
|
| Anonymous_operations ops ->
|
||||||
fold_left_s
|
fold_left_s
|
||||||
(fun (ctxt, acc) op ->
|
(fun (ctxt, acc) op ->
|
||||||
@ -759,9 +759,6 @@ let may_start_new_cycle ctxt =
|
|||||||
return ctxt
|
return ctxt
|
||||||
|
|
||||||
let begin_full_construction ctxt pred_timestamp protocol_data =
|
let begin_full_construction ctxt pred_timestamp protocol_data =
|
||||||
Lwt.return
|
|
||||||
(Block_header.parse_unsigned_protocol_data
|
|
||||||
protocol_data) >>=? fun protocol_data ->
|
|
||||||
Baking.check_baking_rights
|
Baking.check_baking_rights
|
||||||
ctxt protocol_data pred_timestamp >>=? fun delegate_pk ->
|
ctxt protocol_data pred_timestamp >>=? fun delegate_pk ->
|
||||||
let delegate_pkh = Signature.Public_key.hash delegate_pk in
|
let delegate_pkh = Signature.Public_key.hash delegate_pk in
|
||||||
@ -778,10 +775,10 @@ let begin_application ctxt block_header pred_timestamp =
|
|||||||
Baking.check_proof_of_work_stamp ctxt block_header >>=? fun () ->
|
Baking.check_proof_of_work_stamp ctxt block_header >>=? fun () ->
|
||||||
Baking.check_fitness_gap ctxt block_header >>=? fun () ->
|
Baking.check_fitness_gap ctxt block_header >>=? fun () ->
|
||||||
Baking.check_baking_rights
|
Baking.check_baking_rights
|
||||||
ctxt block_header.protocol_data pred_timestamp >>=? fun delegate_pk ->
|
ctxt block_header.protocol_data.contents pred_timestamp >>=? fun delegate_pk ->
|
||||||
Baking.check_signature block_header delegate_pk >>=? fun () ->
|
Baking.check_signature block_header delegate_pk >>=? fun () ->
|
||||||
let has_commitment =
|
let has_commitment =
|
||||||
match block_header.protocol_data.seed_nonce_hash with
|
match block_header.protocol_data.contents.seed_nonce_hash with
|
||||||
| None -> false
|
| None -> false
|
||||||
| Some _ -> true in
|
| Some _ -> true in
|
||||||
fail_unless
|
fail_unless
|
||||||
@ -790,7 +787,7 @@ let begin_application ctxt block_header pred_timestamp =
|
|||||||
{ expected = current_level.expected_commitment }) >>=? fun () ->
|
{ expected = current_level.expected_commitment }) >>=? fun () ->
|
||||||
let delegate_pkh = Signature.Public_key.hash delegate_pk in
|
let delegate_pkh = Signature.Public_key.hash delegate_pk in
|
||||||
Baking.freeze_baking_deposit ctxt
|
Baking.freeze_baking_deposit ctxt
|
||||||
block_header.protocol_data delegate_pkh >>=? fun (ctxt, deposit) ->
|
block_header.protocol_data.contents delegate_pkh >>=? fun (ctxt, deposit) ->
|
||||||
let ctxt = Fitness.increase ctxt in
|
let ctxt = Fitness.increase ctxt in
|
||||||
return (ctxt, delegate_pk, deposit)
|
return (ctxt, delegate_pk, deposit)
|
||||||
|
|
||||||
@ -818,7 +815,7 @@ let finalize_application ctxt protocol_data delegate =
|
|||||||
return ctxt
|
return ctxt
|
||||||
|
|
||||||
let compare_operations op1 op2 =
|
let compare_operations op1 op2 =
|
||||||
match op1.contents, op2.contents with
|
match op1.protocol_data.contents, op2.protocol_data.contents with
|
||||||
| Anonymous_operations _, Anonymous_operations _ -> 0
|
| Anonymous_operations _, Anonymous_operations _ -> 0
|
||||||
| Anonymous_operations _, Sourced_operation _ -> -1
|
| Anonymous_operations _, Sourced_operation _ -> -1
|
||||||
| Sourced_operation _, Anonymous_operations _ -> 1
|
| Sourced_operation _, Anonymous_operations _ -> 1
|
||||||
|
@ -251,25 +251,29 @@ let check_hash hash stamp_threshold =
|
|||||||
let word = MBytes.get_int64 bytes 0 in
|
let word = MBytes.get_int64 bytes 0 in
|
||||||
Compare.Uint64.(word <= stamp_threshold)
|
Compare.Uint64.(word <= stamp_threshold)
|
||||||
|
|
||||||
let check_header_proof_of_work_stamp shell protocol_data stamp_threshold =
|
let check_header_proof_of_work_stamp shell contents stamp_threshold =
|
||||||
let hash =
|
let hash =
|
||||||
Block_header.hash
|
Block_header.hash
|
||||||
{ shell ; protocol_data ; signature = Signature.zero } in
|
{ shell ; protocol_data = { contents ; signature = Signature.zero } } in
|
||||||
check_hash hash stamp_threshold
|
check_hash hash stamp_threshold
|
||||||
|
|
||||||
let check_proof_of_work_stamp ctxt block =
|
let check_proof_of_work_stamp ctxt block =
|
||||||
let proof_of_work_threshold = Constants.proof_of_work_threshold ctxt in
|
let proof_of_work_threshold = Constants.proof_of_work_threshold ctxt in
|
||||||
if check_header_proof_of_work_stamp
|
if check_header_proof_of_work_stamp
|
||||||
block.Block_header.shell
|
block.Block_header.shell
|
||||||
block.protocol_data
|
block.protocol_data.contents
|
||||||
proof_of_work_threshold then
|
proof_of_work_threshold then
|
||||||
return ()
|
return ()
|
||||||
else
|
else
|
||||||
fail Invalid_stamp
|
fail Invalid_stamp
|
||||||
|
|
||||||
let check_signature block key =
|
let check_signature block key =
|
||||||
let check_signature key { Block_header.protocol_data ; shell ; signature } =
|
let check_signature key
|
||||||
let unsigned_header = Block_header.forge_unsigned shell protocol_data in
|
{ Block_header.shell ; protocol_data = { contents ; signature } } =
|
||||||
|
let unsigned_header =
|
||||||
|
Data_encoding.Binary.to_bytes_exn
|
||||||
|
Block_header.unsigned_encoding
|
||||||
|
(shell, contents) in
|
||||||
Signature.check ~watermark:Block_header key signature unsigned_header in
|
Signature.check ~watermark:Block_header key signature unsigned_header in
|
||||||
if check_signature key block then
|
if check_signature key block then
|
||||||
return ()
|
return ()
|
||||||
|
@ -39,7 +39,7 @@ val minimal_time: context -> int -> Time.t -> Time.t tzresult Lwt.t
|
|||||||
funds to claim baking rights. *)
|
funds to claim baking rights. *)
|
||||||
val freeze_baking_deposit:
|
val freeze_baking_deposit:
|
||||||
context ->
|
context ->
|
||||||
Block_header.protocol_data ->
|
Block_header.contents ->
|
||||||
public_key_hash ->
|
public_key_hash ->
|
||||||
(context * Tez.t) tzresult Lwt.t
|
(context * Tez.t) tzresult Lwt.t
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ val freeze_endorsement_deposit:
|
|||||||
* the deposit have been payed if the slot is below [Constants.first_free_baking_slot].
|
* the deposit have been payed if the slot is below [Constants.first_free_baking_slot].
|
||||||
*)
|
*)
|
||||||
val check_baking_rights:
|
val check_baking_rights:
|
||||||
context -> Block_header.protocol_data -> Time.t ->
|
context -> Block_header.contents -> Time.t ->
|
||||||
public_key tzresult Lwt.t
|
public_key tzresult Lwt.t
|
||||||
|
|
||||||
(** [check_endorsements_rights c slots]:
|
(** [check_endorsements_rights c slots]:
|
||||||
@ -108,7 +108,7 @@ val check_signature: Block_header.t -> public_key -> unit tzresult Lwt.t
|
|||||||
is does not impact the proof-of-work stamp. The stamp is checked on
|
is does not impact the proof-of-work stamp. The stamp is checked on
|
||||||
the hash of a block header whose signature has been zeroed-out. *)
|
the hash of a block header whose signature has been zeroed-out. *)
|
||||||
val check_header_proof_of_work_stamp:
|
val check_header_proof_of_work_stamp:
|
||||||
Block_header.shell_header -> Block_header.protocol_data -> int64 -> bool
|
Block_header.shell_header -> Block_header.contents -> int64 -> bool
|
||||||
|
|
||||||
(** verify if the proof of work stamp is valid *)
|
(** verify if the proof of work stamp is valid *)
|
||||||
val check_proof_of_work_stamp:
|
val check_proof_of_work_stamp:
|
||||||
|
@ -9,14 +9,17 @@
|
|||||||
|
|
||||||
(** Block header *)
|
(** Block header *)
|
||||||
|
|
||||||
(** Exported type *)
|
|
||||||
type t = {
|
type t = {
|
||||||
shell: Block_header.shell_header ;
|
shell: Block_header.shell_header ;
|
||||||
protocol_data: protocol_data ;
|
protocol_data: protocol_data ;
|
||||||
signature: Signature.t ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
and protocol_data = {
|
and protocol_data = {
|
||||||
|
contents: contents ;
|
||||||
|
signature: Signature.t ;
|
||||||
|
}
|
||||||
|
|
||||||
|
and contents = {
|
||||||
priority: int ;
|
priority: int ;
|
||||||
seed_nonce_hash: Nonce_hash.t option ;
|
seed_nonce_hash: Nonce_hash.t option ;
|
||||||
proof_of_work_nonce: MBytes.t ;
|
proof_of_work_nonce: MBytes.t ;
|
||||||
@ -30,7 +33,7 @@ type shell_header = Block_header.shell_header
|
|||||||
let raw_encoding = Block_header.encoding
|
let raw_encoding = Block_header.encoding
|
||||||
let shell_header_encoding = Block_header.shell_header_encoding
|
let shell_header_encoding = Block_header.shell_header_encoding
|
||||||
|
|
||||||
let protocol_data_encoding =
|
let contents_encoding =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
conv
|
conv
|
||||||
(fun { priority ; seed_nonce_hash ; proof_of_work_nonce } ->
|
(fun { priority ; seed_nonce_hash ; proof_of_work_nonce } ->
|
||||||
@ -43,28 +46,31 @@ let protocol_data_encoding =
|
|||||||
(Fixed.bytes Constants_repr.proof_of_work_nonce_size))
|
(Fixed.bytes Constants_repr.proof_of_work_nonce_size))
|
||||||
(opt "seed_nonce_hash" Nonce_hash.encoding))
|
(opt "seed_nonce_hash" Nonce_hash.encoding))
|
||||||
|
|
||||||
let signed_protocol_data_encoding =
|
let protocol_data_encoding =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
merge_objs
|
conv
|
||||||
protocol_data_encoding
|
(fun { contents ; signature } -> (contents, signature))
|
||||||
(obj1 (req "signature" Signature.encoding))
|
(fun (contents, signature) -> { contents ; signature })
|
||||||
|
(merge_objs
|
||||||
|
contents_encoding
|
||||||
|
(obj1 (req "signature" Signature.encoding)))
|
||||||
|
|
||||||
let unsigned_header_encoding =
|
let unsigned_encoding =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
merge_objs
|
merge_objs
|
||||||
Block_header.shell_header_encoding
|
Block_header.shell_header_encoding
|
||||||
protocol_data_encoding
|
contents_encoding
|
||||||
|
|
||||||
let encoding =
|
let encoding =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
conv
|
conv
|
||||||
(fun { shell ; protocol_data ; signature } ->
|
(fun { shell ; protocol_data } ->
|
||||||
(shell, (protocol_data, signature)))
|
(shell, protocol_data))
|
||||||
(fun (shell, (protocol_data, signature)) ->
|
(fun (shell, protocol_data) ->
|
||||||
{ shell ; protocol_data ; signature })
|
{ shell ; protocol_data })
|
||||||
(merge_objs
|
(merge_objs
|
||||||
Block_header.shell_header_encoding
|
Block_header.shell_header_encoding
|
||||||
signed_protocol_data_encoding)
|
protocol_data_encoding)
|
||||||
|
|
||||||
(** Constants *)
|
(** Constants *)
|
||||||
|
|
||||||
@ -74,47 +80,16 @@ let max_header_length =
|
|||||||
MBytes.create Constants_repr.proof_of_work_nonce_size ;
|
MBytes.create Constants_repr.proof_of_work_nonce_size ;
|
||||||
seed_nonce_hash = Some Nonce_hash.zero } in
|
seed_nonce_hash = Some Nonce_hash.zero } in
|
||||||
Data_encoding.Binary.length
|
Data_encoding.Binary.length
|
||||||
signed_protocol_data_encoding
|
protocol_data_encoding
|
||||||
(fake, Signature.zero)
|
{ contents = fake ; signature = Signature.zero}
|
||||||
|
|
||||||
|
|
||||||
(** Header parsing entry point *)
|
(** Header parsing entry point *)
|
||||||
|
|
||||||
type error +=
|
|
||||||
| Cant_parse_protocol_data
|
|
||||||
|
|
||||||
let parse
|
|
||||||
({ shell = { level ; proto_level ; predecessor ;
|
|
||||||
timestamp ; fitness ; validation_passes ; operations_hash ;
|
|
||||||
context } ;
|
|
||||||
protocol_data } : Block_header.t) : block_header tzresult =
|
|
||||||
match
|
|
||||||
Data_encoding.Binary.of_bytes signed_protocol_data_encoding protocol_data
|
|
||||||
with
|
|
||||||
| None -> Error [Cant_parse_protocol_data]
|
|
||||||
| Some (protocol_data, signature) ->
|
|
||||||
let shell =
|
|
||||||
{ Block_header.level ; proto_level ; predecessor ;
|
|
||||||
timestamp ; fitness ; validation_passes ; operations_hash ;
|
|
||||||
context } in
|
|
||||||
Ok { shell ; protocol_data ; signature }
|
|
||||||
|
|
||||||
let parse_unsigned_protocol_data bytes =
|
|
||||||
match Data_encoding.Binary.of_bytes protocol_data_encoding bytes with
|
|
||||||
| None -> Error [Cant_parse_protocol_data]
|
|
||||||
| Some proto -> Ok proto
|
|
||||||
|
|
||||||
let forge_unsigned shell proto =
|
|
||||||
Data_encoding.Binary.to_bytes_exn unsigned_header_encoding (shell, proto)
|
|
||||||
|
|
||||||
let forge_unsigned_protocol_data proto =
|
|
||||||
Data_encoding.Binary.to_bytes_exn protocol_data_encoding proto
|
|
||||||
|
|
||||||
let hash_raw = Block_header.hash
|
let hash_raw = Block_header.hash
|
||||||
let hash { shell ; protocol_data ; signature } =
|
let hash { shell ; protocol_data } =
|
||||||
Block_header.hash
|
Block_header.hash
|
||||||
{ shell ;
|
{ shell ;
|
||||||
protocol_data =
|
protocol_data =
|
||||||
Data_encoding.Binary.to_bytes_exn
|
Data_encoding.Binary.to_bytes_exn
|
||||||
signed_protocol_data_encoding
|
protocol_data_encoding
|
||||||
(protocol_data, signature ) }
|
protocol_data }
|
||||||
|
@ -7,14 +7,17 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
(** Exported type *)
|
|
||||||
type t = {
|
type t = {
|
||||||
shell: Block_header.shell_header ;
|
shell: Block_header.shell_header ;
|
||||||
protocol_data: protocol_data ;
|
protocol_data: protocol_data ;
|
||||||
signature: Signature.t ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
and protocol_data = {
|
and protocol_data = {
|
||||||
|
contents: contents ;
|
||||||
|
signature: Signature.t ;
|
||||||
|
}
|
||||||
|
|
||||||
|
and contents = {
|
||||||
priority: int ;
|
priority: int ;
|
||||||
seed_nonce_hash: Nonce_hash.t option ;
|
seed_nonce_hash: Nonce_hash.t option ;
|
||||||
proof_of_work_nonce: MBytes.t ;
|
proof_of_work_nonce: MBytes.t ;
|
||||||
@ -27,29 +30,13 @@ type shell_header = Block_header.shell_header
|
|||||||
|
|
||||||
val encoding: block_header Data_encoding.encoding
|
val encoding: block_header Data_encoding.encoding
|
||||||
val raw_encoding: raw Data_encoding.t
|
val raw_encoding: raw Data_encoding.t
|
||||||
|
val contents_encoding: contents Data_encoding.t
|
||||||
|
val unsigned_encoding: (Block_header.shell_header * contents) Data_encoding.t
|
||||||
val protocol_data_encoding: protocol_data Data_encoding.encoding
|
val protocol_data_encoding: protocol_data Data_encoding.encoding
|
||||||
val shell_header_encoding: shell_header Data_encoding.encoding
|
val shell_header_encoding: shell_header Data_encoding.encoding
|
||||||
|
|
||||||
val max_header_length: int
|
val max_header_length: int
|
||||||
(** The maximum size of block headers in bytes *)
|
(** The maximum size of block headers in bytes *)
|
||||||
|
|
||||||
val parse: Block_header.t -> block_header tzresult
|
|
||||||
(** Parse the (signed) protocol-specific part of a block header. *)
|
|
||||||
|
|
||||||
val parse_unsigned_protocol_data: MBytes.t -> protocol_data tzresult
|
|
||||||
(** Parse the (unsigned) protocol-specific part of a block header. *)
|
|
||||||
|
|
||||||
val forge_unsigned_protocol_data: protocol_data -> MBytes.t
|
|
||||||
(** [forge_header proto_hdr] is the binary serialization
|
|
||||||
(using [protocol_data_encoding]) of the protocol-specific part
|
|
||||||
of a block header, without the signature. *)
|
|
||||||
|
|
||||||
val forge_unsigned:
|
|
||||||
Block_header.shell_header -> protocol_data -> MBytes.t
|
|
||||||
(** [forge_header shell_hdr proto_hdr] is the binary serialization
|
|
||||||
(using [unsigned_header_encoding]) of a block header,
|
|
||||||
comprising both the shell and the protocol part of the header,
|
|
||||||
without the signature. *)
|
|
||||||
|
|
||||||
val hash: block_header -> Block_hash.t
|
val hash: block_header -> Block_hash.t
|
||||||
val hash_raw: raw -> Block_hash.t
|
val hash_raw: raw -> Block_hash.t
|
||||||
|
@ -9,6 +9,31 @@
|
|||||||
|
|
||||||
open Alpha_context
|
open Alpha_context
|
||||||
|
|
||||||
|
type error +=
|
||||||
|
| Cannot_parse_operation (* `Branch *)
|
||||||
|
| Cant_parse_block_header
|
||||||
|
|
||||||
|
let () =
|
||||||
|
register_error_kind
|
||||||
|
`Branch
|
||||||
|
~id:"operation.cannot_parse"
|
||||||
|
~title:"Cannot parse operation"
|
||||||
|
~description:"The operation is ill-formed \
|
||||||
|
or for another protocol version"
|
||||||
|
~pp:(fun ppf () ->
|
||||||
|
Format.fprintf ppf "The operation cannot be parsed")
|
||||||
|
Data_encoding.unit
|
||||||
|
(function Cannot_parse_operation -> Some () | _ -> None)
|
||||||
|
(fun () -> Cannot_parse_operation)
|
||||||
|
|
||||||
|
let parse_operation (op: Operation.raw) =
|
||||||
|
match Data_encoding.Binary.of_bytes
|
||||||
|
Operation.protocol_data_encoding
|
||||||
|
op.proto with
|
||||||
|
| Some protocol_data ->
|
||||||
|
ok { shell = op.shell ; protocol_data }
|
||||||
|
| None -> error Cannot_parse_operation
|
||||||
|
|
||||||
module S = struct
|
module S = struct
|
||||||
|
|
||||||
open Data_encoding
|
open Data_encoding
|
||||||
@ -135,13 +160,14 @@ module I = struct
|
|||||||
let apply_operation ctxt () (pred_block, hash, forged_operation, signature) =
|
let apply_operation ctxt () (pred_block, hash, forged_operation, signature) =
|
||||||
(* ctxt accept_failing_script baker_contract pred_block block_prio operation *)
|
(* ctxt accept_failing_script baker_contract pred_block block_prio operation *)
|
||||||
match Data_encoding.Binary.of_bytes
|
match Data_encoding.Binary.of_bytes
|
||||||
Operation.unsigned_operation_encoding
|
Operation.unsigned_encoding
|
||||||
forged_operation with
|
forged_operation with
|
||||||
| None -> Error_monad.fail Operation.Cannot_parse_operation
|
| None -> fail Cannot_parse_operation
|
||||||
| Some (shell, contents) ->
|
| Some (shell, contents) ->
|
||||||
let operation = { shell ; contents ; signature } in
|
let operation = { shell ; protocol_data = { contents ; signature } } in
|
||||||
Apply.apply_operation ctxt Readable pred_block hash operation
|
Apply.apply_operation
|
||||||
>>=? fun (_, result) -> return result
|
ctxt Readable pred_block hash operation >>=? fun (_, result) ->
|
||||||
|
return result
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -259,7 +285,7 @@ module Forge = struct
|
|||||||
RPC_service.post_service
|
RPC_service.post_service
|
||||||
~description:"Forge an operation"
|
~description:"Forge an operation"
|
||||||
~query: RPC_query.empty
|
~query: RPC_query.empty
|
||||||
~input: Operation.unsigned_operation_encoding
|
~input: Operation.unsigned_encoding
|
||||||
~output:
|
~output:
|
||||||
(obj1
|
(obj1
|
||||||
(req "operation" bytes))
|
(req "operation" bytes))
|
||||||
@ -289,11 +315,13 @@ module Forge = struct
|
|||||||
let () =
|
let () =
|
||||||
let open Services_registration in
|
let open Services_registration in
|
||||||
register0_noctxt S.operations begin fun () (shell, proto) ->
|
register0_noctxt S.operations begin fun () (shell, proto) ->
|
||||||
return (Operation.forge shell proto)
|
return (Data_encoding.Binary.to_bytes_exn
|
||||||
|
Operation.unsigned_encoding (shell, proto))
|
||||||
end ;
|
end ;
|
||||||
register0_noctxt S.protocol_data begin fun ()
|
register0_noctxt S.protocol_data begin fun ()
|
||||||
(priority, seed_nonce_hash, proof_of_work_nonce) ->
|
(priority, seed_nonce_hash, proof_of_work_nonce) ->
|
||||||
return (Block_header.forge_unsigned_protocol_data
|
return (Data_encoding.Binary.to_bytes_exn
|
||||||
|
Block_header.contents_encoding
|
||||||
{ priority ; seed_nonce_hash ; proof_of_work_nonce })
|
{ priority ; seed_nonce_hash ; proof_of_work_nonce })
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -489,37 +517,47 @@ module Parse = struct
|
|||||||
Roll.delegate_pubkey ctxt manager
|
Roll.delegate_pubkey ctxt manager
|
||||||
end >>=? fun public_key ->
|
end >>=? fun public_key ->
|
||||||
Operation.check_signature public_key
|
Operation.check_signature public_key
|
||||||
{ signature ; shell ; contents }
|
{ shell ; protocol_data = { contents ; signature } }
|
||||||
| Sourced_operation (Consensus_operation (Endorsements { level ; slots ; _ })) ->
|
| Sourced_operation (Consensus_operation (Endorsements { level ; slots ; _ })) ->
|
||||||
let level = Level.from_raw ctxt level in
|
let level = Level.from_raw ctxt level in
|
||||||
Baking.check_endorsements_rights ctxt level slots >>=? fun public_key ->
|
Baking.check_endorsements_rights ctxt level slots >>=? fun public_key ->
|
||||||
Operation.check_signature public_key
|
Operation.check_signature public_key
|
||||||
{ signature ; shell ; contents }
|
{ shell ; protocol_data = { contents ; signature } }
|
||||||
| Sourced_operation (Amendment_operation { source ; _ }) ->
|
| Sourced_operation (Amendment_operation { source ; _ }) ->
|
||||||
Roll.delegate_pubkey ctxt source >>=? fun source ->
|
Roll.delegate_pubkey ctxt source >>=? fun source ->
|
||||||
Operation.check_signature source
|
Operation.check_signature source
|
||||||
{ signature ; shell ; contents }
|
{ shell ; protocol_data = { contents ; signature } }
|
||||||
| Sourced_operation (Dictator_operation _) ->
|
| Sourced_operation (Dictator_operation _) ->
|
||||||
let key = Constants.dictator_pubkey ctxt in
|
let key = Constants.dictator_pubkey ctxt in
|
||||||
Operation.check_signature key
|
Operation.check_signature key
|
||||||
{ signature ; shell ; contents }
|
{ shell ; protocol_data = { contents ; signature } }
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let parse_protocol_data protocol_data =
|
||||||
|
match
|
||||||
|
Data_encoding.Binary.of_bytes
|
||||||
|
Block_header.protocol_data_encoding
|
||||||
|
protocol_data
|
||||||
|
with
|
||||||
|
| None -> failwith "Cant_parse_protocol_data"
|
||||||
|
| Some protocol_data -> return protocol_data
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
let open Services_registration in
|
let open Services_registration in
|
||||||
register0 S.operations begin fun ctxt () (operations, check) ->
|
register0 S.operations begin fun ctxt () (operations, check) ->
|
||||||
map_s begin fun raw ->
|
map_s begin fun raw ->
|
||||||
Lwt.return (Operation.parse raw) >>=? fun op ->
|
Lwt.return (parse_operation raw) >>=? fun op ->
|
||||||
begin match check with
|
begin match check with
|
||||||
| Some true -> I.check_signature ctxt op.signature op.shell op.contents
|
| Some true ->
|
||||||
|
I.check_signature ctxt
|
||||||
|
op.protocol_data.signature op.shell op.protocol_data.contents
|
||||||
| Some false | None -> return ()
|
| Some false | None -> return ()
|
||||||
end >>|? fun () -> op
|
end >>|? fun () -> op
|
||||||
end operations
|
end operations
|
||||||
end ;
|
end ;
|
||||||
register0_noctxt S.block begin fun () raw_block ->
|
register0_noctxt S.block begin fun () raw_block ->
|
||||||
Lwt.return (Block_header.parse raw_block) >>=? fun { protocol_data ; _ } ->
|
parse_protocol_data raw_block.protocol_data
|
||||||
return protocol_data
|
|
||||||
end
|
end
|
||||||
|
|
||||||
let operations ctxt block ?check operations =
|
let operations ctxt block ?check operations =
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
|
|
||||||
open Alpha_context
|
open Alpha_context
|
||||||
|
|
||||||
|
type error +=
|
||||||
|
| Cannot_parse_operation (* `Branch *)
|
||||||
|
| Cant_parse_block_header
|
||||||
|
|
||||||
val minimal_time:
|
val minimal_time:
|
||||||
'a #RPC_context.simple ->
|
'a #RPC_context.simple ->
|
||||||
?priority:int -> 'a -> Time.t shell_tzresult Lwt.t
|
?priority:int -> 'a -> Time.t shell_tzresult Lwt.t
|
||||||
|
@ -9,9 +9,22 @@
|
|||||||
|
|
||||||
(* Tezos Protocol Implementation - Protocol Signature Instance *)
|
(* Tezos Protocol Implementation - Protocol Signature Instance *)
|
||||||
|
|
||||||
type operation = Alpha_context.operation
|
type block_header_data = Alpha_context.Block_header.protocol_data
|
||||||
|
type block_header = Alpha_context.Block_header.t = {
|
||||||
|
shell: Block_header.shell_header ;
|
||||||
|
protocol_data: block_header_data ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let block_header_data_encoding = Alpha_context.Block_header.protocol_data_encoding
|
||||||
|
|
||||||
|
type operation_data = Alpha_context.Operation.protocol_data
|
||||||
|
type operation = Alpha_context.Operation.t = {
|
||||||
|
shell: Operation.shell_header ;
|
||||||
|
protocol_data: operation_data ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let operation_data_encoding = Alpha_context.Operation.protocol_data_encoding
|
||||||
|
|
||||||
let parse_operation _hash op = Alpha_context.Operation.parse op
|
|
||||||
let acceptable_passes = Alpha_context.Operation.acceptable_passes
|
let acceptable_passes = Alpha_context.Operation.acceptable_passes
|
||||||
|
|
||||||
let max_block_length =
|
let max_block_length =
|
||||||
@ -36,7 +49,7 @@ type validation_mode =
|
|||||||
}
|
}
|
||||||
| Full_construction of {
|
| Full_construction of {
|
||||||
predecessor : Block_hash.t ;
|
predecessor : Block_hash.t ;
|
||||||
protocol_data : Alpha_context.Block_header.protocol_data ;
|
protocol_data : Alpha_context.Block_header.contents ;
|
||||||
baker : Alpha_context.public_key_hash ;
|
baker : Alpha_context.public_key_hash ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,17 +66,15 @@ let current_context { ctxt ; _ } =
|
|||||||
let precheck_block
|
let precheck_block
|
||||||
~ancestor_context:_
|
~ancestor_context:_
|
||||||
~ancestor_timestamp:_
|
~ancestor_timestamp:_
|
||||||
raw_block =
|
_block_header =
|
||||||
Lwt.return (Alpha_context.Block_header.parse raw_block) >>=? fun _ ->
|
(* TODO: decide what properties should be checked *)
|
||||||
(* TODO: decide what other properties should be checked *)
|
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let begin_application
|
let begin_application
|
||||||
~predecessor_context:ctxt
|
~predecessor_context:ctxt
|
||||||
~predecessor_timestamp:pred_timestamp
|
~predecessor_timestamp:pred_timestamp
|
||||||
~predecessor_fitness:pred_fitness
|
~predecessor_fitness:pred_fitness
|
||||||
raw_block =
|
(block_header : Alpha_context.Block_header.t) =
|
||||||
Lwt.return (Alpha_context.Block_header.parse raw_block) >>=? fun block_header ->
|
|
||||||
let level = block_header.shell.level in
|
let level = block_header.shell.level in
|
||||||
let fitness = pred_fitness in
|
let fitness = pred_fitness in
|
||||||
let timestamp = block_header.shell.timestamp in
|
let timestamp = block_header.shell.timestamp in
|
||||||
@ -80,7 +91,7 @@ let begin_construction
|
|||||||
~predecessor_fitness:pred_fitness
|
~predecessor_fitness:pred_fitness
|
||||||
~predecessor
|
~predecessor
|
||||||
~timestamp
|
~timestamp
|
||||||
?protocol_data
|
?(protocol_data : block_header_data option)
|
||||||
() =
|
() =
|
||||||
let level = Int32.succ pred_level in
|
let level = Int32.succ pred_level in
|
||||||
let fitness = pred_fitness in
|
let fitness = pred_fitness in
|
||||||
@ -94,7 +105,7 @@ let begin_construction
|
|||||||
| Some proto_header ->
|
| Some proto_header ->
|
||||||
Apply.begin_full_construction
|
Apply.begin_full_construction
|
||||||
ctxt pred_timestamp
|
ctxt pred_timestamp
|
||||||
proto_header >>=? fun (ctxt, protocol_data, baker, deposit) ->
|
proto_header.contents >>=? fun (ctxt, protocol_data, baker, deposit) ->
|
||||||
let mode =
|
let mode =
|
||||||
let baker = Signature.Public_key.hash baker in
|
let baker = Signature.Public_key.hash baker in
|
||||||
Full_construction { predecessor ; baker ; protocol_data } in
|
Full_construction { predecessor ; baker ; protocol_data } in
|
||||||
@ -121,7 +132,7 @@ let finalize_block { mode ; ctxt ; op_count ; deposit = _ } =
|
|||||||
let ctxt = Alpha_context.finalize ctxt in
|
let ctxt = Alpha_context.finalize ctxt in
|
||||||
return ctxt
|
return ctxt
|
||||||
| Application
|
| Application
|
||||||
{ baker ; block_header = { protocol_data ; _ } }
|
{ baker ; block_header = { protocol_data = { contents = protocol_data ; _ } ; _ } }
|
||||||
| Full_construction { protocol_data ; baker ; _ } ->
|
| Full_construction { protocol_data ; baker ; _ } ->
|
||||||
Apply.finalize_application ctxt protocol_data baker >>=? fun ctxt ->
|
Apply.finalize_application ctxt protocol_data baker >>=? fun ctxt ->
|
||||||
let { level ; _ } : Alpha_context.Level.t =
|
let { level ; _ } : Alpha_context.Level.t =
|
||||||
|
@ -19,7 +19,7 @@ type validation_mode =
|
|||||||
}
|
}
|
||||||
| Full_construction of {
|
| Full_construction of {
|
||||||
predecessor : Block_hash.t ;
|
predecessor : Block_hash.t ;
|
||||||
protocol_data : Alpha_context.Block_header.protocol_data ;
|
protocol_data : Alpha_context.Block_header.contents ;
|
||||||
baker : Alpha_context.public_key_hash ;
|
baker : Alpha_context.public_key_hash ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,5 +30,8 @@ type validation_state =
|
|||||||
deposit : Alpha_context.Tez.t ;
|
deposit : Alpha_context.Tez.t ;
|
||||||
}
|
}
|
||||||
|
|
||||||
include Updater.PROTOCOL with type operation = Alpha_context.Operation.t
|
include Updater.PROTOCOL with type block_header_data = Alpha_context.Block_header.protocol_data
|
||||||
|
and type block_header = Alpha_context.Block_header.t
|
||||||
|
and type operation_data = Alpha_context.Operation.protocol_data
|
||||||
|
and type operation = Alpha_context.operation
|
||||||
and type validation_state := validation_state
|
and type validation_state := validation_state
|
||||||
|
@ -18,11 +18,15 @@ let raw_encoding = Operation.encoding
|
|||||||
|
|
||||||
type operation = {
|
type operation = {
|
||||||
shell: Operation.shell_header ;
|
shell: Operation.shell_header ;
|
||||||
contents: proto_operation ;
|
protocol_data: protocol_data ;
|
||||||
|
}
|
||||||
|
|
||||||
|
and protocol_data = {
|
||||||
|
contents: contents ;
|
||||||
signature: Signature.t option ;
|
signature: Signature.t option ;
|
||||||
}
|
}
|
||||||
|
|
||||||
and proto_operation =
|
and contents =
|
||||||
| Anonymous_operations of anonymous_operation list
|
| Anonymous_operations of anonymous_operation list
|
||||||
| Sourced_operation of sourced_operation
|
| Sourced_operation of sourced_operation
|
||||||
|
|
||||||
@ -307,7 +311,7 @@ module Encoding = struct
|
|||||||
(function Dictator_operation op -> Some op | _ -> None)
|
(function Dictator_operation op -> Some op | _ -> None)
|
||||||
(fun op -> Dictator_operation op)
|
(fun op -> Dictator_operation op)
|
||||||
|
|
||||||
let signed_operations_case tag =
|
let sourced_operation_case tag =
|
||||||
case tag
|
case tag
|
||||||
(union [
|
(union [
|
||||||
consensus_kind_case (Tag 0) ;
|
consensus_kind_case (Tag 0) ;
|
||||||
@ -374,7 +378,7 @@ module Encoding = struct
|
|||||||
)
|
)
|
||||||
(fun ((), id, secret) -> Activation { id ; secret })
|
(fun ((), id, secret) -> Activation { id ; secret })
|
||||||
|
|
||||||
let unsigned_operation_case tag op_encoding =
|
let anonymous_operations_case tag op_encoding =
|
||||||
case tag
|
case tag
|
||||||
(obj1
|
(obj1
|
||||||
(req "operations"
|
(req "operations"
|
||||||
@ -388,40 +392,42 @@ module Encoding = struct
|
|||||||
(function Anonymous_operations ops -> Some ops | _ -> None)
|
(function Anonymous_operations ops -> Some ops | _ -> None)
|
||||||
(fun ops -> Anonymous_operations ops)
|
(fun ops -> Anonymous_operations ops)
|
||||||
|
|
||||||
let mu_proto_operation_encoding op_encoding =
|
let contents_encoding op_encoding =
|
||||||
union [
|
union [
|
||||||
signed_operations_case (Tag 0) ;
|
sourced_operation_case (Tag 0) ;
|
||||||
unsigned_operation_case (Tag 1) op_encoding ;
|
anonymous_operations_case (Tag 1) op_encoding ;
|
||||||
]
|
]
|
||||||
|
|
||||||
let mu_signed_proto_operation_encoding op_encoding =
|
let protocol_data_encoding op_encoding =
|
||||||
merge_objs
|
conv
|
||||||
(mu_proto_operation_encoding op_encoding)
|
(fun { contents ; signature } -> (contents, signature))
|
||||||
(obj1 (varopt "signature" Signature.encoding))
|
(fun (contents, signature) -> { contents ; signature })
|
||||||
|
(merge_objs
|
||||||
|
(contents_encoding op_encoding)
|
||||||
|
(obj1 (varopt "signature" Signature.encoding)))
|
||||||
|
|
||||||
let operation_encoding =
|
let operation_encoding =
|
||||||
mu "operation"
|
mu "operation"
|
||||||
(fun encoding ->
|
(fun encoding ->
|
||||||
conv
|
conv
|
||||||
(fun { shell ; contents ; signature } ->
|
(fun { shell ; protocol_data } -> (shell, protocol_data))
|
||||||
(shell, (contents, signature)))
|
(fun (shell, protocol_data) -> { shell ; protocol_data })
|
||||||
(fun (shell, (contents, signature)) ->
|
|
||||||
{ shell ; contents ; signature })
|
|
||||||
(merge_objs
|
(merge_objs
|
||||||
Operation.shell_header_encoding
|
Operation.shell_header_encoding
|
||||||
(mu_signed_proto_operation_encoding encoding)))
|
(protocol_data_encoding encoding)))
|
||||||
|
|
||||||
let proto_operation_encoding =
|
|
||||||
mu_proto_operation_encoding operation_encoding
|
|
||||||
|
|
||||||
let signed_proto_operation_encoding =
|
let contents_encoding =
|
||||||
mu_signed_proto_operation_encoding operation_encoding
|
contents_encoding operation_encoding
|
||||||
|
|
||||||
|
let protocol_data_encoding =
|
||||||
|
protocol_data_encoding operation_encoding
|
||||||
|
|
||||||
let unsigned_operation_encoding =
|
let unsigned_operation_encoding =
|
||||||
def "operation.alpha.unsigned_operation" @@
|
def "operation.alpha.unsigned_operation" @@
|
||||||
merge_objs
|
merge_objs
|
||||||
Operation.shell_header_encoding
|
Operation.shell_header_encoding
|
||||||
proto_operation_encoding
|
contents_encoding
|
||||||
|
|
||||||
let internal_operation_encoding =
|
let internal_operation_encoding =
|
||||||
conv
|
conv
|
||||||
@ -439,33 +445,14 @@ module Encoding = struct
|
|||||||
]))
|
]))
|
||||||
end
|
end
|
||||||
|
|
||||||
type error += Cannot_parse_operation
|
|
||||||
|
|
||||||
let encoding = Encoding.operation_encoding
|
let encoding = Encoding.operation_encoding
|
||||||
|
let contents_encoding = Encoding.contents_encoding
|
||||||
let () =
|
let protocol_data_encoding = Encoding.protocol_data_encoding
|
||||||
register_error_kind
|
let unsigned_operation_encoding = Encoding.unsigned_operation_encoding
|
||||||
`Branch
|
let internal_operation_encoding = Encoding.internal_operation_encoding
|
||||||
~id:"operation.cannot_parse"
|
|
||||||
~title:"Cannot parse operation"
|
|
||||||
~description:"The operation is ill-formed \
|
|
||||||
or for another protocol version"
|
|
||||||
~pp:(fun ppf () ->
|
|
||||||
Format.fprintf ppf "The operation cannot be parsed")
|
|
||||||
Data_encoding.unit
|
|
||||||
(function Cannot_parse_operation -> Some () | _ -> None)
|
|
||||||
(fun () -> Cannot_parse_operation)
|
|
||||||
|
|
||||||
let parse (op: Operation.t) =
|
|
||||||
match Data_encoding.Binary.of_bytes
|
|
||||||
Encoding.signed_proto_operation_encoding
|
|
||||||
op.proto with
|
|
||||||
| Some (contents, signature) ->
|
|
||||||
ok { shell = op.shell ; contents ; signature }
|
|
||||||
| None -> error Cannot_parse_operation
|
|
||||||
|
|
||||||
let acceptable_passes op =
|
let acceptable_passes op =
|
||||||
match op.contents with
|
match op.protocol_data.contents with
|
||||||
| Sourced_operation (Consensus_operation _) -> [0]
|
| Sourced_operation (Consensus_operation _) -> [0]
|
||||||
| Sourced_operation (Amendment_operation _ | Dictator_operation _) -> [1]
|
| Sourced_operation (Amendment_operation _ | Dictator_operation _) -> [1]
|
||||||
| Anonymous_operations _ -> [2]
|
| Anonymous_operations _ -> [2]
|
||||||
@ -498,18 +485,16 @@ let () =
|
|||||||
(function Missing_signature -> Some () | _ -> None)
|
(function Missing_signature -> Some () | _ -> None)
|
||||||
(fun () -> Missing_signature)
|
(fun () -> Missing_signature)
|
||||||
|
|
||||||
let forge shell proto =
|
let check_signature key { shell ; protocol_data } =
|
||||||
Data_encoding.Binary.to_bytes_exn
|
match protocol_data.contents, protocol_data.signature with
|
||||||
Encoding.unsigned_operation_encoding (shell, proto)
|
|
||||||
|
|
||||||
let check_signature key { shell ; contents ; signature } =
|
|
||||||
match contents, signature with
|
|
||||||
| Anonymous_operations _, _ -> return ()
|
| Anonymous_operations _, _ -> return ()
|
||||||
| Sourced_operation _, None ->
|
| Sourced_operation _, None ->
|
||||||
fail Missing_signature
|
fail Missing_signature
|
||||||
| Sourced_operation (Consensus_operation _), Some signature ->
|
| Sourced_operation (Consensus_operation _), Some signature ->
|
||||||
(* Safe for baking *)
|
(* Safe for baking *)
|
||||||
let unsigned_operation = forge shell contents in
|
let unsigned_operation =
|
||||||
|
Data_encoding.Binary.to_bytes_exn
|
||||||
|
unsigned_operation_encoding (shell, protocol_data.contents) in
|
||||||
if Signature.check
|
if Signature.check
|
||||||
~watermark:Endorsement
|
~watermark:Endorsement
|
||||||
key signature unsigned_operation then
|
key signature unsigned_operation then
|
||||||
@ -518,7 +503,9 @@ let check_signature key { shell ; contents ; signature } =
|
|||||||
fail Invalid_signature
|
fail Invalid_signature
|
||||||
| Sourced_operation _, Some signature ->
|
| Sourced_operation _, Some signature ->
|
||||||
(* Unsafe for baking *)
|
(* Unsafe for baking *)
|
||||||
let unsigned_operation = forge shell contents in
|
let unsigned_operation =
|
||||||
|
Data_encoding.Binary.to_bytes_exn
|
||||||
|
unsigned_operation_encoding (shell, protocol_data.contents) in
|
||||||
if Signature.check
|
if Signature.check
|
||||||
~watermark:Generic_operation
|
~watermark:Generic_operation
|
||||||
key signature unsigned_operation then
|
key signature unsigned_operation then
|
||||||
@ -526,19 +513,10 @@ let check_signature key { shell ; contents ; signature } =
|
|||||||
else
|
else
|
||||||
fail Invalid_signature
|
fail Invalid_signature
|
||||||
|
|
||||||
let parse_proto bytes =
|
|
||||||
match Data_encoding.Binary.of_bytes
|
|
||||||
Encoding.signed_proto_operation_encoding
|
|
||||||
bytes with
|
|
||||||
| Some (proto, signature) -> return (proto, signature)
|
|
||||||
| None -> fail Cannot_parse_operation
|
|
||||||
|
|
||||||
let hash_raw = Operation.hash
|
let hash_raw = Operation.hash
|
||||||
let hash o =
|
let hash o =
|
||||||
let proto =
|
let proto =
|
||||||
Data_encoding.Binary.to_bytes_exn
|
Data_encoding.Binary.to_bytes_exn
|
||||||
Encoding.signed_proto_operation_encoding
|
protocol_data_encoding
|
||||||
(o.contents, o.signature) in
|
o.protocol_data in
|
||||||
Operation.hash { shell = o.shell ; proto }
|
Operation.hash { shell = o.shell ; proto }
|
||||||
|
|
||||||
include Encoding
|
|
||||||
|
@ -18,11 +18,15 @@ val raw_encoding: raw Data_encoding.t
|
|||||||
|
|
||||||
type operation = {
|
type operation = {
|
||||||
shell: Operation.shell_header ;
|
shell: Operation.shell_header ;
|
||||||
contents: proto_operation ;
|
protocol_data: protocol_data ;
|
||||||
|
}
|
||||||
|
|
||||||
|
and protocol_data = {
|
||||||
|
contents: contents ;
|
||||||
signature: Signature.t option ;
|
signature: Signature.t option ;
|
||||||
}
|
}
|
||||||
|
|
||||||
and proto_operation =
|
and contents =
|
||||||
| Anonymous_operations of anonymous_operation list
|
| Anonymous_operations of anonymous_operation list
|
||||||
| Sourced_operation of sourced_operation
|
| Sourced_operation of sourced_operation
|
||||||
|
|
||||||
@ -102,21 +106,16 @@ and dictator_operation =
|
|||||||
|
|
||||||
and counter = Int32.t
|
and counter = Int32.t
|
||||||
|
|
||||||
type error += Cannot_parse_operation (* `Branch *)
|
|
||||||
|
|
||||||
val encoding: operation Data_encoding.t
|
val encoding: operation Data_encoding.t
|
||||||
|
val contents_encoding: contents Data_encoding.t
|
||||||
|
val protocol_data_encoding: protocol_data Data_encoding.t
|
||||||
|
val unsigned_operation_encoding: (Operation.shell_header * contents) Data_encoding.t
|
||||||
|
|
||||||
val hash_raw: raw -> Operation_hash.t
|
val hash_raw: raw -> Operation_hash.t
|
||||||
val hash: operation -> Operation_hash.t
|
val hash: operation -> Operation_hash.t
|
||||||
|
|
||||||
val parse: Operation.t -> operation tzresult
|
|
||||||
|
|
||||||
val acceptable_passes: operation -> int list
|
val acceptable_passes: operation -> int list
|
||||||
|
|
||||||
val parse_proto:
|
|
||||||
MBytes.t ->
|
|
||||||
(proto_operation * Signature.t option) tzresult Lwt.t
|
|
||||||
|
|
||||||
type error += Missing_signature (* `Permanent *)
|
type error += Missing_signature (* `Permanent *)
|
||||||
type error += Invalid_signature (* `Permanent *)
|
type error += Invalid_signature (* `Permanent *)
|
||||||
|
|
||||||
@ -124,14 +123,6 @@ type error += Invalid_signature (* `Permanent *)
|
|||||||
val check_signature:
|
val check_signature:
|
||||||
Signature.Public_key.t -> operation -> unit tzresult Lwt.t
|
Signature.Public_key.t -> operation -> unit tzresult Lwt.t
|
||||||
|
|
||||||
val forge: Operation.shell_header -> proto_operation -> MBytes.t
|
|
||||||
|
|
||||||
val proto_operation_encoding:
|
|
||||||
proto_operation Data_encoding.t
|
|
||||||
|
|
||||||
val unsigned_operation_encoding:
|
|
||||||
(Operation.shell_header * proto_operation) Data_encoding.t
|
|
||||||
|
|
||||||
type internal_operation = {
|
type internal_operation = {
|
||||||
source: Contract_repr.contract ;
|
source: Contract_repr.contract ;
|
||||||
operation: manager_operation ;
|
operation: manager_operation ;
|
||||||
|
@ -14,7 +14,7 @@ open Alpha_context
|
|||||||
|
|
||||||
val operation :
|
val operation :
|
||||||
tc:context -> ?src:Helpers_account.t ->
|
tc:context -> ?src:Helpers_account.t ->
|
||||||
Block_hash.t -> Tezos_base.Operation.shell_header -> proto_operation ->
|
Block_hash.t -> Tezos_base.Operation.shell_header -> Operation.contents ->
|
||||||
(Contract.contract list * context) proto_tzresult Lwt.t
|
(Contract.contract list * context) proto_tzresult Lwt.t
|
||||||
|
|
||||||
val transaction :
|
val transaction :
|
||||||
|
@ -13,12 +13,13 @@ open Error_monad
|
|||||||
type shell_header = Block_header.shell_header
|
type shell_header = Block_header.shell_header
|
||||||
type tezos_header = Block_header.t
|
type tezos_header = Block_header.t
|
||||||
type protocol_data = Proto_alpha.Alpha_context.Block_header.protocol_data
|
type protocol_data = Proto_alpha.Alpha_context.Block_header.protocol_data
|
||||||
|
type contents = Proto_alpha.Alpha_context.Block_header.contents
|
||||||
type operation_header = Operation.shell_header
|
type operation_header = Operation.shell_header
|
||||||
|
|
||||||
type init_block = {
|
type init_block = {
|
||||||
pred_block_hash : Block_hash.t ;
|
pred_block_hash : Block_hash.t ;
|
||||||
pred_shell_header : shell_header ;
|
pred_shell_header : shell_header ;
|
||||||
protocol_data : protocol_data ;
|
protocol_data : contents ;
|
||||||
op_header : operation_header ;
|
op_header : operation_header ;
|
||||||
sourced_operations : (Proto_alpha.Main.operation * Helpers_account.t) list ;
|
sourced_operations : (Proto_alpha.Main.operation * Helpers_account.t) list ;
|
||||||
operation_hashs : Operation_hash.t list ;
|
operation_hashs : Operation_hash.t list ;
|
||||||
@ -40,7 +41,7 @@ let get_op_header_res (res : result) : operation_header = {
|
|||||||
branch = res.hash
|
branch = res.hash
|
||||||
}
|
}
|
||||||
|
|
||||||
let get_protocol_data priority commit : protocol_data = {
|
let get_protocol_data priority commit : Alpha_context.Block_header.contents = {
|
||||||
priority ;
|
priority ;
|
||||||
proof_of_work_nonce = Helpers_crypto.generate_proof_of_work_nonce ();
|
proof_of_work_nonce = Helpers_crypto.generate_proof_of_work_nonce ();
|
||||||
seed_nonce_hash =
|
seed_nonce_hash =
|
||||||
@ -68,7 +69,8 @@ let init (pred_shell_header : shell_header) pred_block_hash
|
|||||||
let (sourced_operations, operation_hashs) = List.split src_ops_hashs in
|
let (sourced_operations, operation_hashs) = List.split src_ops_hashs in
|
||||||
let protocol_data = get_protocol_data priority true in
|
let protocol_data = get_protocol_data priority true in
|
||||||
let protocol_data_bytes =
|
let protocol_data_bytes =
|
||||||
Proto_alpha.Alpha_context.Block_header.forge_unsigned_protocol_data
|
Data_encoding.Binary.to_bytes_exn
|
||||||
|
Proto_alpha.Alpha_context.Block_header.contents_encoding
|
||||||
protocol_data
|
protocol_data
|
||||||
in
|
in
|
||||||
let timestamp =
|
let timestamp =
|
||||||
@ -155,7 +157,9 @@ let begin_construction_pre (init_block: init_block) =
|
|||||||
~predecessor_fitness: init_block.pred_shell_header.fitness
|
~predecessor_fitness: init_block.pred_shell_header.fitness
|
||||||
~predecessor: init_block.pred_block_hash
|
~predecessor: init_block.pred_block_hash
|
||||||
~timestamp: init_block.timestamp
|
~timestamp: init_block.timestamp
|
||||||
~protocol_data: init_block.protocol_data_bytes
|
~protocol_data:
|
||||||
|
(Alpha_context.Block_header.{ contents = init_block.protocol_data ;
|
||||||
|
signature = Signature.zero })
|
||||||
()
|
()
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,13 +14,14 @@ open Proto_alpha
|
|||||||
type shell_header = Block_header.shell_header
|
type shell_header = Block_header.shell_header
|
||||||
type tezos_header = Block_header.t
|
type tezos_header = Block_header.t
|
||||||
type protocol_data = Alpha_context.Block_header.protocol_data
|
type protocol_data = Alpha_context.Block_header.protocol_data
|
||||||
|
type contents = Proto_alpha.Alpha_context.Block_header.contents
|
||||||
type operation_header = Operation.shell_header
|
type operation_header = Operation.shell_header
|
||||||
|
|
||||||
(** Block before application *)
|
(** Block before application *)
|
||||||
type init_block = {
|
type init_block = {
|
||||||
pred_block_hash : Block_hash.t;
|
pred_block_hash : Block_hash.t;
|
||||||
pred_shell_header : shell_header;
|
pred_shell_header : shell_header;
|
||||||
protocol_data : protocol_data;
|
protocol_data : contents;
|
||||||
op_header : operation_header;
|
op_header : operation_header;
|
||||||
sourced_operations :
|
sourced_operations :
|
||||||
(Main.operation * Helpers_account.t) list;
|
(Main.operation * Helpers_account.t) list;
|
||||||
@ -40,20 +41,20 @@ type result = {
|
|||||||
tezos_context : Alpha_context.t;
|
tezos_context : Alpha_context.t;
|
||||||
}
|
}
|
||||||
val get_op_header_res : result -> operation_header
|
val get_op_header_res : result -> operation_header
|
||||||
val get_protocol_data : int -> bool -> protocol_data
|
val get_protocol_data : int -> bool -> contents
|
||||||
val get_op_header : Block_hash.t -> operation_header
|
val get_op_header : Block_hash.t -> operation_header
|
||||||
val make_sourced_operation :
|
val make_sourced_operation :
|
||||||
Operation.shell_header ->
|
Operation.shell_header ->
|
||||||
Alpha_context.proto_operation *
|
Alpha_context.Operation.contents *
|
||||||
Helpers_account.t ->
|
Helpers_account.t ->
|
||||||
((Proto_alpha.Main.operation * Helpers_account.t) * Operation_hash.t) proto_tzresult
|
((Proto_alpha.Main.operation * Helpers_account.t) * Operation_hash.t) proto_tzresult
|
||||||
val init :
|
val init :
|
||||||
shell_header -> Block_hash.t -> Int32.t -> int ->
|
shell_header -> Block_hash.t -> Int32.t -> int ->
|
||||||
(Alpha_context.proto_operation * Helpers_account.t) list ->
|
(Alpha_context.Operation.contents * Helpers_account.t) list ->
|
||||||
Context.t -> init_block proto_tzresult
|
Context.t -> init_block proto_tzresult
|
||||||
val init_of_result :
|
val init_of_result :
|
||||||
?priority:int -> res:result ->
|
?priority:int -> res:result ->
|
||||||
ops:(Alpha_context.proto_operation * Helpers_account.t) list ->
|
ops:(Alpha_context.Operation.contents * Helpers_account.t) list ->
|
||||||
init_block proto_tzresult
|
init_block proto_tzresult
|
||||||
val get_level : string option -> int32
|
val get_level : string option -> int32
|
||||||
val get_header_hash :
|
val get_header_hash :
|
||||||
@ -64,11 +65,11 @@ val begin_construction_pre :
|
|||||||
val make : init_block -> result proto_tzresult Lwt.t
|
val make : init_block -> result proto_tzresult Lwt.t
|
||||||
val make_init :
|
val make_init :
|
||||||
shell_header -> Block_hash.t -> Int32.t -> int ->
|
shell_header -> Block_hash.t -> Int32.t -> int ->
|
||||||
(Alpha_context.proto_operation * Helpers_account.t) list ->
|
(Alpha_context.Operation.contents * Helpers_account.t) list ->
|
||||||
Context.t -> result proto_tzresult Lwt.t
|
Context.t -> result proto_tzresult Lwt.t
|
||||||
val of_res :
|
val of_res :
|
||||||
?priority:int ->
|
?priority:int ->
|
||||||
?ops:(Alpha_context.proto_operation * Helpers_account.t) list ->
|
?ops:(Alpha_context.Operation.contents * Helpers_account.t) list ->
|
||||||
res:result ->
|
res:result ->
|
||||||
unit -> result proto_tzresult Lwt.t
|
unit -> result proto_tzresult Lwt.t
|
||||||
val endorsement :
|
val endorsement :
|
||||||
|
@ -76,7 +76,7 @@ let main () =
|
|||||||
} in
|
} in
|
||||||
let protocol_data =
|
let protocol_data =
|
||||||
Data_encoding.Binary.to_bytes_exn
|
Data_encoding.Binary.to_bytes_exn
|
||||||
Alpha_context.Block_header.protocol_data_encoding
|
Alpha_context.Block_header.contents_encoding
|
||||||
(Helpers_block.get_protocol_data 0 true) in
|
(Helpers_block.get_protocol_data 0 true) in
|
||||||
let tezos_header = { Block_header.shell = header ; protocol_data } in
|
let tezos_header = { Block_header.shell = header ; protocol_data } in
|
||||||
Proto_alpha.init context header >>=? fun validation ->
|
Proto_alpha.init context header >>=? fun validation ->
|
||||||
|
@ -108,27 +108,39 @@ let sign src oph protop =
|
|||||||
Some Signature.Endorsement
|
Some Signature.Endorsement
|
||||||
| _ ->
|
| _ ->
|
||||||
Some Generic_operation in
|
Some Generic_operation in
|
||||||
let bytes = Operation.forge oph protop in
|
let signature =
|
||||||
match src with
|
match src with
|
||||||
| None -> bytes, None
|
| None -> None
|
||||||
| Some src ->
|
| Some src ->
|
||||||
let signature =
|
let contents =
|
||||||
Signature.sign ?watermark src.Helpers_account.ppk bytes in
|
Data_encoding.Binary.to_bytes_exn
|
||||||
Signature.concat bytes signature, Some signature
|
Operation.unsigned_encoding (oph, protop) in
|
||||||
|
Some (Signature.sign ?watermark src.Helpers_account.ppk contents) in
|
||||||
|
let proto_bytes =
|
||||||
|
Data_encoding.Binary.to_bytes_exn
|
||||||
|
Operation.protocol_data_encoding
|
||||||
|
{ contents = protop ; signature } in
|
||||||
|
(proto_bytes, signature)
|
||||||
|
|
||||||
let main_of_proto (src: Helpers_account.t) operation_header protocol_operation =
|
let main_of_proto (src: Helpers_account.t) operation_header protocol_operation =
|
||||||
let (proto,_) = sign (Some src) operation_header protocol_operation in
|
let (proto,_) = sign (Some src) operation_header protocol_operation in
|
||||||
let data_operation: Tezos_base.Operation.t =
|
let data_operation: Tezos_base.Operation.t =
|
||||||
{shell = operation_header ; proto} in
|
{shell = operation_header ; proto} in
|
||||||
let hash = Tezos_base.Operation.hash data_operation in
|
let hash = Tezos_base.Operation.hash data_operation in
|
||||||
Proto_alpha.Main.parse_operation hash data_operation >>? fun op ->
|
match Data_encoding.Binary.of_bytes
|
||||||
ok (op, hash)
|
Operation.protocol_data_encoding proto with
|
||||||
|
| None ->
|
||||||
|
Error []
|
||||||
|
| Some op ->
|
||||||
|
ok ({ shell = operation_header ; protocol_data = op }, hash)
|
||||||
|
|
||||||
let apply_of_proto
|
let apply_of_proto
|
||||||
(source: Helpers_account.t option) operation_header protocol_operation =
|
(source: Helpers_account.t option) operation_header protocol_operation =
|
||||||
let (_proto, signature) = sign source operation_header protocol_operation in
|
let (_proto, signature) = sign source operation_header protocol_operation in
|
||||||
{
|
{
|
||||||
shell = operation_header ;
|
shell = operation_header ;
|
||||||
contents = protocol_operation ;
|
protocol_data = {
|
||||||
signature
|
contents = protocol_operation ;
|
||||||
|
signature
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ open Alpha_context
|
|||||||
|
|
||||||
(** Functions building operations *)
|
(** Functions building operations *)
|
||||||
|
|
||||||
val sourced : sourced_operation -> proto_operation
|
val sourced : sourced_operation -> Operation.contents
|
||||||
|
|
||||||
val manager :
|
val manager :
|
||||||
Helpers_account.t -> ?fee:Tez.tez -> manager_operation list ->
|
Helpers_account.t -> ?fee:Tez.tez -> manager_operation list ->
|
||||||
@ -20,7 +20,7 @@ val manager :
|
|||||||
|
|
||||||
val manager_full :
|
val manager_full :
|
||||||
Helpers_account.t -> ?fee:Tez.tez -> manager_operation list ->
|
Helpers_account.t -> ?fee:Tez.tez -> manager_operation list ->
|
||||||
Alpha_environment.Context.t -> Z.t -> proto_operation proto_tzresult Lwt.t
|
Alpha_environment.Context.t -> Z.t -> Operation.contents proto_tzresult Lwt.t
|
||||||
|
|
||||||
val transaction :
|
val transaction :
|
||||||
?parameters:Script.expr -> Tez.t -> Contract.contract ->
|
?parameters:Script.expr -> Tez.t -> Contract.contract ->
|
||||||
@ -34,20 +34,20 @@ val delegation : public_key_hash -> manager_operation
|
|||||||
|
|
||||||
val delegation_full :
|
val delegation_full :
|
||||||
?fee:Tez.tez -> Helpers_account.t -> public_key_hash -> Alpha_environment.Context.t ->
|
?fee:Tez.tez -> Helpers_account.t -> public_key_hash -> Alpha_environment.Context.t ->
|
||||||
proto_operation proto_tzresult Lwt.t
|
Operation.contents proto_tzresult Lwt.t
|
||||||
|
|
||||||
val script_origination_full :
|
val script_origination_full :
|
||||||
Script.t option -> Helpers_account.t -> Tez.t -> Z.t -> Alpha_environment.Context.t ->
|
Script.t option -> Helpers_account.t -> Tez.t -> Z.t -> Alpha_environment.Context.t ->
|
||||||
proto_operation proto_tzresult Lwt.t
|
Operation.contents proto_tzresult Lwt.t
|
||||||
|
|
||||||
val origination_full :
|
val origination_full :
|
||||||
?spendable:bool -> ?delegatable:bool -> ?fee:Tez.tez ->
|
?spendable:bool -> ?delegatable:bool -> ?fee:Tez.tez ->
|
||||||
Helpers_account.t -> Tez.t -> Z.t -> Alpha_environment.Context.t ->
|
Helpers_account.t -> Tez.t -> Z.t -> Alpha_environment.Context.t ->
|
||||||
proto_operation proto_tzresult Lwt.t
|
Operation.contents proto_tzresult Lwt.t
|
||||||
|
|
||||||
val transaction_full :
|
val transaction_full :
|
||||||
?fee:Tez.tez -> ?parameters:Proto_alpha.Alpha_context.Script.expr -> Helpers_account.t -> Contract.contract -> Tez.t -> Z.t ->
|
?fee:Tez.tez -> ?parameters:Proto_alpha.Alpha_context.Script.expr -> Helpers_account.t -> Contract.contract -> Tez.t -> Z.t ->
|
||||||
Alpha_environment.Context.t -> proto_operation proto_tzresult Lwt.t
|
Alpha_environment.Context.t -> Operation.contents proto_tzresult Lwt.t
|
||||||
|
|
||||||
val amendment_operation :
|
val amendment_operation :
|
||||||
Helpers_account.t -> amendment_operation -> sourced_operation
|
Helpers_account.t -> amendment_operation -> sourced_operation
|
||||||
@ -56,16 +56,16 @@ val endorsements :
|
|||||||
?slot:int -> Block_hash.t -> Raw_level.t -> consensus_operation
|
?slot:int -> Block_hash.t -> Raw_level.t -> consensus_operation
|
||||||
|
|
||||||
val endorsement_full :
|
val endorsement_full :
|
||||||
?slot:int -> Block_hash.t -> Raw_level.t -> proto_operation
|
?slot:int -> Block_hash.t -> Raw_level.t -> Operation.contents
|
||||||
|
|
||||||
val sign :
|
val sign :
|
||||||
Helpers_account.t option -> Tezos_base.Operation.shell_header ->
|
Helpers_account.t option -> Tezos_base.Operation.shell_header ->
|
||||||
proto_operation -> MBytes.t * Signature.t option
|
Operation.contents -> MBytes.t * Signature.t option
|
||||||
|
|
||||||
val main_of_proto :
|
val main_of_proto :
|
||||||
Helpers_account.t -> Tezos_base.Operation.shell_header ->
|
Helpers_account.t -> Tezos_base.Operation.shell_header ->
|
||||||
proto_operation -> (Main.operation * Operation_hash.t) proto_tzresult
|
Operation.contents -> (Main.operation * Operation_hash.t) proto_tzresult
|
||||||
|
|
||||||
val apply_of_proto :
|
val apply_of_proto :
|
||||||
Helpers_account.t option -> Tezos_base.Operation.shell_header ->
|
Helpers_account.t option -> Tezos_base.Operation.shell_header ->
|
||||||
proto_operation -> operation
|
Operation.contents -> operation
|
||||||
|
@ -7,15 +7,27 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
type operation = Operation_hash.t
|
|
||||||
|
type block_header_data = MBytes.t
|
||||||
|
type block_header = {
|
||||||
|
shell : Block_header.shell_header ;
|
||||||
|
protocol_data : block_header_data ;
|
||||||
|
}
|
||||||
|
let block_header_data_encoding =
|
||||||
|
Data_encoding.(obj1 (req "random_data" Variable.bytes))
|
||||||
|
|
||||||
|
type operation_data = unit
|
||||||
|
type operation = {
|
||||||
|
shell : Operation.shell_header ;
|
||||||
|
protocol_data : operation_data ;
|
||||||
|
}
|
||||||
|
let operation_data_encoding = Data_encoding.unit
|
||||||
let max_operation_data_length = 42
|
let max_operation_data_length = 42
|
||||||
|
|
||||||
let max_block_length = 42
|
let max_block_length = 42
|
||||||
let validation_passes = []
|
let validation_passes = []
|
||||||
let acceptable_passes _op = []
|
let acceptable_passes _op = []
|
||||||
|
|
||||||
let parse_operation h _ = Ok h
|
|
||||||
|
|
||||||
let compare_operations _ _ = 0
|
let compare_operations _ _ = 0
|
||||||
|
|
||||||
type validation_state = {
|
type validation_state = {
|
||||||
@ -57,16 +69,16 @@ end
|
|||||||
let precheck_block
|
let precheck_block
|
||||||
~ancestor_context:_
|
~ancestor_context:_
|
||||||
~ancestor_timestamp:_
|
~ancestor_timestamp:_
|
||||||
raw_block =
|
(raw_block: block_header) =
|
||||||
Fitness.to_int64 raw_block.Block_header.shell.fitness >>=? fun _ ->
|
Fitness.to_int64 raw_block.shell.fitness >>=? fun _ ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let begin_application
|
let begin_application
|
||||||
~predecessor_context:context
|
~predecessor_context:context
|
||||||
~predecessor_timestamp:_
|
~predecessor_timestamp:_
|
||||||
~predecessor_fitness:_
|
~predecessor_fitness:_
|
||||||
raw_block =
|
(raw_block: block_header) =
|
||||||
Fitness.to_int64 raw_block.Block_header.shell.fitness >>=? fun fitness ->
|
Fitness.to_int64 raw_block.shell.fitness >>=? fun fitness ->
|
||||||
return { context ; fitness }
|
return { context ; fitness }
|
||||||
|
|
||||||
let begin_construction
|
let begin_construction
|
||||||
|
12
src/proto_demo/lib_protocol/src/main.mli
Normal file
12
src/proto_demo/lib_protocol/src/main.mli
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2018. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
(** Tezos Protocol Implementation - Protocol Signature Instance *)
|
||||||
|
|
||||||
|
include Updater.PROTOCOL with type block_header_data = MBytes.t
|
@ -14,13 +14,14 @@ let protocol =
|
|||||||
"ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im"
|
"ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im"
|
||||||
|
|
||||||
let bake cctxt ?(timestamp = Time.now ()) block command sk =
|
let bake cctxt ?(timestamp = Time.now ()) block command sk =
|
||||||
let protocol_data = Data_encoding.Binary.to_bytes_exn Data.Command.encoding command in
|
let protocol_data =
|
||||||
|
Data_encoding.Binary.to_bytes_exn
|
||||||
|
Proto_genesis.block_header_data_encoding
|
||||||
|
{ command ; signature = Signature.zero } in
|
||||||
Block_services.preapply
|
Block_services.preapply
|
||||||
cctxt block ~timestamp ~protocol_data
|
cctxt block ~timestamp ~protocol_data
|
||||||
[] >>=? fun { shell_header } ->
|
[] >>=? fun { shell_header } ->
|
||||||
let blk =
|
let blk = Data.Command.forge shell_header command in
|
||||||
Data_encoding.Binary.to_bytes_exn Block_header.encoding
|
|
||||||
{ shell = shell_header ; protocol_data } in
|
|
||||||
Client_keys.append sk blk >>=? fun signed_blk ->
|
Client_keys.append sk blk >>=? fun signed_blk ->
|
||||||
Shell_services.inject_block cctxt signed_blk []
|
Shell_services.inject_block cctxt signed_blk []
|
||||||
|
|
||||||
|
@ -32,17 +32,31 @@ let () =
|
|||||||
(function Invalid_signature -> Some () | _ -> None)
|
(function Invalid_signature -> Some () | _ -> None)
|
||||||
(fun () -> Invalid_signature)
|
(fun () -> Invalid_signature)
|
||||||
|
|
||||||
type operation = unit
|
type operation_data = unit
|
||||||
let parse_operation _h _op = Error []
|
type operation = {
|
||||||
|
shell: Operation.shell_header ;
|
||||||
|
protocol_data: operation_data ;
|
||||||
|
}
|
||||||
|
let operation_data_encoding = Data_encoding.unit
|
||||||
|
|
||||||
let acceptable_passes _op = []
|
let acceptable_passes _op = []
|
||||||
let compare_operations _ _ = 0
|
let compare_operations _ _ = 0
|
||||||
let validation_passes = []
|
let validation_passes = []
|
||||||
|
|
||||||
type block = {
|
type block_header_data = {
|
||||||
shell: Block_header.shell_header ;
|
|
||||||
command: Data.Command.t ;
|
command: Data.Command.t ;
|
||||||
signature: Signature.t ;
|
signature: Signature.t ;
|
||||||
}
|
}
|
||||||
|
type block_header = {
|
||||||
|
shell: Block_header.shell_header ;
|
||||||
|
protocol_data: block_header_data ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let block_header_data_encoding =
|
||||||
|
Data_encoding.conv
|
||||||
|
(fun { command ; signature } -> (command, signature))
|
||||||
|
(fun (command, signature) -> { command ; signature })
|
||||||
|
Data.Command.signed_encoding
|
||||||
|
|
||||||
let max_block_length =
|
let max_block_length =
|
||||||
Data_encoding.Binary.length
|
Data_encoding.Binary.length
|
||||||
@ -51,14 +65,7 @@ let max_block_length =
|
|||||||
delay = 0L })
|
delay = 0L })
|
||||||
+ Signature.size
|
+ Signature.size
|
||||||
|
|
||||||
let parse_block { Block_header.shell ; protocol_data } : block tzresult =
|
let check_signature ctxt { shell ; protocol_data = { command ; signature } } =
|
||||||
match
|
|
||||||
Data_encoding.Binary.of_bytes Data.Command.signed_encoding protocol_data
|
|
||||||
with
|
|
||||||
| None -> Error [Parsing_error]
|
|
||||||
| Some (command, signature) -> Ok { shell ; command ; signature }
|
|
||||||
|
|
||||||
let check_signature ctxt { shell ; command ; signature } =
|
|
||||||
let bytes = Data.Command.forge shell command in
|
let bytes = Data.Command.forge shell command in
|
||||||
Data.Pubkey.get_pubkey ctxt >>= fun public_key ->
|
Data.Pubkey.get_pubkey ctxt >>= fun public_key ->
|
||||||
fail_unless
|
fail_unless
|
||||||
@ -73,8 +80,7 @@ let current_context ({ context ; _ } : validation_state) =
|
|||||||
let precheck_block
|
let precheck_block
|
||||||
~ancestor_context:_
|
~ancestor_context:_
|
||||||
~ancestor_timestamp:_
|
~ancestor_timestamp:_
|
||||||
raw_block =
|
_block_header =
|
||||||
Lwt.return (parse_block raw_block) >>=? fun _ ->
|
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
(* temporary hardcoded key to be removed... *)
|
(* temporary hardcoded key to be removed... *)
|
||||||
@ -106,12 +112,11 @@ let begin_application
|
|||||||
~predecessor_context:ctxt
|
~predecessor_context:ctxt
|
||||||
~predecessor_timestamp:_
|
~predecessor_timestamp:_
|
||||||
~predecessor_fitness:_
|
~predecessor_fitness:_
|
||||||
raw_block =
|
block_header =
|
||||||
Data.Init.check_inited ctxt >>=? fun () ->
|
Data.Init.check_inited ctxt >>=? fun () ->
|
||||||
Lwt.return (parse_block raw_block) >>=? fun block ->
|
check_signature ctxt block_header >>=? fun () ->
|
||||||
check_signature ctxt block >>=? fun () ->
|
prepare_application ctxt block_header.protocol_data.command
|
||||||
prepare_application ctxt block.command
|
block_header.shell.level block_header.shell.timestamp block_header.shell.fitness
|
||||||
block.shell.level block.shell.timestamp block.shell.fitness
|
|
||||||
|
|
||||||
let begin_construction
|
let begin_construction
|
||||||
~predecessor_context:ctxt
|
~predecessor_context:ctxt
|
||||||
@ -130,12 +135,9 @@ let begin_construction
|
|||||||
max_operation_data_length = 0 ;
|
max_operation_data_length = 0 ;
|
||||||
last_allowed_fork_level = 0l ;
|
last_allowed_fork_level = 0l ;
|
||||||
}
|
}
|
||||||
| Some command ->
|
| Some { command ; _ }->
|
||||||
match Data_encoding.Binary.of_bytes Data.Command.encoding command with
|
Data.Init.check_inited ctxt >>=? fun () ->
|
||||||
| None -> failwith "Failed to parse proto header"
|
prepare_application ctxt command level timestamp fitness
|
||||||
| Some command ->
|
|
||||||
Data.Init.check_inited ctxt >>=? fun () ->
|
|
||||||
prepare_application ctxt command level timestamp fitness
|
|
||||||
|
|
||||||
let apply_operation _vctxt _ =
|
let apply_operation _vctxt _ =
|
||||||
Lwt.return (Error []) (* absurd *)
|
Lwt.return (Error []) (* absurd *)
|
||||||
|
@ -9,4 +9,9 @@
|
|||||||
|
|
||||||
(** Tezos Protocol Implementation - Protocol Signature Instance *)
|
(** Tezos Protocol Implementation - Protocol Signature Instance *)
|
||||||
|
|
||||||
include Updater.PROTOCOL
|
type block_header_data = {
|
||||||
|
command: Data.Command.t ;
|
||||||
|
signature: Signature.t ;
|
||||||
|
}
|
||||||
|
|
||||||
|
include Updater.PROTOCOL with type block_header_data := block_header_data
|
||||||
|
Loading…
Reference in New Issue
Block a user