Shell: remove net_id from the block header.

This commit is contained in:
Grégoire Henry 2017-11-14 03:14:26 +01:00 committed by Benjamin Canou
parent b7deebaf42
commit 178d839ee1
23 changed files with 113 additions and 83 deletions

View File

@ -18,9 +18,11 @@ let errors cctxt =
let forge_block_header cctxt header =
call_service0 cctxt Services.forge_block_header header
let inject_block cctxt ?(async = false) ?(force = false) raw operations =
let inject_block cctxt
?(async = false) ?(force = false) ?net_id
raw operations =
call_err_service0 cctxt Services.inject_block
{ raw ; blocking = not async ; force ; operations }
{ raw ; blocking = not async ; force ; net_id ; operations }
let inject_operation cctxt ?(async = false) ?force ?net_id operation =
call_err_service0 cctxt Services.inject_operation

View File

@ -19,7 +19,7 @@ val forge_block_header:
val inject_block:
config ->
?async:bool -> ?force:bool ->
?async:bool -> ?force:bool -> ?net_id:Net_id.t ->
MBytes.t -> Operation.t list list ->
Block_hash.t tzresult Lwt.t
(** [inject_block cctxt ?async ?force raw_block] tries to inject

View File

@ -9,6 +9,7 @@
type block_info = {
hash: Block_hash.t ;
net_id: Net_id.t ;
predecessor: Block_hash.t ;
fitness: MBytes.t list ;
timestamp: Time.t ;
@ -17,21 +18,22 @@ type block_info = {
}
let convert_block_info cctxt
( { hash ; predecessor ; fitness ; timestamp ; protocol }
( { hash ; net_id ; predecessor ; fitness ; timestamp ; protocol }
: Client_node_rpcs.Blocks.block_info ) =
Client_proto_rpcs.Context.level cctxt (`Hash hash) >>= function
| Ok level ->
Lwt.return
(Some { hash ; predecessor ; fitness ; timestamp ; protocol ; level })
(Some { hash ; net_id ; predecessor ;
fitness ; timestamp ; protocol ; level })
| Error _ ->
(* TODO log error *)
Lwt.return_none
let convert_block_info_err cctxt
( { hash ; predecessor ; fitness ; timestamp ; protocol }
( { hash ; net_id ; predecessor ; fitness ; timestamp ; protocol }
: Client_node_rpcs.Blocks.block_info ) =
Client_proto_rpcs.Context.level cctxt (`Hash hash) >>=? fun level ->
return { hash ; predecessor ; fitness ; timestamp ; protocol ; level }
return { hash ; net_id ; predecessor ; fitness ; timestamp ; protocol ; level }
let info cctxt ?include_ops block =
Client_node_rpcs.Blocks.info cctxt ?include_ops block >>=? fun block ->

View File

@ -9,6 +9,7 @@
type block_info = {
hash: Block_hash.t ;
net_id: Net_id.t ;
predecessor: Block_hash.t ;
fitness: MBytes.t list ;
timestamp: Time.t ;

View File

@ -61,13 +61,14 @@ let assert_valid_operations_hash shell_header operations =
inconsistent header.")
let inject_block cctxt
?force ~shell_header ~priority ~seed_nonce_hash ~src_sk operations =
?force ?net_id
~shell_header ~priority ~seed_nonce_hash ~src_sk operations =
assert_valid_operations_hash shell_header operations >>=? fun () ->
let block = `Hash shell_header.Tezos_data.Block_header.predecessor in
forge_block_header cctxt block
src_sk shell_header priority seed_nonce_hash >>=? fun signed_header ->
Client_node_rpcs.inject_block cctxt
?force signed_header operations >>=? fun block_hash ->
?force ?net_id signed_header operations >>=? fun block_hash ->
return block_hash
type error +=
@ -174,8 +175,9 @@ let forge_block cctxt block
let operations =
if not best_effort then operations
else List.map snd result.applied in
Client_node_rpcs.Blocks.info cctxt block >>=? fun {net_id} ->
inject_block cctxt
?force ~shell_header ~priority ~seed_nonce_hash ~src_sk
?force ~net_id ~shell_header ~priority ~seed_nonce_hash ~src_sk
[operations]
else
Lwt.return_error @@
@ -507,7 +509,8 @@ let mine cctxt state =
Fitness.pp shell_header.fitness >>= fun () ->
Client_keys.get_key cctxt delegate >>=? fun (_,_,src_sk) ->
inject_block cctxt.rpc_config
~force:true ~shell_header ~priority ~seed_nonce_hash ~src_sk
~force:true ~net_id:bi.net_id
~shell_header ~priority ~seed_nonce_hash ~src_sk
[List.map snd operations.applied]
|> trace_exn (Failure "Error while injecting block") >>=? fun block_hash ->
State.record_block cctxt level block_hash seed_nonce

View File

@ -16,6 +16,7 @@ val generate_seed_nonce: unit -> Nonce.t
val inject_block:
Client_rpcs.config ->
?force:bool ->
?net_id:Net_id.t ->
shell_header:Block_header.shell_header ->
priority:int ->
seed_nonce_hash:Nonce_hash.t ->

View File

@ -47,8 +47,7 @@ let mine cctxt =
(cctxt.message "Cannot parse fitness: %a" Environment.Fitness.pp bi.fitness);
exit 2 in
Client_node_rpcs.forge_block_header cctxt.rpc_config
{ shell = { net_id = bi.net_id ;
predecessor = bi.hash ;
{ shell = { predecessor = bi.hash ;
proto_level = bi.proto_level ;
level = Int32.succ bi.level ;
timestamp = Time.now () ;
@ -56,7 +55,7 @@ let mine cctxt =
validation_passes = 0 ;
operations_hash = Operation_list_list_hash.empty } ;
proto = MBytes.create 0 } >>=? fun bytes ->
Client_node_rpcs.inject_block cctxt.rpc_config bytes [] >>=? fun hash ->
Client_node_rpcs.inject_block cctxt.rpc_config ~net_id:bi.net_id bytes [] >>=? fun hash ->
cctxt.answer "Injected %a" Block_hash.pp_short hash >>= fun () ->
return ()

View File

@ -74,7 +74,6 @@ end
module Block_header : sig
type shell_header = {
net_id: Net_id.t ;
level: Int32.t ;
(** The number of preceding block in this chain, i.e. the genesis
has level 0. *)

View File

@ -24,7 +24,9 @@
(executable
((name client_main)
(public_name tezos-client)
(libraries (lwt utils client_lib client_embedded_genesis client_embedded_alpha))
(libraries (lwt utils client_lib
client_embedded_genesis
client_embedded_alpha))
(flags (:standard -w -9+27-30-32-40@8
-safe-string
-linkall))

View File

@ -340,15 +340,27 @@ let state { disk } = disk
let net_state { net_state } = net_state
let db { global_db } = global_db
let find_pending_block_header active_nets h =
Net_id.Table.fold
(fun _net_id net_db acc ->
match acc with
| Some _ -> acc
| None when Raw_block_header.Table.pending
net_db.block_header_db.table h ->
Some net_db
| None -> None)
active_nets
None
let find_pending_operation active_nets h =
Net_id.Table.fold
(fun _net_id net_db acc ->
match acc with
| Some _ -> acc
| None ->
if Raw_operation.Table.pending net_db.operation_db.table h then
| None when Raw_operation.Table.pending
net_db.operation_db.table h ->
Some net_db
else None)
| None -> None)
active_nets
None
@ -465,12 +477,17 @@ module P2p_reader = struct
P2p.try_send global_db.p2p state.conn (Block_header header))
hashes
| Block_header block ->
may_handle state block.shell.net_id @@ fun net_db ->
| Block_header block -> begin
let hash = Block_header.hash block in
match find_pending_block_header state.peer_active_nets hash with
| None ->
(* TODO some penalty. *)
Lwt.return_unit
| Some net_db ->
Raw_block_header.Table.notify
net_db.block_header_db.table state.gid hash block >>= fun () ->
Lwt.return_unit
end
| Get_operations (net_id, hashes) ->
may_handle state net_id @@ fun net_db ->
@ -720,7 +737,6 @@ let clear_block net_db hash n =
let commit_block net_db hash header operations result =
assert (Block_hash.equal hash (Block_header.hash header)) ;
assert (Net_id.equal (State.Net.id net_db.net_state) header.shell.net_id) ;
assert (List.length operations = header.shell.validation_passes) ;
State.Block.store net_db.net_state header operations result >>=? fun res ->
clear_block net_db hash header.shell.validation_passes ;
@ -728,21 +744,10 @@ let commit_block net_db hash header operations result =
let commit_invalid_block net_db hash header _err =
assert (Block_hash.equal hash (Block_header.hash header)) ;
assert (Net_id.equal (State.Net.id net_db.net_state) header.shell.net_id) ;
State.Block.store_invalid net_db.net_state header >>=? fun res ->
clear_block net_db hash header.shell.validation_passes ;
return res
let inject_block_header net_db h b =
fail_unless
(Net_id.equal
b.Block_header.shell.net_id
(State.Net.id net_db.net_state))
(failure "Inconsitent net_id in operation") >>=? fun () ->
Raw_block_header.Table.inject
net_db.block_header_db.table h b >>= fun res ->
return res
let inject_operation net_db h op =
assert (Operation_hash.equal h (Operation.hash op)) ;
Raw_operation.Table.inject net_db.operation_db.table h op >>= fun res ->

View File

@ -40,9 +40,9 @@ let inject_protocol state ?force:_ proto =
in
Lwt.return (hash, validation)
let inject_block validator ?force bytes operations =
let inject_block validator ?force ?net_id bytes operations =
Validator.validate_block
validator ?force bytes operations >>=? fun (hash, block) ->
validator ?force ?net_id bytes operations >>=? fun (hash, block) ->
return (hash, (block >>=? fun _ -> return ()))
type t = {
@ -52,6 +52,7 @@ type t = {
mainnet_validator: Net_validator.t ;
inject_block:
?force:bool ->
?net_id:Net_id.t ->
MBytes.t -> Operation.t list list ->
(Block_hash.t * unit tzresult Lwt.t) tzresult Lwt.t ;
inject_operation:
@ -165,7 +166,7 @@ module RPC = struct
Context.get_test_network context >>= fun test_network ->
Lwt.return {
hash ;
net_id = header.shell.net_id ;
net_id = State.Block.net_id block ;
level = header.shell.level ;
proto_level = header.shell.proto_level ;
predecessor = header.shell.predecessor ;
@ -203,17 +204,13 @@ module RPC = struct
let get_validator_per_hash node hash =
State.read_block_exn node.state hash >>= fun block ->
let header = State.Block.header block in
if Net_id.equal
(Net_validator.net_id node.mainnet_validator)
header.shell.net_id then
let net_id = State.Block.net_id block in
if Net_id.equal (Net_validator.net_id node.mainnet_validator) net_id then
Lwt.return (Some node.mainnet_validator)
else
match Net_validator.child node.mainnet_validator with
| Some test_validator ->
if Net_id.equal
(Net_validator.net_id test_validator)
header.shell.net_id then
if Net_id.equal (Net_validator.net_id test_validator) net_id then
Lwt.return_some test_validator
else
Lwt.return_none
@ -253,6 +250,7 @@ module RPC = struct
Chain.head net_state >>= fun head ->
let head_header = State.Block.header head in
let head_hash = State.Block.hash head in
let head_net_id = State.Block.net_id head in
State.Block.context head >>= fun head_context ->
Context.get_protocol head_context >>= fun head_protocol ->
Prevalidator.context pv >>= function
@ -284,7 +282,7 @@ module RPC = struct
operations) ;
operations = Some operations ;
data = MBytes.of_string "" ;
net_id = head_header.shell.net_id ;
net_id = head_net_id ;
test_network ;
}
@ -351,7 +349,6 @@ module RPC = struct
Updater.block_hash = prevalidation_hash ;
block_header = {
shell = {
net_id = head_header.shell.net_id ;
level = Int32.succ head_header.shell.level ;
proto_level ;
predecessor = head_hash ;
@ -495,7 +492,6 @@ module RPC = struct
else
((pred_shell_header.proto_level + 1) mod 256) in
let shell_header : Block_header.shell_header = {
net_id = pred_shell_header.net_id ;
level = Int32.succ pred_shell_header.level ;
proto_level ;
predecessor = State.Block.hash predecessor ;

View File

@ -35,7 +35,7 @@ module RPC : sig
type block_info = Node_rpc_services.Blocks.block_info
val inject_block:
t -> ?force:bool ->
t -> ?force:bool -> ?net_id:Net_id.t ->
MBytes.t -> Operation.t list list ->
(Block_hash.t * unit tzresult Lwt.t) tzresult Lwt.t
(** [inject_block node ?force bytes] tries to insert [bytes]

View File

@ -81,14 +81,14 @@ module Blocks = struct
fitness ; timestamp ; protocol ;
validation_passes ; operations_hash ; data ;
operations ; test_network } ->
((hash, operations, protocol, test_network),
((hash, net_id, operations, protocol, test_network),
{ Block_header.shell =
{ net_id ; level ; proto_level ; predecessor ;
{ level ; proto_level ; predecessor ;
timestamp ; validation_passes ; operations_hash ; fitness } ;
proto = data }))
(fun ((hash, operations, protocol, test_network),
(fun ((hash, net_id, operations, protocol, test_network),
{ Block_header.shell =
{ net_id ; level ; proto_level ; predecessor ;
{ level ; proto_level ; predecessor ;
timestamp ; validation_passes ; operations_hash ; fitness } ;
proto = data }) ->
{ hash ; net_id ; level ; proto_level ; predecessor ;
@ -97,8 +97,9 @@ module Blocks = struct
operations ; test_network })
(dynamic_size
(merge_objs
(obj4
(obj5
(req "hash" Block_hash.encoding)
(req "net_id" Net_id.encoding)
(opt "operations" (dynamic_size (list (dynamic_size (list (dynamic_size operation_encoding))))))
(req "protocol" Protocol_hash.encoding)
(dft "test_network"
@ -602,16 +603,17 @@ type inject_block_param = {
raw: MBytes.t ;
blocking: bool ;
force: bool ;
net_id: Net_id.t option ;
operations: Operation.t list list ;
}
let inject_block_param =
conv
(fun { raw ; blocking ; force ; operations } ->
(raw, blocking, force, operations))
(fun (raw, blocking, force, operations) ->
{ raw ; blocking ; force ; operations })
(obj4
(fun { raw ; blocking ; force ; net_id ; operations } ->
(raw, blocking, force, net_id, operations))
(fun (raw, blocking, force, net_id, operations) ->
{ raw ; blocking ; force ; net_id ; operations })
(obj5
(req "data" bytes)
(dft "blocking"
(describe
@ -627,6 +629,7 @@ let inject_block_param =
the current head. (default: false)"
bool)
false)
(opt "net_id" Net_id.encoding)
(req "operations"
(describe
~description:"..."

View File

@ -177,6 +177,7 @@ type inject_block_param = {
raw: MBytes.t ;
blocking: bool ;
force: bool ;
net_id: Net_id.t option ;
operations: Operation.t list list ;
}

View File

@ -142,9 +142,7 @@ type t = global_state
module Locked_block = struct
let store_genesis store genesis commit =
let net_id = Net_id.of_block_hash genesis.block in
let shell : Block_header.shell_header = {
net_id ;
level = 0l ;
proto_level = 0 ;
predecessor = genesis.block ;
@ -350,8 +348,8 @@ module Block = struct
let hash { hash } = hash
let header { contents = { header } } = header
let net_state { net_state } = net_state
let net_id { net_state = { net_id } } = net_id
let shell_header { contents = { header = { shell } } } = shell
let net_id b = (shell_header b).net_id
let timestamp b = (shell_header b).timestamp
let fitness b = (shell_header b).fitness
let level b = (shell_header b).level

View File

@ -56,14 +56,37 @@ let get v net_id =
try get_exn v net_id >>= fun nv -> return nv
with Not_found -> fail (Inactive_network net_id)
let validate_block v ?force bytes operations =
let validate_block v ?(force = false) ?net_id bytes operations =
let hash = Block_hash.hash_bytes [bytes] in
match Block_header.of_bytes bytes with
| None -> failwith "Cannot parse block header."
| Some block ->
get v block.shell.net_id >>=? fun nv ->
begin
match net_id with
| None -> begin
Distributed_db.read_block_header
v.db block.shell.predecessor >>= function
| None ->
failwith "Unknown predecessor (%a), cannot inject the block."
Block_hash.pp_short block.shell.predecessor
| Some (net_id, _bh) -> get v net_id
end
| Some net_id ->
get v net_id >>=? fun nv ->
if force then
return nv
else
Distributed_db.Block_header.known
(Net_validator.net_db nv)
block.shell.predecessor >>= function
| true ->
return nv
| false ->
failwith "Unknown predecessor (%a), cannot inject the block."
Block_hash.pp_short block.shell.predecessor
end >>=? fun nv ->
let validation =
Net_validator.validate_block nv ?force hash block operations in
Net_validator.validate_block nv ~force hash block operations in
return (hash, validation)
let shutdown { active_nets ; block_validator } =

View File

@ -30,6 +30,7 @@ val get_exn: t -> Net_id.t -> Net_validator.t Lwt.t
val validate_block:
t ->
?force:bool ->
?net_id:Net_id.t ->
MBytes.t -> Operation.t list list ->
(Block_hash.t * State.Block.t tzresult Lwt.t) tzresult Lwt.t

View File

@ -81,14 +81,14 @@ type error +=
| Cant_parse_proto_header
let parse
({ shell = { net_id ; level ; proto_level ; predecessor ;
({ shell = { level ; proto_level ; predecessor ;
timestamp ; fitness ; validation_passes ; operations_hash } ;
proto } : Block_header.t) : block_header tzresult =
match Data_encoding.Binary.of_bytes signed_proto_header_encoding proto with
| None -> Error [Cant_parse_proto_header]
| Some (proto, signature) ->
let shell =
{ Block_header.net_id ; level ; proto_level ; predecessor ;
{ Block_header.level ; proto_level ; predecessor ;
timestamp ; fitness ; validation_passes ; operations_hash } in
Ok { shell ; proto ; signature }

View File

@ -64,9 +64,9 @@ let rpc_services : Updater.rpc_context RPC.directory =
RPC.register
dir
(Forge.block RPC.Path.root)
(fun _ctxt ((net_id, level, proto_level, predecessor,
(fun _ctxt ((_net_id, level, proto_level, predecessor,
timestamp, fitness), command) ->
let shell = { Block_header.net_id ; level ; proto_level ; predecessor ;
let shell = { Block_header.level ; proto_level ; predecessor ;
timestamp ; fitness ; validation_passes = 1 ; operations_hash } in
let bytes = Data.Command.forge shell command in
RPC.Answer.return bytes) in

View File

@ -164,7 +164,6 @@ end
module Block_header = struct
type shell_header = {
net_id: Net_id.t ;
level: Int32.t ;
proto_level: int ; (* uint8 *)
predecessor: Block_hash.t ;
@ -177,16 +176,15 @@ module Block_header = struct
let shell_header_encoding =
let open Data_encoding in
conv
(fun { net_id ; level ; proto_level ; predecessor ;
(fun { level ; proto_level ; predecessor ;
timestamp ; validation_passes ; operations_hash ; fitness } ->
(net_id, level, proto_level, predecessor,
(level, proto_level, predecessor,
timestamp, validation_passes, operations_hash, fitness))
(fun (net_id, level, proto_level, predecessor,
(fun (level, proto_level, predecessor,
timestamp, validation_passes, operations_hash, fitness) ->
{ net_id ; level ; proto_level ; predecessor ;
{ level ; proto_level ; predecessor ;
timestamp ; validation_passes ; operations_hash ; fitness })
(obj8
(req "net_id" Net_id.encoding)
(obj7
(req "level" int32)
(req "proto" uint8)
(req "predecessor" Block_hash.encoding)

View File

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

View File

@ -68,7 +68,6 @@ let block _state ?(operations = []) pred_hash pred name : Block_header.t =
let fitness = incr_fitness pred.Block_header.shell.fitness in
let timestamp = incr_timestamp pred.shell.timestamp in
{ shell = {
net_id = pred.shell.net_id ;
level = Int32.succ pred.shell.level ;
proto_level = pred.shell.proto_level ;
predecessor = pred_hash ;
@ -111,8 +110,7 @@ let block _state ?(operations = []) (pred: State.Block.t) name
let pred_header = State.Block.shell_header pred in
let fitness = incr_fitness pred_header.fitness in
let timestamp = incr_timestamp pred_header.timestamp in
{ shell = { net_id = pred_header.net_id ;
level = Int32.succ pred_header.level ;
{ shell = { level = Int32.succ pred_header.level ;
proto_level = pred_header.proto_level ;
predecessor = State.Block.hash pred ;
validation_passes = 1 ;

View File

@ -82,7 +82,6 @@ let lolblock ?(operations = []) header =
{ timestamp = Time.of_seconds (Random.int64 1500L) ;
level = 0l ; (* dummy *)
proto_level = 0 ; (* dummy *)
net_id ;
validation_passes = Random.int 32 ;
predecessor = genesis_block ; operations_hash ;
fitness = [MBytes.of_string @@ string_of_int @@ String.length header;