From b7deebaf424cd59fa76f5182753b731a7755310d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Henry?= Date: Tue, 14 Nov 2017 02:41:37 +0100 Subject: [PATCH] Shell: Remove `net_id` from the operation header. The `branch` of the operation contains enough information to induce the `net_id`, and the code of the validator/prevalidator is now mature enough to efficiently determine the `net_id` of an incoming operation. --- src/client/client_node_rpcs.ml | 4 +- src/client/client_node_rpcs.mli | 2 +- .../alpha/client_baking_endorsement.ml | 4 +- .../alpha/client_baking_revelation.ml | 6 +- .../embedded/alpha/client_proto_context.ml | 30 +++++----- .../embedded/alpha/client_proto_rpcs.ml | 56 +++++++++---------- .../embedded/alpha/client_proto_rpcs.mli | 14 ----- src/environment/v1/tezos_data.mli | 1 - src/node/shell/block_validator.ml | 21 ------- src/node/shell/block_validator.mli | 2 - src/node/shell/distributed_db.ml | 49 +++++++++++++--- src/node/shell/distributed_db.mli | 7 +++ src/node/shell/distributed_db_functors.ml | 8 +++ src/node/shell/distributed_db_functors.mli | 2 + src/node/shell/node.ml | 12 ++-- src/node/shell/node.mli | 2 +- src/node/shell/node_rpc.ml | 5 +- src/node/shell/node_rpc_services.ml | 3 +- src/node/shell/node_rpc_services.mli | 3 +- src/node/shell/prevalidator.ml | 4 -- src/node/shell/validator.ml | 28 ++++++++++ src/node/shell/validator.mli | 6 ++ src/utils/tezos_data.ml | 11 ++-- src/utils/tezos_data.mli | 1 - test/proto_alpha/proto_alpha_helpers.ml | 5 +- test/shell/test_state.ml | 2 +- test/shell/test_store.ml | 2 +- 27 files changed, 163 insertions(+), 127 deletions(-) diff --git a/src/client/client_node_rpcs.ml b/src/client/client_node_rpcs.ml index 8ba105914..b2eb0ddc9 100644 --- a/src/client/client_node_rpcs.ml +++ b/src/client/client_node_rpcs.ml @@ -22,9 +22,9 @@ let inject_block cctxt ?(async = false) ?(force = false) raw operations = call_err_service0 cctxt Services.inject_block { raw ; blocking = not async ; force ; operations } -let inject_operation cctxt ?(async = false) ?force operation = +let inject_operation cctxt ?(async = false) ?force ?net_id operation = call_err_service0 cctxt Services.inject_operation - (operation, not async, force) + (operation, not async, net_id, force) let inject_protocol cctxt ?(async = false) ?force protocol = call_err_service0 cctxt Services.inject_protocol diff --git a/src/client/client_node_rpcs.mli b/src/client/client_node_rpcs.mli index 30aec584f..e5697680f 100644 --- a/src/client/client_node_rpcs.mli +++ b/src/client/client_node_rpcs.mli @@ -30,7 +30,7 @@ val inject_block: val inject_operation: config -> - ?async:bool -> ?force:bool -> + ?async:bool -> ?force:bool -> ?net_id:Net_id.t -> MBytes.t -> Operation_hash.t tzresult Lwt.t diff --git a/src/client/embedded/alpha/client_baking_endorsement.ml b/src/client/embedded/alpha/client_baking_endorsement.ml index 064217087..62e4bea90 100644 --- a/src/client/embedded/alpha/client_baking_endorsement.ml +++ b/src/client/embedded/alpha/client_baking_endorsement.ml @@ -122,7 +122,6 @@ let inject_endorsement cctxt Client_node_rpcs.Blocks.info cctxt.rpc_config block >>=? fun bi -> Client_proto_rpcs.Helpers.Forge.Delegate.endorsement cctxt.rpc_config block - ~net_id:bi.net_id ~branch:bi.hash ~source ~block:bi.hash @@ -130,7 +129,8 @@ let inject_endorsement cctxt () >>=? fun bytes -> let signed_bytes = Ed25519.Signature.append src_sk bytes in Client_node_rpcs.inject_operation - cctxt.rpc_config ?force ?async signed_bytes >>=? fun oph -> + cctxt.rpc_config ?force ?async ~net_id:bi.net_id + signed_bytes >>=? fun oph -> State.record_endorsement cctxt level bi.hash slot oph >>=? fun () -> return oph diff --git a/src/client/embedded/alpha/client_baking_revelation.ml b/src/client/embedded/alpha/client_baking_revelation.ml index f68996be3..d9010e753 100644 --- a/src/client/embedded/alpha/client_baking_revelation.ml +++ b/src/client/embedded/alpha/client_baking_revelation.ml @@ -17,8 +17,10 @@ let inject_seed_nonce_revelation rpc_config block ?force ?async nonces = let block = Client_rpcs.last_mined_block block in Client_node_rpcs.Blocks.info rpc_config block >>=? fun bi -> Client_proto_rpcs.Helpers.Forge.Anonymous.operations rpc_config - block ~net_id:bi.net_id ~branch:bi.hash operations >>=? fun bytes -> - Client_node_rpcs.inject_operation rpc_config ?force ?async bytes >>=? fun oph -> + block ~branch:bi.hash operations >>=? fun bytes -> + Client_node_rpcs.inject_operation + rpc_config ?force ?async ~net_id:bi.net_id + bytes >>=? fun oph -> return oph let forge_seed_nonce_revelation diff --git a/src/client/embedded/alpha/client_proto_context.ml b/src/client/embedded/alpha/client_proto_context.ml index 625a0ba1b..393177392 100644 --- a/src/client/embedded/alpha/client_proto_context.ml +++ b/src/client/embedded/alpha/client_proto_context.ml @@ -60,7 +60,7 @@ let transfer rpc_config let counter = Int32.succ pcounter in Client_proto_rpcs.Helpers.Forge.Manager.transaction rpc_config block - ~net_id ~branch ~source ~sourcePubKey:src_pk ~counter ~amount + ~branch ~source ~sourcePubKey:src_pk ~counter ~amount ~destination ?parameters ~fee () >>=? fun bytes -> Client_node_rpcs.Blocks.predecessor rpc_config block >>=? fun predecessor -> let signature = Ed25519.sign src_sk bytes in @@ -69,11 +69,11 @@ let transfer rpc_config Client_proto_rpcs.Helpers.apply_operation rpc_config block predecessor oph bytes (Some signature) >>=? fun contracts -> Client_node_rpcs.inject_operation - rpc_config ?force signed_bytes >>=? fun injected_oph -> + rpc_config ?force ~net_id signed_bytes >>=? fun injected_oph -> assert (Operation_hash.equal oph injected_oph) ; return (oph, contracts) -let originate rpc_config ?force ~block ?signature bytes = +let originate rpc_config ?force ?net_id ~block ?signature bytes = let signed_bytes = match signature with | None -> bytes @@ -84,7 +84,7 @@ let originate rpc_config ?force ~block ?signature bytes = predecessor oph bytes signature >>=? function | [ contract ] -> Client_node_rpcs.inject_operation - rpc_config ?force signed_bytes >>=? fun injected_oph -> + rpc_config ?force ?net_id signed_bytes >>=? fun injected_oph -> assert (Operation_hash.equal oph injected_oph) ; return (oph, contract) | contracts -> @@ -101,11 +101,11 @@ let originate_account rpc_config rpc_config block source >>=? fun pcounter -> let counter = Int32.succ pcounter in Client_proto_rpcs.Helpers.Forge.Manager.origination rpc_config block - ~net_id ~branch ~source ~sourcePubKey:src_pk ~managerPubKey:manager_pkh + ~branch ~source ~sourcePubKey:src_pk ~managerPubKey:manager_pkh ~counter ~balance ?spendable ?delegatable ?delegatePubKey:delegate ~fee () >>=? fun bytes -> let signature = Ed25519.sign src_sk bytes in - originate rpc_config ?force ~block ~signature bytes + originate rpc_config ?force ~block ~net_id ~signature bytes let originate_contract rpc_config block ?force ?branch @@ -117,18 +117,18 @@ let originate_contract rpc_config let counter = Int32.succ pcounter in get_branch rpc_config block branch >>=? fun (net_id, branch) -> Client_proto_rpcs.Helpers.Forge.Manager.origination rpc_config block - ~net_id ~branch ~source ~sourcePubKey:src_pk ~managerPubKey:manager_pkh + ~branch ~source ~sourcePubKey:src_pk ~managerPubKey:manager_pkh ~counter ~balance ~spendable:spendable ?delegatable ?delegatePubKey ~script:{ code ; storage } ~fee () >>=? fun bytes -> let signature = Ed25519.sign src_sk bytes in - originate rpc_config ?force ~block ~signature bytes + originate rpc_config ?force ~net_id ~block ~signature bytes let faucet rpc_config block ?force ?branch ~manager_pkh () = get_branch rpc_config block branch >>=? fun (net_id, branch) -> Client_proto_rpcs.Helpers.Forge.Anonymous.faucet - rpc_config block ~net_id ~branch ~id:manager_pkh () >>=? fun bytes -> - originate rpc_config ?force ~block bytes + rpc_config block ~branch ~id:manager_pkh () >>=? fun bytes -> + originate rpc_config ?force ~net_id ~block bytes let delegate_contract rpc_config block ?force ?branch @@ -139,13 +139,13 @@ let delegate_contract rpc_config rpc_config block source >>=? fun pcounter -> let counter = Int32.succ pcounter in Client_proto_rpcs.Helpers.Forge.Manager.delegation rpc_config block - ~net_id ~branch ~source ?sourcePubKey:src_pk ~counter ~fee delegate_opt + ~branch ~source ?sourcePubKey:src_pk ~counter ~fee delegate_opt >>=? fun bytes -> let signature = Environment.Ed25519.sign manager_sk bytes in let signed_bytes = MBytes.concat bytes signature in let oph = Operation_hash.hash_bytes [ signed_bytes ] in Client_node_rpcs.inject_operation - rpc_config ?force signed_bytes >>=? fun injected_oph -> + rpc_config ?force ~net_id signed_bytes >>=? fun injected_oph -> assert (Operation_hash.equal oph injected_oph) ; return oph @@ -218,17 +218,17 @@ let group = { Cli_entries.name = "context" ; title = "Block contextual commands (see option -block)" } -let dictate rpc_config block command seckey = +let dictate rpc_config ?force block command seckey = let block = Client_rpcs.last_mined_block block in Client_node_rpcs.Blocks.info rpc_config block >>=? fun { net_id ; hash = branch } -> Client_proto_rpcs.Helpers.Forge.Dictator.operation - rpc_config block ~net_id ~branch command >>=? fun bytes -> + rpc_config block ~branch command >>=? fun bytes -> let signature = Ed25519.sign seckey bytes in let signed_bytes = MBytes.concat bytes signature in let oph = Operation_hash.hash_bytes [ signed_bytes ] in Client_node_rpcs.inject_operation - rpc_config signed_bytes >>=? fun injected_oph -> + rpc_config ?force ~net_id signed_bytes >>=? fun injected_oph -> assert (Operation_hash.equal oph injected_oph) ; return oph diff --git a/src/client/embedded/alpha/client_proto_rpcs.ml b/src/client/embedded/alpha/client_proto_rpcs.ml index e2e626a32..fc0a6a79d 100644 --- a/src/client/embedded/alpha/client_proto_rpcs.ml +++ b/src/client/embedded/alpha/client_proto_rpcs.ml @@ -187,25 +187,25 @@ module Helpers = struct module Manager = struct let operations cctxt - block ~net_id ~branch ~source ?sourcePubKey ~counter ~fee operations = + block ~branch ~source ?sourcePubKey ~counter ~fee operations = let ops = Manager_operations { source ; public_key = sourcePubKey ; counter ; operations ; fee } in (call_error_service1 cctxt Services.Helpers.Forge.operations block - ({net_id ; branch }, Sourced_operations ops)) + ({ branch }, Sourced_operations ops)) let transaction cctxt - block ~net_id ~branch ~source ?sourcePubKey ~counter + block ~branch ~source ?sourcePubKey ~counter ~amount ~destination ?parameters ~fee ()= - operations cctxt block ~net_id ~branch ~source ?sourcePubKey ~counter ~fee + operations cctxt block ~branch ~source ?sourcePubKey ~counter ~fee Tezos_context.[Transaction { amount ; parameters ; destination }] let origination cctxt - block ~net_id ~branch + block ~branch ~source ?sourcePubKey ~counter ~managerPubKey ~balance ?(spendable = true) ?(delegatable = true) ?delegatePubKey ?script ~fee () = - operations cctxt block ~net_id ~branch ~source ?sourcePubKey ~counter ~fee + operations cctxt block ~branch ~source ?sourcePubKey ~counter ~fee Tezos_context.[ Origination { manager = managerPubKey ; delegate = delegatePubKey ; @@ -215,53 +215,53 @@ module Helpers = struct credit = balance } ] let delegation cctxt - block ~net_id ~branch ~source ?sourcePubKey ~counter ~fee delegate = - operations cctxt block ~net_id ~branch ~source ?sourcePubKey ~counter ~fee + block ~branch ~source ?sourcePubKey ~counter ~fee delegate = + operations cctxt block ~branch ~source ?sourcePubKey ~counter ~fee Tezos_context.[Delegation delegate] end module Delegate = struct let operations cctxt - block ~net_id ~branch ~source operations = + block ~branch ~source operations = let ops = Delegate_operations { source ; operations } in (call_error_service1 cctxt Services.Helpers.Forge.operations block - ({net_id ; branch}, Sourced_operations ops)) + ({ branch }, Sourced_operations ops)) let endorsement cctxt - b ~net_id ~branch ~source ~block ~slot () = - operations cctxt b ~net_id ~branch ~source + b ~branch ~source ~block ~slot () = + operations cctxt b ~branch ~source Tezos_context.[Endorsement { block ; slot }] let proposals cctxt - b ~net_id ~branch ~source ~period ~proposals () = - operations cctxt b ~net_id ~branch ~source + b ~branch ~source ~period ~proposals () = + operations cctxt b ~branch ~source Tezos_context.[Proposals { period ; proposals }] let ballot cctxt - b ~net_id ~branch ~source ~period ~proposal ~ballot () = - operations cctxt b ~net_id ~branch ~source + b ~branch ~source ~period ~proposal ~ballot () = + operations cctxt b ~branch ~source Tezos_context.[Ballot { period ; proposal ; ballot }] end module Dictator = struct let operation cctxt - block ~net_id ~branch operation = + block ~branch operation = let op = Dictator_operation operation in (call_error_service1 cctxt Services.Helpers.Forge.operations block - ({net_id ; branch}, Sourced_operations op)) + ({ branch }, Sourced_operations op)) let activate cctxt - b ~net_id ~branch hash = - operation cctxt b ~net_id ~branch (Activate hash) + b ~branch hash = + operation cctxt b ~branch (Activate hash) let activate_testnet cctxt - b ~net_id ~branch hash = - operation cctxt b ~net_id ~branch (Activate_testnet hash) + b ~branch hash = + operation cctxt b ~branch (Activate_testnet hash) end module Anonymous = struct - let operations cctxt block ~net_id ~branch operations = + let operations cctxt block ~branch operations = (call_error_service1 cctxt Services.Helpers.Forge.operations block - ({net_id ; branch}, Anonymous_operations operations)) + ({ branch }, Anonymous_operations operations)) let seed_nonce_revelation cctxt - block ~net_id ~branch ~level ~nonce () = - operations cctxt block ~net_id ~branch [Seed_nonce_revelation { level ; nonce }] + block ~branch ~level ~nonce () = + operations cctxt block ~branch [Seed_nonce_revelation { level ; nonce }] let faucet cctxt - block ~net_id ~branch ~id () = + block ~branch ~id () = let nonce = Sodium.Random.Bigbytes.generate 16 in - operations cctxt block ~net_id ~branch [Faucet { id ; nonce }] + operations cctxt block ~branch [Faucet { id ; nonce }] end let empty_proof_of_work_nonce = MBytes.of_string diff --git a/src/client/embedded/alpha/client_proto_rpcs.mli b/src/client/embedded/alpha/client_proto_rpcs.mli index 767bada1e..31697df9f 100644 --- a/src/client/embedded/alpha/client_proto_rpcs.mli +++ b/src/client/embedded/alpha/client_proto_rpcs.mli @@ -201,7 +201,6 @@ module Helpers : sig val operations: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> source:Contract.t -> ?sourcePubKey:public_key -> @@ -212,7 +211,6 @@ module Helpers : sig val transaction: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> source:Contract.t -> ?sourcePubKey:public_key -> @@ -225,7 +223,6 @@ module Helpers : sig val origination: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> source:Contract.t -> ?sourcePubKey:public_key -> @@ -242,7 +239,6 @@ module Helpers : sig val delegation: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> source:Contract.t -> ?sourcePubKey:public_key -> @@ -255,21 +251,18 @@ module Helpers : sig val operation: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> dictator_operation -> MBytes.t tzresult Lwt.t val activate: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> Protocol_hash.t -> MBytes.t tzresult Lwt.t val activate_testnet: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> Protocol_hash.t -> MBytes.t tzresult Lwt.t @@ -278,7 +271,6 @@ module Helpers : sig val operations: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> source:public_key -> delegate_operation list -> @@ -286,7 +278,6 @@ module Helpers : sig val endorsement: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> source:public_key -> block:Block_hash.t -> @@ -295,7 +286,6 @@ module Helpers : sig val proposals: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> source:public_key -> period:Voting_period.t -> @@ -304,7 +294,6 @@ module Helpers : sig val ballot: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> source:public_key -> period:Voting_period.t -> @@ -316,14 +305,12 @@ module Helpers : sig val operations: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> anonymous_operation list -> MBytes.t tzresult Lwt.t val seed_nonce_revelation: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> level:Raw_level.t -> nonce:Nonce.t -> @@ -331,7 +318,6 @@ module Helpers : sig val faucet: Client_rpcs.config -> block -> - net_id:Net_id.t -> branch:Block_hash.t -> id:public_key_hash -> unit -> MBytes.t tzresult Lwt.t diff --git a/src/environment/v1/tezos_data.mli b/src/environment/v1/tezos_data.mli index 0f535dc42..fc51a3a94 100644 --- a/src/environment/v1/tezos_data.mli +++ b/src/environment/v1/tezos_data.mli @@ -55,7 +55,6 @@ module Fitness : DATA with type t = MBytes.t list module Operation : sig type shell_header = { - net_id: Net_id.t ; branch: Block_hash.t ; (** The operation is only valid in a branch containing the block [branch]. *) diff --git a/src/node/shell/block_validator.ml b/src/node/shell/block_validator.ml index a43a7fb3e..4dc69ae48 100644 --- a/src/node/shell/block_validator.ml +++ b/src/node/shell/block_validator.ml @@ -36,8 +36,6 @@ type t = { type block_error = | Cannot_parse_operation of Operation_hash.t | Invalid_fitness of { expected: Fitness.t ; found: Fitness.t } - | Inconsistent_netid of { operation: Operation_hash.t ; - expected: Net_id.t ; found: Net_id.t } | Non_increasing_timestamp | Non_increasing_fitness | Invalid_level of { expected: Int32.t ; found: Int32.t } @@ -147,15 +145,6 @@ let pp_block_error ppf = function \ found %a@]" Fitness.pp expected Fitness.pp found - | Inconsistent_netid { operation ; expected ; found } -> - Format.fprintf ppf - "@[The network identifier of the operation %a is not \ - \ constitent with the network identifier of the block: @ \ - \ expected: %a@ \ - \ found: %a@]" - Operation_hash.pp_short operation - Net_id.pp expected - Net_id.pp found | Non_increasing_timestamp -> Format.fprintf ppf "Non increasing timestamp" | Non_increasing_fitness -> @@ -334,16 +323,6 @@ let apply_block check_header pred_header hash header >>=? fun () -> let operation_hashes = List.map (List.map Operation.hash) operations in check_liveness net_state pred hash operation_hashes operations >>=? fun () -> - iter_p (iter_p (fun op -> - let op_hash = Operation.hash op in - fail_unless - (Net_id.equal op.shell.net_id header.shell.net_id) - (invalid_block hash @@ Inconsistent_netid { - operation = op_hash ; - expected = header.shell.net_id ; - found = op.shell.net_id ; - }))) - operations >>=? fun () -> map2_s (map2_s begin fun op_hash raw -> Lwt.return (Proto.parse_operation op_hash raw) |> trace (invalid_block hash (Cannot_parse_operation op_hash)) diff --git a/src/node/shell/block_validator.mli b/src/node/shell/block_validator.mli index 1d4e526ed..5a1ba16d9 100644 --- a/src/node/shell/block_validator.mli +++ b/src/node/shell/block_validator.mli @@ -12,8 +12,6 @@ type t type block_error = | Cannot_parse_operation of Operation_hash.t | Invalid_fitness of { expected: Fitness.t ; found: Fitness.t } - | Inconsistent_netid of { operation: Operation_hash.t ; - expected: Net_id.t ; found: Net_id.t } | Non_increasing_timestamp | Non_increasing_fitness | Invalid_level of { expected: Int32.t ; found: Int32.t } diff --git a/src/node/shell/distributed_db.ml b/src/node/shell/distributed_db.ml index 26f6e71c7..8382d45a7 100644 --- a/src/node/shell/distributed_db.ml +++ b/src/node/shell/distributed_db.ml @@ -340,6 +340,18 @@ let state { disk } = disk let net_state { net_state } = net_state let db { global_db } = global_db +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 + Some net_db + else None) + active_nets + None + module P2p_reader = struct let may_activate global_db state net_id f = @@ -473,12 +485,17 @@ module P2p_reader = struct P2p.try_send global_db.p2p state.conn (Operation p)) hashes - | Operation operation -> - may_handle state operation.shell.net_id @@ fun net_db -> + | Operation operation -> begin let hash = Operation.hash operation in - Raw_operation.Table.notify - net_db.operation_db.table state.gid hash operation >>= fun () -> - Lwt.return_unit + match find_pending_operation state.peer_active_nets hash with + | None -> + (* TODO some penalty. *) + Lwt.return_unit + | Some net_db -> + Raw_operation.Table.notify + net_db.operation_db.table state.gid hash operation >>= fun () -> + Lwt.return_unit + end | Get_protocols hashes -> Lwt_list.iter_p @@ -727,9 +744,7 @@ let inject_block_header net_db h b = return res let inject_operation net_db h op = - fail_unless - (Net_id.equal op.Operation.shell.net_id (State.Net.id net_db.net_state)) - (failure "Inconsitent net_id in operation") >>=? fun () -> + assert (Operation_hash.equal h (Operation.hash op)) ; Raw_operation.Table.inject net_db.operation_db.table h op >>= fun res -> return res @@ -809,6 +824,22 @@ module Block_header = struct and type param := unit) end +let read_block_header { disk ; active_nets } h = + State.read_block disk h >>= function + | Some b -> + Lwt.return_some (State.Block.net_id b, State.Block.header b) + | None -> + Net_id.Table.fold + (fun net_id net_db acc -> + acc >>= function + | Some _ -> acc + | None -> + Block_header.read_opt net_db h >>= function + | None -> Lwt.return_none + | Some bh -> Lwt.return_some (net_id, bh)) + active_nets + Lwt.return_none + module Operation_hashes = Make (Raw_operation_hashes.Table) (struct type t = net_db @@ -822,7 +853,7 @@ module Operations = end) module Operation = struct - type t = Operation.t + include Operation include (Make (Raw_operation.Table) (struct type t = net_db let proj net = net.operation_db.table diff --git a/src/node/shell/distributed_db.mli b/src/node/shell/distributed_db.mli index 6e5c8e195..0bf1d35c3 100644 --- a/src/node/shell/distributed_db.mli +++ b/src/node/shell/distributed_db.mli @@ -32,6 +32,9 @@ type net_db for new head or new operations. *) val activate: t -> State.Net.t -> net_db +(** Look for the database of an active network. *) +val get_net: t -> Net_id.t -> net_db option + (** Deactivate a given network. The node will notify its neighbours that it does not care anymore about this network. *) val deactivate: net_db -> unit Lwt.t @@ -178,6 +181,10 @@ module Block_header : sig and type param := unit end +(** Lookup for block header in any active networks *) +val read_block_header: + db -> Block_hash.t -> (Net_id.t * Block_header.t) option Lwt.t + (** Index of all the operations of a given block (per validation pass). *) module Operations : DISTRIBUTED_DB with type t := net_db diff --git a/src/node/shell/distributed_db_functors.ml b/src/node/shell/distributed_db_functors.ml index 15b1e42ad..e10bf00a2 100644 --- a/src/node/shell/distributed_db_functors.ml +++ b/src/node/shell/distributed_db_functors.ml @@ -42,6 +42,8 @@ module type DISTRIBUTED_DB = sig val inject: t -> key -> value -> bool Lwt.t val watch: t -> (key * value) Lwt_stream.t * Watcher.stopper + val pending: t -> key -> bool + end module type DISK_TABLE = sig @@ -294,6 +296,12 @@ end = struct let input = Watcher.create_input () in { scheduler ; disk ; memory ; input ; global_input } + let pending s k = + match Memory_table.find s.memory k with + | exception Not_found -> false + | Found _ -> false + | Pending _ -> true + end module type REQUEST = sig diff --git a/src/node/shell/distributed_db_functors.mli b/src/node/shell/distributed_db_functors.mli index 43b4354ec..612d3e030 100644 --- a/src/node/shell/distributed_db_functors.mli +++ b/src/node/shell/distributed_db_functors.mli @@ -43,6 +43,8 @@ module type DISTRIBUTED_DB = sig val inject: t -> key -> value -> bool Lwt.t val watch: t -> (key * value) Lwt_stream.t * Watcher.stopper + val pending: t -> key -> bool + end module type DISK_TABLE = sig diff --git a/src/node/shell/node.ml b/src/node/shell/node.ml index fecbeef87..e2181be5e 100644 --- a/src/node/shell/node.ml +++ b/src/node/shell/node.ml @@ -10,15 +10,13 @@ open Lwt.Infix open Logging.Node.Worker -let inject_operation validator ?force bytes = +let inject_operation validator ?force ?net_id bytes = let t = match Data_encoding.Binary.of_bytes Operation.encoding bytes with | None -> failwith "Can't parse the operation" - | Some operation -> - Validator.get - validator operation.shell.net_id >>=? fun net_validator -> - let pv = Net_validator.prevalidator net_validator in - Prevalidator.inject_operation pv ?force operation in + | Some op -> + Validator.inject_operation validator ?force ?net_id op + in let hash = Operation_hash.hash_bytes [bytes] in Lwt.return (hash, t) @@ -57,7 +55,7 @@ type t = { MBytes.t -> Operation.t list list -> (Block_hash.t * unit tzresult Lwt.t) tzresult Lwt.t ; inject_operation: - ?force:bool -> MBytes.t -> + ?force:bool -> ?net_id:Net_id.t -> MBytes.t -> (Operation_hash.t * unit tzresult Lwt.t) Lwt.t ; inject_protocol: ?force:bool -> Protocol.t -> diff --git a/src/node/shell/node.mli b/src/node/shell/node.mli index 757c4cb00..56cf8f744 100644 --- a/src/node/shell/node.mli +++ b/src/node/shell/node.mli @@ -44,7 +44,7 @@ module RPC : sig non strictly increasing fitness. *) val inject_operation: - t -> ?force:bool -> MBytes.t -> + t -> ?force:bool -> ?net_id:Net_id.t -> MBytes.t -> (Operation_hash.t * unit tzresult Lwt.t) Lwt.t val inject_protocol: t -> ?force:bool -> Protocol.t -> diff --git a/src/node/shell/node_rpc.ml b/src/node/shell/node_rpc.ml index 82af36aec..91c4281ce 100644 --- a/src/node/shell/node_rpc.ml +++ b/src/node/shell/node_rpc.ml @@ -402,8 +402,9 @@ let build_rpc_directory node = end >>= RPC.Answer.return in RPC.register0 dir Services.inject_block implementation in let dir = - let implementation (contents, blocking, force) = - Node.RPC.inject_operation node ?force contents >>= fun (hash, wait) -> + let implementation (contents, blocking, net_id, force) = + Node.RPC.inject_operation + node ?force ?net_id contents >>= fun (hash, wait) -> begin (if blocking then wait else return ()) >>=? fun () -> return hash end >>= RPC.Answer.return in diff --git a/src/node/shell/node_rpc_services.ml b/src/node/shell/node_rpc_services.ml index 36cab8992..b3605eb77 100644 --- a/src/node/shell/node_rpc_services.ml +++ b/src/node/shell/node_rpc_services.ml @@ -658,7 +658,7 @@ let inject_operation = RPCs ubder /blocks/prevalidation for more details on the \ prevalidation context." ~input: - (obj3 + (obj4 (req "signedOperationContents" (describe ~title: "Tezos signed operation (hex encoded)" bytes)) @@ -669,6 +669,7 @@ let inject_operation = (pre-)validated before answering. (default: true)" bool) true) + (opt "net_id" Net_id.encoding) (opt "force" (describe ~description: diff --git a/src/node/shell/node_rpc_services.mli b/src/node/shell/node_rpc_services.mli index 5fb7019e7..68534031c 100644 --- a/src/node/shell/node_rpc_services.mli +++ b/src/node/shell/node_rpc_services.mli @@ -185,7 +185,8 @@ val inject_block: val inject_operation: (unit, unit, - (MBytes.t * bool * bool option), Operation_hash.t tzresult) RPC.service + (MBytes.t * bool * Net_id.t option * bool option), + Operation_hash.t tzresult) RPC.service val inject_protocol: (unit, unit, diff --git a/src/node/shell/prevalidator.ml b/src/node/shell/prevalidator.ml index 5b44f7754..ccb701dca 100644 --- a/src/node/shell/prevalidator.ml +++ b/src/node/shell/prevalidator.ml @@ -420,7 +420,6 @@ let context pv = pv.context () let shutdown pv = pv.shutdown () let inject_operation pv ?(force = false) (op: Operation.t) = - let net_id = State.Net.id (Distributed_db.net_state pv.net_db) in let wrap_error h map = begin try return (snd (Operation_hash.Map.find h map)) @@ -428,9 +427,6 @@ let inject_operation pv ?(force = false) (op: Operation.t) = failwith "unexpected protocol result" end >>=? fun errors -> Lwt.return (Error errors) in - fail_unless (Net_id.equal net_id op.shell.net_id) - (failure - "Prevalidator.inject_operation: invalid network") >>=? fun () -> pv.prevalidate_operations force [op] >>=? function | ([h], { applied = [h', _] }) when Operation_hash.equal h h' -> return () diff --git a/src/node/shell/validator.ml b/src/node/shell/validator.ml index 82c74e0c2..3b5871e9f 100644 --- a/src/node/shell/validator.ml +++ b/src/node/shell/validator.ml @@ -77,3 +77,31 @@ let shutdown { active_nets ; block_validator } = let watcher { valid_block_input } = Watcher.create_stream valid_block_input + +let inject_operation v ?(force = false) ?net_id op = + begin + match net_id with + | None -> begin + Distributed_db.read_block_header + v.db op.Operation.shell.branch >>= function + | None -> + failwith "Unknown branch (%a), cannot inject the operation." + Block_hash.pp_short op.shell.branch + | 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) + op.shell.branch >>= function + | true -> + return nv + | false -> + failwith "Unknown branch (%a), cannot inject the operation." + Block_hash.pp_short op.shell.branch + end >>=? fun nv -> + let pv = Net_validator.prevalidator nv in + Prevalidator.inject_operation pv ~force op diff --git a/src/node/shell/validator.mli b/src/node/shell/validator.mli index 41a8de826..c22484830 100644 --- a/src/node/shell/validator.mli +++ b/src/node/shell/validator.mli @@ -35,3 +35,9 @@ val validate_block: (** Monitor all the valid block (for all activate networks). *) val watcher: t -> State.Block.t Lwt_stream.t * Watcher.stopper + +val inject_operation: + t -> + ?force:bool -> + ?net_id:Net_id.t -> + Operation.t -> unit tzresult Lwt.t diff --git a/src/utils/tezos_data.ml b/src/utils/tezos_data.ml index 4c50395e8..0de45afe8 100644 --- a/src/utils/tezos_data.ml +++ b/src/utils/tezos_data.ml @@ -110,18 +110,15 @@ end module Operation = struct type shell_header = { - net_id: Net_id.t ; branch: Block_hash.t ; } let shell_header_encoding = let open Data_encoding in conv - (fun { net_id ; branch } -> net_id, branch) - (fun (net_id, branch) -> { net_id ; branch }) - (obj2 - (req "net_id" Net_id.encoding) - (req "branch" Block_hash.encoding)) + (fun { branch } -> branch) + (fun branch -> { branch }) + (obj1 (req "branch" Block_hash.encoding)) type t = { shell: shell_header ; @@ -142,7 +139,7 @@ module Operation = struct let compare o1 o2 = let (>>) x y = if x = 0 then y () else x in - Net_id.compare o1.shell.net_id o1.shell.net_id >> fun () -> + Block_hash.compare o1.shell.branch o1.shell.branch >> fun () -> MBytes.compare o1.proto o2.proto let equal b1 b2 = compare b1 b2 = 0 diff --git a/src/utils/tezos_data.mli b/src/utils/tezos_data.mli index 1c0e083c1..bf987f9b7 100644 --- a/src/utils/tezos_data.mli +++ b/src/utils/tezos_data.mli @@ -48,7 +48,6 @@ end module Operation : sig type shell_header = { - net_id: Net_id.t ; branch: Block_hash.t ; } val shell_header_encoding: shell_header Data_encoding.t diff --git a/test/proto_alpha/proto_alpha_helpers.ml b/test/proto_alpha/proto_alpha_helpers.ml index ca1ed7fde..0bda22cb2 100644 --- a/test/proto_alpha/proto_alpha_helpers.ml +++ b/test/proto_alpha/proto_alpha_helpers.ml @@ -260,7 +260,6 @@ module Protocol = struct Client_node_rpcs.Blocks.info !rpc_config block >>=? fun block_info -> Client_proto_rpcs.Context.next_level !rpc_config block >>=? fun next_level -> Client_proto_rpcs.Helpers.Forge.Delegate.proposals !rpc_config block - ~net_id:block_info.net_id ~branch:block_info.hash ~source:pk ~period:next_level.voting_period @@ -273,7 +272,6 @@ module Protocol = struct Client_node_rpcs.Blocks.info !rpc_config block >>=? fun block_info -> Client_proto_rpcs.Context.next_level !rpc_config block >>=? fun next_level -> Client_proto_rpcs.Helpers.Forge.Delegate.ballot !rpc_config block - ~net_id:block_info.net_id ~branch:block_info.hash ~source:pk ~period:next_level.voting_period @@ -458,10 +456,9 @@ module Endorse = struct source slot = let block = Client_rpcs.last_mined_block block in - Client_node_rpcs.Blocks.info !rpc_config block >>=? fun { hash ; net_id } -> + Client_node_rpcs.Blocks.info !rpc_config block >>=? fun { hash } -> Client_proto_rpcs.Helpers.Forge.Delegate.endorsement !rpc_config block - ~net_id:net_id ~branch:hash ~source ~block:hash diff --git a/test/shell/test_state.ml b/test/shell/test_state.ml index ec2c9dc29..dcb6f6d77 100644 --- a/test/shell/test_state.ml +++ b/test/shell/test_state.ml @@ -54,7 +54,7 @@ let incr_timestamp timestamp = let operation op = let op : Operation.t = { - shell = { net_id ; branch = genesis_block } ; + shell = { branch = genesis_block } ; proto = MBytes.of_string op ; } in Operation.hash op, diff --git a/test/shell/test_store.ml b/test/shell/test_store.ml index 3818af1ea..802d91523 100644 --- a/test/shell/test_store.ml +++ b/test/shell/test_store.ml @@ -63,7 +63,7 @@ let net_id = Net_id.of_block_hash genesis_block (** Operation store *) let make proto : Tezos_data.Operation.t = - { shell = { net_id ; branch = genesis_block } ; proto } + { shell = { branch = genesis_block } ; proto } let op1 = make (MBytes.of_string "Capadoce") let oph1 = Tezos_data.Operation.hash op1