Shell: add context
in block header
This commit is contained in:
parent
270dc3e9e8
commit
009d562e08
@ -15,27 +15,33 @@ type shell_header = {
|
|||||||
validation_passes: int ; (* uint8 *)
|
validation_passes: int ; (* uint8 *)
|
||||||
operations_hash: Operation_list_list_hash.t ;
|
operations_hash: Operation_list_list_hash.t ;
|
||||||
fitness: MBytes.t list ;
|
fitness: MBytes.t list ;
|
||||||
|
context: Context_hash.t ;
|
||||||
}
|
}
|
||||||
|
|
||||||
let shell_header_encoding =
|
let shell_header_encoding =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
conv
|
conv
|
||||||
(fun { level ; proto_level ; predecessor ;
|
(fun { level ; proto_level ; predecessor ;
|
||||||
timestamp ; validation_passes ; operations_hash ; fitness } ->
|
timestamp ; validation_passes ; operations_hash ; fitness ;
|
||||||
|
context } ->
|
||||||
(level, proto_level, predecessor,
|
(level, proto_level, predecessor,
|
||||||
timestamp, validation_passes, operations_hash, fitness))
|
timestamp, validation_passes, operations_hash, fitness,
|
||||||
|
context))
|
||||||
(fun (level, proto_level, predecessor,
|
(fun (level, proto_level, predecessor,
|
||||||
timestamp, validation_passes, operations_hash, fitness) ->
|
timestamp, validation_passes, operations_hash, fitness,
|
||||||
|
context) ->
|
||||||
{ level ; proto_level ; predecessor ;
|
{ level ; proto_level ; predecessor ;
|
||||||
timestamp ; validation_passes ; operations_hash ; fitness })
|
timestamp ; validation_passes ; operations_hash ; fitness ;
|
||||||
(obj7
|
context })
|
||||||
|
(obj8
|
||||||
(req "level" int32)
|
(req "level" int32)
|
||||||
(req "proto" uint8)
|
(req "proto" uint8)
|
||||||
(req "predecessor" Block_hash.encoding)
|
(req "predecessor" Block_hash.encoding)
|
||||||
(req "timestamp" Time.encoding)
|
(req "timestamp" Time.encoding)
|
||||||
(req "validation_pass" uint8)
|
(req "validation_pass" uint8)
|
||||||
(req "operations_hash" Operation_list_list_hash.encoding)
|
(req "operations_hash" Operation_list_list_hash.encoding)
|
||||||
(req "fitness" Fitness.encoding))
|
(req "fitness" Fitness.encoding)
|
||||||
|
(req "context" Context_hash.encoding))
|
||||||
|
|
||||||
type t = {
|
type t = {
|
||||||
shell: shell_header ;
|
shell: shell_header ;
|
||||||
|
@ -15,6 +15,7 @@ type shell_header = {
|
|||||||
validation_passes: int ; (* uint8 *)
|
validation_passes: int ; (* uint8 *)
|
||||||
operations_hash: Operation_list_list_hash.t ;
|
operations_hash: Operation_list_list_hash.t ;
|
||||||
fitness: MBytes.t list ;
|
fitness: MBytes.t list ;
|
||||||
|
context: Context_hash.t ;
|
||||||
}
|
}
|
||||||
|
|
||||||
val shell_header_encoding: shell_header Data_encoding.t
|
val shell_header_encoding: shell_header Data_encoding.t
|
||||||
|
@ -61,6 +61,7 @@ module Blocks = struct
|
|||||||
validation_passes: int ; (* uint8 *)
|
validation_passes: int ; (* uint8 *)
|
||||||
operations_hash: Operation_list_list_hash.t ;
|
operations_hash: Operation_list_list_hash.t ;
|
||||||
fitness: MBytes.t list ;
|
fitness: MBytes.t list ;
|
||||||
|
context: Context_hash.t ;
|
||||||
data: MBytes.t ;
|
data: MBytes.t ;
|
||||||
operations: (Operation_hash.t * Operation.t) list list option ;
|
operations: (Operation_hash.t * Operation.t) list list option ;
|
||||||
protocol: Protocol_hash.t ;
|
protocol: Protocol_hash.t ;
|
||||||
|
@ -89,6 +89,7 @@ module Blocks : sig
|
|||||||
validation_passes: int ; (* uint8 *)
|
validation_passes: int ; (* uint8 *)
|
||||||
operations_hash: Operation_list_list_hash.t ;
|
operations_hash: Operation_list_list_hash.t ;
|
||||||
fitness: MBytes.t list ;
|
fitness: MBytes.t list ;
|
||||||
|
context: Context_hash.t ;
|
||||||
data: MBytes.t ;
|
data: MBytes.t ;
|
||||||
operations: (Operation_hash.t * Operation.t) list list option ;
|
operations: (Operation_hash.t * Operation.t) list list option ;
|
||||||
protocol: Protocol_hash.t ;
|
protocol: Protocol_hash.t ;
|
||||||
|
@ -82,14 +82,16 @@ type error +=
|
|||||||
|
|
||||||
let parse
|
let parse
|
||||||
({ shell = { level ; proto_level ; predecessor ;
|
({ shell = { level ; proto_level ; predecessor ;
|
||||||
timestamp ; fitness ; validation_passes ; operations_hash } ;
|
timestamp ; fitness ; validation_passes ; operations_hash ;
|
||||||
|
context } ;
|
||||||
proto } : Block_header.t) : block_header tzresult =
|
proto } : Block_header.t) : block_header tzresult =
|
||||||
match Data_encoding.Binary.of_bytes signed_proto_header_encoding proto with
|
match Data_encoding.Binary.of_bytes signed_proto_header_encoding proto with
|
||||||
| None -> Error [Cant_parse_proto_header]
|
| None -> Error [Cant_parse_proto_header]
|
||||||
| Some (proto, signature) ->
|
| Some (proto, signature) ->
|
||||||
let shell =
|
let shell =
|
||||||
{ Block_header.level ; proto_level ; predecessor ;
|
{ Block_header.level ; proto_level ; predecessor ;
|
||||||
timestamp ; fitness ; validation_passes ; operations_hash } in
|
timestamp ; fitness ; validation_passes ; operations_hash ;
|
||||||
|
context } in
|
||||||
Ok { shell ; proto ; signature }
|
Ok { shell ; proto ; signature }
|
||||||
|
|
||||||
let parse_unsigned_proto_header bytes =
|
let parse_unsigned_proto_header bytes =
|
||||||
|
@ -40,12 +40,12 @@ module Forge = struct
|
|||||||
~input:
|
~input:
|
||||||
(merge_objs
|
(merge_objs
|
||||||
(obj6
|
(obj6
|
||||||
(req "net_id" Net_id.encoding)
|
|
||||||
(req "level" int32)
|
(req "level" int32)
|
||||||
(req "proto_level" uint8)
|
(req "proto_level" uint8)
|
||||||
(req "predecessor" Block_hash.encoding)
|
(req "predecessor" Block_hash.encoding)
|
||||||
(req "timestamp" Time.encoding)
|
(req "timestamp" Time.encoding)
|
||||||
(req "fitness" Fitness.encoding))
|
(req "fitness" Fitness.encoding)
|
||||||
|
(req "context" Context_hash.encoding))
|
||||||
Data.Command.encoding)
|
Data.Command.encoding)
|
||||||
~output: (obj1 (req "payload" bytes))
|
~output: (obj1 (req "payload" bytes))
|
||||||
~error: Data_encoding.empty
|
~error: Data_encoding.empty
|
||||||
@ -66,11 +66,11 @@ let rpc_services : Updater.rpc_context RPC_directory.t =
|
|||||||
RPC_directory.register
|
RPC_directory.register
|
||||||
dir
|
dir
|
||||||
(Forge.block RPC_path.open_root)
|
(Forge.block RPC_path.open_root)
|
||||||
(fun _ctxt () ((_net_id, level, proto_level, predecessor,
|
(fun _ctxt () ((level, proto_level, predecessor,
|
||||||
timestamp, fitness), command) ->
|
timestamp, fitness, context), command) ->
|
||||||
let shell = { Block_header.level ; proto_level ; predecessor ;
|
let shell = { Block_header.level ; proto_level ; predecessor ;
|
||||||
timestamp ; fitness ; validation_passes = 0 ;
|
timestamp ; fitness ; validation_passes = 0 ;
|
||||||
operations_hash } in
|
operations_hash ; context } in
|
||||||
let bytes = Data.Command.forge shell command in
|
let bytes = Data.Command.forge shell command in
|
||||||
RPC_answer.return bytes) in
|
RPC_answer.return bytes) in
|
||||||
dir
|
dir
|
||||||
|
@ -68,6 +68,7 @@ module Blocks = struct
|
|||||||
validation_passes: int ; (* uint8 *)
|
validation_passes: int ; (* uint8 *)
|
||||||
operations_hash: Operation_list_list_hash.t ;
|
operations_hash: Operation_list_list_hash.t ;
|
||||||
fitness: MBytes.t list ;
|
fitness: MBytes.t list ;
|
||||||
|
context: Context_hash.t ;
|
||||||
data: MBytes.t ;
|
data: MBytes.t ;
|
||||||
operations: (Operation_hash.t * Operation.t) list list option ;
|
operations: (Operation_hash.t * Operation.t) list list option ;
|
||||||
protocol: Protocol_hash.t ;
|
protocol: Protocol_hash.t ;
|
||||||
@ -82,21 +83,23 @@ module Blocks = struct
|
|||||||
conv
|
conv
|
||||||
(fun { hash ; net_id ; level ; proto_level ; predecessor ;
|
(fun { hash ; net_id ; level ; proto_level ; predecessor ;
|
||||||
fitness ; timestamp ; protocol ;
|
fitness ; timestamp ; protocol ;
|
||||||
validation_passes ; operations_hash ; data ;
|
validation_passes ; operations_hash ; context ; data ;
|
||||||
operations ; test_network } ->
|
operations ; test_network } ->
|
||||||
((hash, net_id, operations, protocol, test_network),
|
((hash, net_id, operations, protocol, test_network),
|
||||||
{ Block_header.shell =
|
{ Block_header.shell =
|
||||||
{ level ; proto_level ; predecessor ;
|
{ level ; proto_level ; predecessor ;
|
||||||
timestamp ; validation_passes ; operations_hash ; fitness } ;
|
timestamp ; validation_passes ; operations_hash ; fitness ;
|
||||||
|
context } ;
|
||||||
proto = data }))
|
proto = data }))
|
||||||
(fun ((hash, net_id, operations, protocol, test_network),
|
(fun ((hash, net_id, operations, protocol, test_network),
|
||||||
{ Block_header.shell =
|
{ Block_header.shell =
|
||||||
{ level ; proto_level ; predecessor ;
|
{ level ; proto_level ; predecessor ;
|
||||||
timestamp ; validation_passes ; operations_hash ; fitness } ;
|
timestamp ; validation_passes ; operations_hash ; fitness ;
|
||||||
|
context } ;
|
||||||
proto = data }) ->
|
proto = data }) ->
|
||||||
{ hash ; net_id ; level ; proto_level ; predecessor ;
|
{ hash ; net_id ; level ; proto_level ; predecessor ;
|
||||||
fitness ; timestamp ; protocol ;
|
fitness ; timestamp ; protocol ;
|
||||||
validation_passes ; operations_hash ; data ;
|
validation_passes ; operations_hash ; context ; data ;
|
||||||
operations ; test_network })
|
operations ; test_network })
|
||||||
(dynamic_size
|
(dynamic_size
|
||||||
(merge_objs
|
(merge_objs
|
||||||
@ -214,6 +217,15 @@ module Blocks = struct
|
|||||||
~error: Data_encoding.empty
|
~error: Data_encoding.empty
|
||||||
RPC_path.(block_path / "fitness")
|
RPC_path.(block_path / "fitness")
|
||||||
|
|
||||||
|
let context =
|
||||||
|
RPC_service.post_service
|
||||||
|
~description:"Returns the hash of the resulting context."
|
||||||
|
~query: RPC_query.empty
|
||||||
|
~input: empty
|
||||||
|
~output: (obj1 (req "context" Context_hash.encoding))
|
||||||
|
~error: Data_encoding.empty
|
||||||
|
RPC_path.(block_path / "context")
|
||||||
|
|
||||||
let timestamp =
|
let timestamp =
|
||||||
RPC_service.post_service
|
RPC_service.post_service
|
||||||
~description:"Returns the block's timestamp."
|
~description:"Returns the block's timestamp."
|
||||||
|
@ -37,6 +37,7 @@ module Blocks : sig
|
|||||||
validation_passes: int ; (* uint8 *)
|
validation_passes: int ; (* uint8 *)
|
||||||
operations_hash: Operation_list_list_hash.t ;
|
operations_hash: Operation_list_list_hash.t ;
|
||||||
fitness: MBytes.t list ;
|
fitness: MBytes.t list ;
|
||||||
|
context: Context_hash.t ;
|
||||||
data: MBytes.t ;
|
data: MBytes.t ;
|
||||||
operations: (Operation_hash.t * Operation.t) list list option ;
|
operations: (Operation_hash.t * Operation.t) list list option ;
|
||||||
protocol: Protocol_hash.t ;
|
protocol: Protocol_hash.t ;
|
||||||
@ -75,6 +76,10 @@ module Blocks : sig
|
|||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit * block, unit, unit,
|
unit * block, unit, unit,
|
||||||
MBytes.t list, unit) RPC_service.t
|
MBytes.t list, unit) RPC_service.t
|
||||||
|
val context:
|
||||||
|
([ `POST ], unit,
|
||||||
|
unit * block, unit, unit,
|
||||||
|
Context_hash.t, unit) RPC_service.t
|
||||||
|
|
||||||
type operations_param = {
|
type operations_param = {
|
||||||
contents: bool ;
|
contents: bool ;
|
||||||
|
@ -149,6 +149,7 @@ module RPC = struct
|
|||||||
validation_passes: int ; (* uint8 *)
|
validation_passes: int ; (* uint8 *)
|
||||||
operations_hash: Operation_list_list_hash.t ;
|
operations_hash: Operation_list_list_hash.t ;
|
||||||
fitness: MBytes.t list ;
|
fitness: MBytes.t list ;
|
||||||
|
context: Context_hash.t ;
|
||||||
data: MBytes.t ;
|
data: MBytes.t ;
|
||||||
operations: (Operation_hash.t * Operation.t) list list option ;
|
operations: (Operation_hash.t * Operation.t) list list option ;
|
||||||
protocol: Protocol_hash.t ;
|
protocol: Protocol_hash.t ;
|
||||||
@ -174,6 +175,7 @@ module RPC = struct
|
|||||||
validation_passes = header.shell.validation_passes ;
|
validation_passes = header.shell.validation_passes ;
|
||||||
operations_hash = header.shell.operations_hash ;
|
operations_hash = header.shell.operations_hash ;
|
||||||
fitness = header.shell.fitness ;
|
fitness = header.shell.fitness ;
|
||||||
|
context = header.shell.context ;
|
||||||
data = header.proto ;
|
data = header.proto ;
|
||||||
operations = Some operations ;
|
operations = Some operations ;
|
||||||
protocol ;
|
protocol ;
|
||||||
@ -281,6 +283,7 @@ module RPC = struct
|
|||||||
(fun ops -> Operation_list_hash.compute (List.map fst ops))
|
(fun ops -> Operation_list_hash.compute (List.map fst ops))
|
||||||
operations) ;
|
operations) ;
|
||||||
operations = Some operations ;
|
operations = Some operations ;
|
||||||
|
context = Context_hash.zero ;
|
||||||
data = MBytes.of_string "" ;
|
data = MBytes.of_string "" ;
|
||||||
net_id = head_net_id ;
|
net_id = head_net_id ;
|
||||||
test_network ;
|
test_network ;
|
||||||
@ -356,6 +359,7 @@ module RPC = struct
|
|||||||
validation_passes = List.length operation_hashes ;
|
validation_passes = List.length operation_hashes ;
|
||||||
operations_hash ;
|
operations_hash ;
|
||||||
fitness ;
|
fitness ;
|
||||||
|
context = Context_hash.zero ;
|
||||||
} ;
|
} ;
|
||||||
proto = MBytes.create 0 ;
|
proto = MBytes.create 0 ;
|
||||||
} ;
|
} ;
|
||||||
@ -490,7 +494,7 @@ module RPC = struct
|
|||||||
(List.map fst r.Preapply_result.applied))
|
(List.map fst r.Preapply_result.applied))
|
||||||
rs) in
|
rs) in
|
||||||
Prevalidation.end_prevalidation
|
Prevalidation.end_prevalidation
|
||||||
validation_state >>=? fun { fitness ; context } ->
|
validation_state >>=? fun { fitness ; context ; message } ->
|
||||||
let pred_shell_header = State.Block.shell_header predecessor in
|
let pred_shell_header = State.Block.shell_header predecessor in
|
||||||
State.Block.protocol_hash predecessor >>= fun pred_protocol ->
|
State.Block.protocol_hash predecessor >>= fun pred_protocol ->
|
||||||
Context.get_protocol context >>= fun protocol ->
|
Context.get_protocol context >>= fun protocol ->
|
||||||
@ -499,6 +503,7 @@ module RPC = struct
|
|||||||
pred_shell_header.proto_level
|
pred_shell_header.proto_level
|
||||||
else
|
else
|
||||||
((pred_shell_header.proto_level + 1) mod 256) in
|
((pred_shell_header.proto_level + 1) mod 256) in
|
||||||
|
Context.commit ?message ~time:timestamp context >>= fun context ->
|
||||||
let shell_header : Block_header.shell_header = {
|
let shell_header : Block_header.shell_header = {
|
||||||
level = Int32.succ pred_shell_header.level ;
|
level = Int32.succ pred_shell_header.level ;
|
||||||
proto_level ;
|
proto_level ;
|
||||||
@ -507,6 +512,7 @@ module RPC = struct
|
|||||||
validation_passes = List.length rs ;
|
validation_passes = List.length rs ;
|
||||||
operations_hash ;
|
operations_hash ;
|
||||||
fitness ;
|
fitness ;
|
||||||
|
context ;
|
||||||
} in
|
} in
|
||||||
return (shell_header, rs)
|
return (shell_header, rs)
|
||||||
|
|
||||||
|
@ -159,6 +159,7 @@ module Locked_block = struct
|
|||||||
fitness = [] ;
|
fitness = [] ;
|
||||||
validation_passes = 0 ;
|
validation_passes = 0 ;
|
||||||
operations_hash = Operation_list_list_hash.empty ;
|
operations_hash = Operation_list_list_hash.empty ;
|
||||||
|
context ;
|
||||||
} in
|
} in
|
||||||
let header : Block_header.t = { shell ; proto = MBytes.create 0 } in
|
let header : Block_header.t = { shell ; proto = MBytes.create 0 } in
|
||||||
Store.Block.Contents.store (store, genesis.block)
|
Store.Block.Contents.store (store, genesis.block)
|
||||||
|
@ -101,6 +101,7 @@ module Node_protocol_environment_sigs = struct
|
|||||||
and type Hash.Block_hash.t = Block_hash.t
|
and type Hash.Block_hash.t = Block_hash.t
|
||||||
and type Hash.Operation_hash.t = Operation_hash.t
|
and type Hash.Operation_hash.t = Operation_hash.t
|
||||||
and type Hash.Operation_list_list_hash.t = Operation_list_list_hash.t
|
and type Hash.Operation_list_list_hash.t = Operation_list_list_hash.t
|
||||||
|
and type Hash.Context_hash.t = Context_hash.t
|
||||||
and type Context.t = Context.t
|
and type Context.t = Context.t
|
||||||
and type Time.t = Time.t
|
and type Time.t = Time.t
|
||||||
and type MBytes.t = MBytes.t
|
and type MBytes.t = MBytes.t
|
||||||
|
@ -91,6 +91,7 @@ module Node_protocol_environment_sigs : sig
|
|||||||
and type Hash.Block_hash.t = Block_hash.t
|
and type Hash.Block_hash.t = Block_hash.t
|
||||||
and type Hash.Operation_hash.t = Operation_hash.t
|
and type Hash.Operation_hash.t = Operation_hash.t
|
||||||
and type Hash.Operation_list_list_hash.t = Operation_list_list_hash.t
|
and type Hash.Operation_list_list_hash.t = Operation_list_list_hash.t
|
||||||
|
and type Hash.Context_hash.t = Context_hash.t
|
||||||
and type Context.t = Context.t
|
and type Context.t = Context.t
|
||||||
and type Time.t = Time.t
|
and type Time.t = Time.t
|
||||||
and type MBytes.t = MBytes.t
|
and type MBytes.t = MBytes.t
|
||||||
|
@ -131,4 +131,7 @@ module Operation_list_list_hash :
|
|||||||
(** Protocol versions / source hashes. *)
|
(** Protocol versions / source hashes. *)
|
||||||
module Protocol_hash : HASH
|
module Protocol_hash : HASH
|
||||||
|
|
||||||
|
(** Commited conntext. *)
|
||||||
|
module Context_hash : HASH
|
||||||
|
|
||||||
module Net_id : HASH
|
module Net_id : HASH
|
||||||
|
@ -85,6 +85,7 @@ module Block_header : sig
|
|||||||
validation_passes: int ;
|
validation_passes: int ;
|
||||||
operations_hash: Operation_list_list_hash.t ;
|
operations_hash: Operation_list_list_hash.t ;
|
||||||
fitness: MBytes.t list ;
|
fitness: MBytes.t list ;
|
||||||
|
context: Context_hash.t ;
|
||||||
}
|
}
|
||||||
|
|
||||||
val shell_header_encoding: shell_header Data_encoding.t
|
val shell_header_encoding: shell_header Data_encoding.t
|
||||||
|
@ -58,21 +58,6 @@ let operation op =
|
|||||||
op,
|
op,
|
||||||
Data_encoding.Binary.to_bytes Operation.encoding op
|
Data_encoding.Binary.to_bytes Operation.encoding op
|
||||||
|
|
||||||
let block _state ?(operations = []) pred_hash pred name : Block_header.t =
|
|
||||||
let operations_hash =
|
|
||||||
Operation_list_list_hash.compute
|
|
||||||
[Operation_list_hash.compute operations] in
|
|
||||||
let fitness = incr_fitness pred.Block_header.shell.fitness in
|
|
||||||
let timestamp = incr_timestamp pred.shell.timestamp in
|
|
||||||
{ shell = {
|
|
||||||
level = Int32.succ pred.shell.level ;
|
|
||||||
proto_level = pred.shell.proto_level ;
|
|
||||||
predecessor = pred_hash ;
|
|
||||||
validation_passes = 1 ;
|
|
||||||
timestamp ; operations_hash ; fitness } ;
|
|
||||||
proto = MBytes.of_string name ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let equal_operation ?msg op1 op2 =
|
let equal_operation ?msg op1 op2 =
|
||||||
let msg = Assert.format_msg msg in
|
let msg = Assert.format_msg msg in
|
||||||
let eq op1 op2 =
|
let eq op1 op2 =
|
||||||
@ -98,7 +83,7 @@ let equal_block ?msg st1 st2 =
|
|||||||
| Some st -> Block_hash.to_hex (Block_header.hash st) in
|
| Some st -> Block_hash.to_hex (Block_header.hash st) in
|
||||||
Assert.equal ?msg ~prn ~eq st1 st2
|
Assert.equal ?msg ~prn ~eq st1 st2
|
||||||
|
|
||||||
let block _state ?(operations = []) (pred: State.Block.t) name
|
let block _state ?(context = Context_hash.zero) ?(operations = []) (pred: State.Block.t) name
|
||||||
: Block_header.t =
|
: Block_header.t =
|
||||||
let operations_hash =
|
let operations_hash =
|
||||||
Operation_list_list_hash.compute
|
Operation_list_list_hash.compute
|
||||||
@ -110,19 +95,21 @@ let block _state ?(operations = []) (pred: State.Block.t) name
|
|||||||
proto_level = pred_header.proto_level ;
|
proto_level = pred_header.proto_level ;
|
||||||
predecessor = State.Block.hash pred ;
|
predecessor = State.Block.hash pred ;
|
||||||
validation_passes = 1 ;
|
validation_passes = 1 ;
|
||||||
timestamp ; operations_hash ; fitness } ;
|
timestamp ; operations_hash ; fitness ;
|
||||||
|
context } ;
|
||||||
proto = MBytes.of_string name ;
|
proto = MBytes.of_string name ;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 ->
|
||||||
|
State.Block.context pred >>= fun predecessor_context ->
|
||||||
|
let rec attempt context =
|
||||||
begin
|
begin
|
||||||
let oph, op, _bytes = operation name in
|
let oph, op, _bytes = operation name in
|
||||||
let block = block state ~operations:[oph] pred name in
|
let block = block ?context state ~operations:[oph] pred name in
|
||||||
let hash = Block_header.hash block in
|
let hash = Block_header.hash block in
|
||||||
let pred_header = State.Block.header pred in
|
let pred_header = State.Block.header pred in
|
||||||
State.Block.context pred >>= fun predecessor_context ->
|
|
||||||
begin
|
begin
|
||||||
Proto.begin_application
|
Proto.begin_application
|
||||||
~predecessor_context
|
~predecessor_context
|
||||||
@ -138,9 +125,13 @@ let build_valid_chain state vtbl pred names =
|
|||||||
return vblock
|
return vblock
|
||||||
end >>= function
|
end >>= function
|
||||||
| Ok v -> Lwt.return v
|
| Ok v -> Lwt.return v
|
||||||
|
| Error [ State.Block.Inconsistent_hash (got, _) ] ->
|
||||||
|
(* Kind of a hack, but at least it tests idempotence to some extent. *)
|
||||||
|
attempt (Some got)
|
||||||
| Error err ->
|
| Error err ->
|
||||||
Error_monad.pp_print_error Format.err_formatter err ;
|
Error_monad.pp_print_error Format.err_formatter err ;
|
||||||
assert false)
|
assert false in
|
||||||
|
attempt None)
|
||||||
pred
|
pred
|
||||||
names >>= fun _ ->
|
names >>= fun _ ->
|
||||||
Lwt.return ()
|
Lwt.return ()
|
||||||
|
@ -83,7 +83,8 @@ let lolblock ?(operations = []) header =
|
|||||||
validation_passes = Random.int 32 ;
|
validation_passes = Random.int 32 ;
|
||||||
predecessor = genesis_block ; operations_hash ;
|
predecessor = genesis_block ; operations_hash ;
|
||||||
fitness = [MBytes.of_string @@ string_of_int @@ String.length header;
|
fitness = [MBytes.of_string @@ string_of_int @@ String.length header;
|
||||||
MBytes.of_string @@ string_of_int @@ 12] } ;
|
MBytes.of_string @@ string_of_int @@ 12] ;
|
||||||
|
context = Context_hash.zero } ;
|
||||||
proto = MBytes.of_string header ;
|
proto = MBytes.of_string header ;
|
||||||
} ;
|
} ;
|
||||||
max_operations_ttl = 0 ;
|
max_operations_ttl = 0 ;
|
||||||
|
Loading…
Reference in New Issue
Block a user