Shell: add the protocol level in the header of block

This commit is contained in:
Grégoire Henry 2017-04-12 18:22:40 +02:00
parent f9f5bca5a0
commit 0f247adea6
26 changed files with 110 additions and 41 deletions

View File

@ -15,9 +15,9 @@ module Services = Node_rpc_services
let errors cctxt = let errors cctxt =
call_service0 cctxt Services.Error.service () call_service0 cctxt Services.Error.service ()
let forge_block cctxt ?net_id ?level ?predecessor ?timestamp fitness ops header = let forge_block cctxt ?net_id ?level ?proto_level ?predecessor ?timestamp fitness ops header =
call_service0 cctxt Services.forge_block call_service0 cctxt Services.forge_block
(net_id, level, predecessor, timestamp, fitness, ops, header) (net_id, level, proto_level, predecessor, timestamp, fitness, ops, header)
let validate_block cctxt net block = let validate_block cctxt net block =
call_err_service0 cctxt Services.validate_block (net, block) call_err_service0 cctxt Services.validate_block (net, block)
@ -55,6 +55,7 @@ module Blocks = struct
hash: Block_hash.t ; hash: Block_hash.t ;
net_id: Net_id.t ; net_id: Net_id.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ; (* uint8 *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
operations_hash: Operation_list_list_hash.t ; operations_hash: Operation_list_list_hash.t ;

View File

@ -16,6 +16,7 @@ val forge_block:
config -> config ->
?net_id:Net_id.t -> ?net_id:Net_id.t ->
?level:Int32.t -> ?level:Int32.t ->
?proto_level:int ->
?predecessor:Block_hash.t -> ?predecessor:Block_hash.t ->
?timestamp:Time.t -> ?timestamp:Time.t ->
Fitness.fitness -> Fitness.fitness ->
@ -105,6 +106,7 @@ module Blocks : sig
hash: Block_hash.t ; hash: Block_hash.t ;
net_id: Net_id.t ; net_id: Net_id.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ; (* uint8 *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
operations_hash: Operation_list_list_hash.t ; operations_hash: Operation_list_list_hash.t ;

View File

@ -52,6 +52,7 @@ let inject_block cctxt block
(List.map Operation_list_hash.compute operations) in (List.map Operation_list_hash.compute operations) in
let shell = let shell =
{ Store.Block_header.net_id = bi.net_id ; level = bi.level ; { Store.Block_header.net_id = bi.net_id ; level = bi.level ;
proto_level = bi.proto_level ;
predecessor = bi.hash ; timestamp ; fitness ; operations_hash } in predecessor = bi.hash ; timestamp ; fitness ; operations_hash } in
compute_stamp cctxt block compute_stamp cctxt block
src_sk shell priority seed_nonce_hash >>=? fun proof_of_work_nonce -> src_sk shell priority seed_nonce_hash >>=? fun proof_of_work_nonce ->
@ -63,6 +64,7 @@ let inject_block cctxt block
~fitness ~fitness
~operations_hash ~operations_hash
~level:level.level ~level:level.level
~proto_level:bi.proto_level
~priority:priority ~priority:priority
~seed_nonce_hash ~seed_nonce_hash
~proof_of_work_nonce ~proof_of_work_nonce

View File

@ -246,10 +246,10 @@ module Helpers = struct
end end
let block cctxt let block cctxt
block ~net ~predecessor ~timestamp ~fitness ~operations_hash block ~net ~predecessor ~timestamp ~fitness ~operations_hash
~level ~priority ~seed_nonce_hash ~proof_of_work_nonce () = ~level ~priority ~proto_level ~seed_nonce_hash ~proof_of_work_nonce () =
call_error_service1 cctxt Services.Helpers.Forge.block block call_error_service1 cctxt Services.Helpers.Forge.block block
(net, predecessor, timestamp, fitness, operations_hash, ((net, predecessor, timestamp, fitness, operations_hash),
level, priority, seed_nonce_hash, proof_of_work_nonce) (level, priority, proto_level, seed_nonce_hash, proof_of_work_nonce))
end end
module Parse = struct module Parse = struct

View File

@ -301,6 +301,7 @@ module Helpers : sig
operations_hash:Operation_list_list_hash.t -> operations_hash:Operation_list_list_hash.t ->
level:Raw_level.t -> level:Raw_level.t ->
priority:int -> priority:int ->
proto_level:int ->
seed_nonce_hash:Nonce_hash.t -> seed_nonce_hash:Nonce_hash.t ->
proof_of_work_nonce:MBytes.t -> proof_of_work_nonce:MBytes.t ->
unit -> MBytes.t tzresult Lwt.t unit -> MBytes.t tzresult Lwt.t

View File

@ -29,7 +29,7 @@ let forge_block
Client_node_rpcs.Blocks.level rpc_config block >>=? fun level -> Client_node_rpcs.Blocks.level rpc_config block >>=? fun level ->
call_service1 rpc_config call_service1 rpc_config
Services.Forge.block block Services.Forge.block block
((net_id, Int32.succ level, pred, timestamp, fitness), command) ((net_id, Int32.succ level, 1, pred, timestamp, fitness), command)
let mine rpc_config ?timestamp block command fitness seckey = let mine rpc_config ?timestamp block command fitness seckey =
Client_blocks.get_block_info rpc_config block >>=? fun bi -> Client_blocks.get_block_info rpc_config block >>=? fun bi ->

View File

@ -253,6 +253,7 @@ module Block_header = struct
type shell_header = { type shell_header = {
net_id: Net_id.t ; net_id: Net_id.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ; (* uint8 *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
operations_hash: Operation_list_list_hash.t ; operations_hash: Operation_list_list_hash.t ;
@ -262,17 +263,18 @@ module Block_header = struct
let shell_header_encoding = let shell_header_encoding =
let open Data_encoding in let open Data_encoding in
conv conv
(fun { net_id ; level ; predecessor ; (fun { net_id ; level ; proto_level ; predecessor ;
timestamp ; operations_hash ; fitness } -> timestamp ; operations_hash ; fitness } ->
(net_id, level, predecessor, (net_id, level, proto_level, predecessor,
timestamp, operations_hash, fitness)) timestamp, operations_hash, fitness))
(fun (net_id, level, predecessor, (fun (net_id, level, proto_level, predecessor,
timestamp, operations_hash, fitness) -> timestamp, operations_hash, fitness) ->
{ net_id ; level ; predecessor ; { net_id ; level ; proto_level ; predecessor ;
timestamp ; operations_hash ; fitness }) timestamp ; operations_hash ; fitness })
(obj6 (obj7
(req "net_id" Net_id.encoding) (req "net_id" Net_id.encoding)
(req "level" int32) (req "level" int32)
(req "proto" uint8)
(req "predecessor" Block_hash.encoding) (req "predecessor" Block_hash.encoding)
(req "timestamp" Time.encoding) (req "timestamp" Time.encoding)
(req "operations_hash" Operation_list_list_hash.encoding) (req "operations_hash" Operation_list_list_hash.encoding)

View File

@ -172,6 +172,7 @@ module Block_header : sig
type shell_header = { type shell_header = {
net_id: Net_id.t ; net_id: Net_id.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ; (* uint8 *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
operations_hash: Operation_list_list_hash.t ; operations_hash: Operation_list_list_hash.t ;

View File

@ -139,6 +139,7 @@ module RPC = struct
hash: Block_hash.t ; hash: Block_hash.t ;
net_id: Net_id.t ; net_id: Net_id.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ; (* uint8 *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
operations_hash: Operation_list_list_hash.t ; operations_hash: Operation_list_list_hash.t ;
@ -153,6 +154,7 @@ module RPC = struct
hash = block.hash ; hash = block.hash ;
net_id = block.net_id ; net_id = block.net_id ;
level = block.level ; level = block.level ;
proto_level = block.proto_level ;
predecessor = block.predecessor ; predecessor = block.predecessor ;
timestamp = block.timestamp ; timestamp = block.timestamp ;
operations_hash = block.operations_hash ; operations_hash = block.operations_hash ;
@ -266,12 +268,18 @@ module RPC = struct
| Ok { context ; fitness } -> | Ok { context ; fitness } ->
Context.get_protocol context >>= fun protocol -> Context.get_protocol context >>= fun protocol ->
Context.get_test_network context >>= fun test_network -> Context.get_test_network context >>= fun test_network ->
let proto_level =
if Protocol_hash.equal protocol head.protocol_hash then
head.proto_level
else
((head.proto_level + 1) mod 256) in
let operations = let operations =
let pv_result, _ = Prevalidator.operations pv in let pv_result, _ = Prevalidator.operations pv in
[ pv_result.applied ] in [ pv_result.applied ] in
Lwt.return Lwt.return
{ hash = prevalidation_hash ; { hash = prevalidation_hash ;
level = Int32.succ head.level ; level = Int32.succ head.level ;
proto_level ;
predecessor = head.hash ; predecessor = head.hash ;
fitness ; fitness ;
timestamp = Prevalidator.timestamp pv ; timestamp = Prevalidator.timestamp pv ;

View File

@ -401,15 +401,17 @@ let build_rpc_directory node =
RPC.register1 dir Services.Protocols.contents (get_protocols node) in RPC.register1 dir Services.Protocols.contents (get_protocols node) in
let dir = let dir =
let implementation let implementation
(net_id, level, pred, time, fitness, operations_hash, header) = (net_id, level, proto_level, pred, time,
fitness, operations_hash, header) =
Node.RPC.block_info node (`Head 0) >>= fun bi -> Node.RPC.block_info node (`Head 0) >>= fun bi ->
let timestamp = Utils.unopt ~default:(Time.now ()) time in let timestamp = Utils.unopt ~default:(Time.now ()) time in
let net_id = Utils.unopt ~default:bi.net_id net_id in let net_id = Utils.unopt ~default:bi.net_id net_id in
let predecessor = Utils.unopt ~default:bi.hash pred in let predecessor = Utils.unopt ~default:bi.hash pred in
let level = Utils.unopt ~default:(Int32.succ bi.level) level in let level = Utils.unopt ~default:(Int32.succ bi.level) level in
let proto_level = Utils.unopt ~default:bi.proto_level proto_level in
let res = let res =
Data_encoding.Binary.to_bytes Store.Block_header.encoding { Data_encoding.Binary.to_bytes Store.Block_header.encoding {
shell = { net_id ; predecessor ; level ; shell = { net_id ; predecessor ; level ; proto_level ;
timestamp ; fitness ; operations_hash } ; timestamp ; fitness ; operations_hash } ;
proto = header ; proto = header ;
} in } in

View File

@ -59,6 +59,7 @@ module Blocks = struct
hash: Block_hash.t ; hash: Block_hash.t ;
net_id: Net_id.t ; net_id: Net_id.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ; (* uint8 *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
operations_hash: Operation_list_list_hash.t ; operations_hash: Operation_list_list_hash.t ;
@ -71,20 +72,20 @@ module Blocks = struct
let block_info_encoding = let block_info_encoding =
conv conv
(fun { hash ; net_id ; level ; predecessor ; (fun { hash ; net_id ; level ; proto_level ; predecessor ;
fitness ; timestamp ; protocol ; operations_hash ; data ; fitness ; timestamp ; protocol ; operations_hash ; data ;
operations ; test_network } -> operations ; test_network } ->
({ Store.Block_header.shell = ({ Store.Block_header.shell =
{ net_id ; level ; predecessor ; { net_id ; level ; proto_level ; predecessor ;
timestamp ; operations_hash ; fitness } ; timestamp ; operations_hash ; fitness } ;
proto = data }, proto = data },
(hash, operations, protocol, test_network))) (hash, operations, protocol, test_network)))
(fun ({ Store.Block_header.shell = (fun ({ Store.Block_header.shell =
{ net_id ; level ; predecessor ; { net_id ; level ; proto_level ; predecessor ;
timestamp ; operations_hash ; fitness } ; timestamp ; operations_hash ; fitness } ;
proto = data }, proto = data },
(hash, operations, protocol, test_network)) -> (hash, operations, protocol, test_network)) ->
{ hash ; net_id ; level ; predecessor ; { hash ; net_id ; level ; proto_level ; predecessor ;
fitness ; timestamp ; protocol ; operations_hash ; data ; fitness ; timestamp ; protocol ; operations_hash ; data ;
operations ; test_network }) operations ; test_network })
(dynamic_size (dynamic_size
@ -632,9 +633,10 @@ let forge_block =
RPC.service RPC.service
~description: "Forge a block header" ~description: "Forge a block header"
~input: ~input:
(obj7 (obj8
(opt "net_id" Net_id.encoding) (opt "net_id" Net_id.encoding)
(opt "level" int32) (opt "level" int32)
(opt "proto_level" uint8)
(opt "predecessor" Block_hash.encoding) (opt "predecessor" Block_hash.encoding)
(opt "timestamp" Time.encoding) (opt "timestamp" Time.encoding)
(req "fitness" Fitness.encoding) (req "fitness" Fitness.encoding)

View File

@ -30,6 +30,7 @@ module Blocks : sig
hash: Block_hash.t ; hash: Block_hash.t ;
net_id: Net_id.t ; net_id: Net_id.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ; (* uint8 *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
operations_hash: Operation_list_list_hash.t ; operations_hash: Operation_list_list_hash.t ;
@ -178,8 +179,8 @@ end
val forge_block: val forge_block:
(unit, unit, (unit, unit,
Net_id.t option * Int32.t option * Block_hash.t option * Time.t option * Net_id.t option * Int32.t option * int option * Block_hash.t option *
Fitness.fitness * Operation_list_list_hash.t * MBytes.t, Time.t option * Fitness.fitness * Operation_list_list_hash.t * MBytes.t,
MBytes.t) RPC.service MBytes.t) RPC.service
val validate_block: val validate_block:

View File

@ -111,6 +111,7 @@ and valid_block = {
net_id: Net_id.t ; net_id: Net_id.t ;
hash: Block_hash.t ; hash: Block_hash.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ;
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
fitness: Protocol.fitness ; fitness: Protocol.fitness ;
@ -136,6 +137,7 @@ let build_valid_block
net_id = header.Store.Block_header.shell.net_id ; net_id = header.Store.Block_header.shell.net_id ;
hash ; hash ;
level = header.shell.level ; level = header.shell.level ;
proto_level = header.shell.proto_level ;
predecessor = header.shell.predecessor ; predecessor = header.shell.predecessor ;
timestamp = header.shell.timestamp ; timestamp = header.shell.timestamp ;
discovery_time ; discovery_time ;
@ -531,6 +533,7 @@ module Raw_block_header = struct
let shell : Store.Block_header.shell_header = { let shell : Store.Block_header.shell_header = {
net_id = Net_id.of_block_hash genesis.block; net_id = Net_id.of_block_hash genesis.block;
level = 0l ; level = 0l ;
proto_level = 0 ;
predecessor = genesis.block ; predecessor = genesis.block ;
timestamp = genesis.time ; timestamp = genesis.time ;
fitness = [] ; fitness = [] ;
@ -686,6 +689,7 @@ module Block_header = struct
type shell_header = Store.Block_header.shell_header = { type shell_header = Store.Block_header.shell_header = {
net_id: Net_id.t ; net_id: Net_id.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ; (* uint8 *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
operations_hash: Operation_list_list_hash.t ; operations_hash: Operation_list_list_hash.t ;
@ -927,6 +931,7 @@ module Valid_block = struct
net_id: Net_id.t ; net_id: Net_id.t ;
hash: Block_hash.t ; hash: Block_hash.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ;
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
fitness: Fitness.fitness ; fitness: Fitness.fitness ;

View File

@ -145,6 +145,7 @@ module Block_header : sig
type shell_header = Store.Block_header.shell_header = { type shell_header = Store.Block_header.shell_header = {
net_id: Net_id.t ; net_id: Net_id.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ; (* uint8 *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
operations_hash: Operation_list_list_hash.t ; operations_hash: Operation_list_list_hash.t ;
@ -248,6 +249,8 @@ module Valid_block : sig
(** The block hash. *) (** The block hash. *)
level: Int32.t ; level: Int32.t ;
(** The number of preceding block in the chain. *) (** The number of preceding block in the chain. *)
proto_level: int ;
(** The number of protocol amendment block in the chain (modulo 256) *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
(** The preceding block in the chain. *) (** The preceding block in the chain. *)
timestamp: Time.t ; timestamp: Time.t ;

View File

@ -145,6 +145,7 @@ type error +=
| Non_increasing_timestamp | Non_increasing_timestamp
| Non_increasing_fitness | Non_increasing_fitness
| Wrong_level of Int32.t * Int32.t | Wrong_level of Int32.t * Int32.t
| Wrong_proto_level of int * int
let () = let () =
register_error_kind register_error_kind
@ -159,7 +160,20 @@ let () =
(req "expected" int32) (req "expected" int32)
(req "provided" int32)) (req "provided" int32))
(function Wrong_level (e, g) -> Some (e, g) | _ -> None) (function Wrong_level (e, g) -> Some (e, g) | _ -> None)
(fun (e, g) -> Wrong_level (e, g)) (fun (e, g) -> Wrong_level (e, g)) ;
register_error_kind
`Permanent
~id:"validator.wrong_proto_level"
~title:"Wrong protocol level"
~description:"The protocol level is not the expected one"
~pp:(fun ppf (e, g) ->
Format.fprintf ppf
"The declared protocol level %d is not %d" g e)
Data_encoding.(obj2
(req "expected" uint8)
(req "provided" uint8))
(function Wrong_proto_level (e, g) -> Some (e, g) | _ -> None)
(fun (e, g) -> Wrong_proto_level (e, g))
let apply_block net db let apply_block net db
(pred: State.Valid_block.t) hash (block: State.Block_header.t) = (pred: State.Valid_block.t) hash (block: State.Block_header.t) =
@ -231,6 +245,15 @@ let apply_block net db
return state) return state)
state parsed_operations >>=? fun state -> state parsed_operations >>=? fun state ->
Proto.finalize_block state >>=? fun new_context -> Proto.finalize_block state >>=? fun new_context ->
Context.get_protocol new_context.context >>= fun new_protocol ->
let expected_proto_level =
if Protocol_hash.equal new_protocol pred.protocol_hash then
pred.proto_level
else
(pred.proto_level + 1) mod 256 in
fail_when (block.shell.proto_level <> expected_proto_level)
(Wrong_proto_level (block.shell.proto_level, expected_proto_level))
>>=? fun () ->
lwt_log_info "validation of %a: success" lwt_log_info "validation of %a: success"
Block_hash.pp_short hash >>= fun () -> Block_hash.pp_short hash >>= fun () ->
return new_context return new_context

View File

@ -25,6 +25,7 @@ type raw_operation = Store.Operation.t = {
type shell_block = Store.Block_header.shell_header = type shell_block = Store.Block_header.shell_header =
{ net_id: Net_id.t ; { net_id: Net_id.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ; (* uint8 *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
operations_hash: Operation_list_list_hash.t ; operations_hash: Operation_list_list_hash.t ;

View File

@ -46,6 +46,7 @@ let raw_operation_encoding = Store.Operation.encoding
type shell_block = Store.Block_header.shell_header = { type shell_block = Store.Block_header.shell_header = {
net_id: Net_id.t ; net_id: Net_id.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ; (* uint8 *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
operations_hash: Operation_list_list_hash.t ; operations_hash: Operation_list_list_hash.t ;

View File

@ -21,6 +21,7 @@ val raw_operation_encoding: raw_operation Data_encoding.t
type shell_block = Store.Block_header.shell_header = { type shell_block = Store.Block_header.shell_header = {
net_id: Net_id.t ; net_id: Net_id.t ;
level: Int32.t ; level: Int32.t ;
proto_level: int ; (* uint8 *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
timestamp: Time.t ; timestamp: Time.t ;
operations_hash: Operation_list_list_hash.t ; operations_hash: Operation_list_list_hash.t ;

View File

@ -62,14 +62,14 @@ type error +=
| Cant_parse_proto_header | Cant_parse_proto_header
let parse_header let parse_header
({ shell = { net_id ; level ; predecessor ; ({ shell = { net_id ; level ; proto_level ; predecessor ;
timestamp ; fitness ; operations_hash } ; timestamp ; fitness ; operations_hash } ;
proto } : Updater.raw_block) : header tzresult = proto } : Updater.raw_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 =
{ Updater.net_id ; level ; predecessor ; { Updater.net_id ; level ; proto_level ; predecessor ;
timestamp ; fitness ; operations_hash } in timestamp ; fitness ; operations_hash } in
Ok { shell ; proto ; signature } Ok { shell ; proto ; signature }

View File

@ -556,17 +556,21 @@ module Helpers = struct
RPC.service RPC.service
~description: "Forge a block header" ~description: "Forge a block header"
~input: ~input:
(obj9 (merge_objs
(req "net_id" Net_id.encoding) (obj5
(req "predecessor" Block_hash.encoding) (req "net_id" Net_id.encoding)
(req "timestamp" Timestamp.encoding) (req "predecessor" Block_hash.encoding)
(req "fitness" Fitness.encoding) (req "timestamp" Timestamp.encoding)
(req "operations" Operation_list_list_hash.encoding) (req "fitness" Fitness.encoding)
(req "level" Raw_level.encoding) (req "operations" Operation_list_list_hash.encoding))
(req "priority" uint16) (obj5
(req "nonce_hash" Nonce_hash.encoding) (req "level" Raw_level.encoding)
(req "proof_of_work_nonce" (req "priority" uint16)
(Fixed.bytes Tezos_context.Constants.proof_of_work_nonce_size))) (req "proto_level" uint8)
(req "nonce_hash" Nonce_hash.encoding)
(req "proof_of_work_nonce"
(Fixed.bytes
Tezos_context.Constants.proof_of_work_nonce_size))))
~output: (wrap_tzerror bytes) ~output: (wrap_tzerror bytes)
RPC.Path.(custom_root / "helpers" / "forge" / "block") RPC.Path.(custom_root / "helpers" / "forge" / "block")

View File

@ -434,11 +434,11 @@ let forge_operations _ctxt (shell, proto) =
let () = register1 Services.Helpers.Forge.operations forge_operations let () = register1 Services.Helpers.Forge.operations forge_operations
let forge_block _ctxt let forge_block _ctxt
(net_id, predecessor, timestamp, fitness, operations_hash, ((net_id, predecessor, timestamp, fitness, operations_hash),
level, priority, seed_nonce_hash, proof_of_work_nonce) : MBytes.t tzresult Lwt.t = (level, priority, proto_level, seed_nonce_hash, proof_of_work_nonce)) : MBytes.t tzresult Lwt.t =
let level = Raw_level.to_int32 level in let level = Raw_level.to_int32 level in
return (Block.forge_header return (Block.forge_header
{ net_id ; level ; predecessor ; { net_id ; level ; proto_level ; predecessor ;
timestamp ; fitness ; operations_hash } timestamp ; fitness ; operations_hash }
{ priority ; seed_nonce_hash ; proof_of_work_nonce }) { priority ; seed_nonce_hash ; proof_of_work_nonce })

View File

@ -21,6 +21,8 @@ type shell_block = {
(** The genesis of the chain this block belongs to. *) (** The genesis of the chain this block belongs to. *)
level: Int32.t ; level: Int32.t ;
(** The number of predecessing block in the chain. *) (** The number of predecessing block in the chain. *)
proto_level: int ;
(** The number of protocol amendment block in the chain (modulo 256) *)
predecessor: Block_hash.t ; predecessor: Block_hash.t ;
(** The preceding block in the chain. *) (** The preceding block in the chain. *)
timestamp: Time.t ; timestamp: Time.t ;

View File

@ -38,9 +38,10 @@ module Forge = struct
~description: "Forge a block" ~description: "Forge a block"
~input: ~input:
(merge_objs (merge_objs
(obj5 (obj6
(req "net_id" Net_id.encoding) (req "net_id" Net_id.encoding)
(req "level" int32) (req "level" int32)
(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))
@ -63,8 +64,9 @@ let rpc_services : Updater.rpc_context RPC.directory =
RPC.register RPC.register
dir dir
(Forge.block RPC.Path.root) (Forge.block RPC.Path.root)
(fun _ctxt ((net_id, level, predecessor, timestamp, fitness), command) -> (fun _ctxt ((net_id, level, proto_level, predecessor,
let shell = { Updater.net_id ; level ; predecessor ; timestamp, fitness), command) ->
let shell = { Updater.net_id ; level ; proto_level ; predecessor ;
timestamp ; fitness ; operations_hash } in timestamp ; fitness ; operations_hash } 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

View File

@ -399,7 +399,8 @@ module Mining = struct
let shell = let shell =
{ Store.Block_header.net_id = bi.net_id ; predecessor = bi.hash ; { Store.Block_header.net_id = bi.net_id ; predecessor = bi.hash ;
timestamp ; fitness ; operations_hash ; timestamp ; fitness ; operations_hash ;
level = Raw_level.to_int32 level.level } in level = Raw_level.to_int32 level.level ;
proto_level = 1 } in
mine_stamp mine_stamp
block src_sk shell priority seed_nonce_hash >>=? fun proof_of_work_nonce -> block src_sk shell priority seed_nonce_hash >>=? fun proof_of_work_nonce ->
Client_proto_rpcs.Helpers.Forge.block rpc_config Client_proto_rpcs.Helpers.Forge.block rpc_config
@ -410,6 +411,7 @@ module Mining = struct
~fitness ~fitness
~operations_hash ~operations_hash
~level:level.level ~level:level.level
~proto_level:1
~priority ~priority
~seed_nonce_hash ~seed_nonce_hash
~proof_of_work_nonce ~proof_of_work_nonce

View File

@ -70,6 +70,7 @@ let block _state ?(operations = []) pred_hash pred name : Store.Block_header.t =
{ shell = { { shell = {
net_id = pred.shell.net_id ; net_id = pred.shell.net_id ;
level = Int32.succ pred.shell.level ; level = Int32.succ pred.shell.level ;
proto_level = pred.shell.proto_level ;
predecessor = pred_hash ; predecessor = pred_hash ;
timestamp ; operations_hash ; fitness } ; timestamp ; operations_hash ; fitness } ;
proto = MBytes.of_string name ; proto = MBytes.of_string name ;
@ -141,6 +142,7 @@ let block _state ?(operations = []) (pred: State.Valid_block.t) name
let timestamp = incr_timestamp pred.timestamp in let timestamp = incr_timestamp pred.timestamp in
{ shell = { net_id = pred.net_id ; { shell = { net_id = pred.net_id ;
level = Int32.succ pred.level ; level = Int32.succ pred.level ;
proto_level = pred.proto_level ;
predecessor = pred.hash ; predecessor = pred.hash ;
timestamp ; operations_hash ; fitness } ; timestamp ; operations_hash ; fitness } ;
proto = MBytes.of_string name ; proto = MBytes.of_string name ;

View File

@ -95,6 +95,7 @@ let lolblock ?(operations = []) header =
{ Store.Block_header.shell = { Store.Block_header.shell =
{ timestamp = Time.of_seconds (Random.int64 1500L) ; { timestamp = Time.of_seconds (Random.int64 1500L) ;
level = 0l ; (* dummy *) level = 0l ; (* dummy *)
proto_level = 0 ; (* dummy *)
net_id ; net_id ;
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;