From 06a6cf5b9af07bc96b096ae20dd23bf0a3f8939d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Henry?= Date: Sun, 19 Nov 2017 14:38:36 +0100 Subject: [PATCH] Proto: allow to update 'max_number_of_operations' The constant is now defined per block and not per protocol. Also allows to set a limit per validation pass. --- src/environment/v1/updater.mli | 32 +++++++++---- src/node/db/store.ml | 22 +++++++-- src/node/db/store.mli | 2 + src/node/shell/state.ml | 14 +++++- src/node/shell/state.mli | 2 + src/node/updater/updater.ml | 6 +-- src/node/updater/updater.mli | 8 ++-- src/proto/alpha/constants_repr.ml | 80 ++++++++++++++++++------------- src/proto/alpha/main.ml | 6 --- src/proto/alpha/tezos_context.ml | 9 +++- src/proto/alpha/tezos_context.mli | 2 +- src/proto/demo/main.ml | 3 +- src/proto/genesis/main.ml | 12 +++-- test/shell/test_store.ml | 2 + 14 files changed, 133 insertions(+), 67 deletions(-) diff --git a/src/environment/v1/updater.mli b/src/environment/v1/updater.mli index b635401b8..eda45acaa 100644 --- a/src/environment/v1/updater.mli +++ b/src/environment/v1/updater.mli @@ -9,11 +9,33 @@ (** Tezos Protocol Environment - Protocol updater. *) +(** Validation result: the record returned by the protocol + on the successfull validation of a block. *) type validation_result = { + context: Context.t ; + (** The resulting context, it will be used for the next block. *) + fitness: Fitness.t ; + (** The effective fitness of the block (to be compared with + the 'announced' one in the block header. *) + message: string option ; + (** An optional informative message to be used as in the 'git + commit' of the block's context. *) + + max_operation_data_length: int ; + (** The maximum size of operations in bytes. *) + + max_number_of_operations: int list ; + (** The maximum number of operations allowed in one block + (per validation pass). *) + max_operations_ttl: int ; + (** The "time-to-live" of operation for the next block: any + operations whose 'branch' is older than 'ttl' blocks in the + past cannot be included in the next block. *) + } type rpc_context = { @@ -28,17 +50,11 @@ type rpc_context = { access to the standard library and the Environment module. *) module type PROTOCOL = sig - (** The version specific type of operations. *) - type operation - - (** The maximum size of operations in bytes. *) - val max_operation_data_length: int - (** The maximum size of block headers in bytes. *) val max_block_length: int - (** The maximum number of operations allowed in one block. *) - val max_number_of_operations: int + (** The version specific type of operations. *) + type operation (** The parsing / preliminary validation function for operations. Similar to {!parse_block}. *) diff --git a/src/node/db/store.ml b/src/node/db/store.ml index e58d19929..69ccb4718 100644 --- a/src/node/db/store.ml +++ b/src/node/db/store.ml @@ -84,6 +84,8 @@ module Block = struct header: Block_header.t ; message: string ; max_operations_ttl: int ; + max_number_of_operations: int list; + max_operation_data_length: int; context: Context.commit ; } @@ -96,13 +98,23 @@ module Block = struct let encoding = let open Data_encoding in conv - (fun { header ; message ; max_operations_ttl ; context } -> - (message, max_operations_ttl, context, header)) - (fun (message, max_operations_ttl, context, header) -> - { header ; message ; max_operations_ttl ; context }) - (obj4 + (fun { header ; message ; max_operations_ttl ; + max_number_of_operations ; max_operation_data_length ; + context } -> + (message, max_operations_ttl, + max_number_of_operations, max_operation_data_length, + context, header)) + (fun (message, max_operations_ttl, + max_number_of_operations, max_operation_data_length, + context, header) -> + { header ; message ; max_operations_ttl ; + max_number_of_operations ; max_operation_data_length ; + context }) + (obj6 (req "message" string) (req "max_operations_ttl" uint16) + (req "max_number_of_operations" (list uint16)) + (req "max_operation_data_length" uint16) (req "context" Context.commit_encoding) (req "header" Block_header.encoding)) end)) diff --git a/src/node/db/store.mli b/src/node/db/store.mli index 06ea069fb..d71725b1b 100644 --- a/src/node/db/store.mli +++ b/src/node/db/store.mli @@ -89,6 +89,8 @@ module Block : sig header: Block_header.t ; message: string ; max_operations_ttl: int ; + max_number_of_operations: int list; + max_operation_data_length: int; context: Context.commit ; } diff --git a/src/node/shell/state.ml b/src/node/shell/state.ml index 1755cf441..fb9377a50 100644 --- a/src/node/shell/state.ml +++ b/src/node/shell/state.ml @@ -154,7 +154,10 @@ module Locked_block = struct let header : Block_header.t = { shell ; proto = MBytes.create 0 } in Store.Block.Contents.store (store, genesis.block) { Store.Block.header ; message = "Genesis" ; - max_operations_ttl = 0 ; context = commit } >>= fun () -> + max_operations_ttl = 0 ; context = commit ; + max_number_of_operations = []; + max_operation_data_length = 0; + } >>= fun () -> Lwt.return header end @@ -358,6 +361,10 @@ module Block = struct let message { contents = { message } } = message let max_operations_ttl { contents = { max_operations_ttl } } = max_operations_ttl + let max_number_of_operations { contents = { max_number_of_operations } } = + max_number_of_operations + let max_operation_data_length { contents = { max_operation_data_length } } = + max_operation_data_length let is_genesis b = Block_hash.equal b.hash b.net_state.genesis.block @@ -415,7 +422,8 @@ module Block = struct let store net_state block_header operations - { Updater.context ; fitness ; message ; max_operations_ttl } = + { Updater.context ; fitness ; message ; max_operations_ttl ; + max_number_of_operations ; max_operation_data_length } = let bytes = Block_header.to_bytes block_header in let hash = Block_header.hash_raw bytes in (* let's the validator check the consistency... of fitness, level, ... *) @@ -440,6 +448,8 @@ module Block = struct Store.Block.header = block_header ; message ; max_operations_ttl ; + max_number_of_operations ; + max_operation_data_length ; context = commit ; } in Store.Block.Contents.store (store, hash) contents >>= fun () -> diff --git a/src/node/shell/state.mli b/src/node/shell/state.mli index f597da424..094f864a4 100644 --- a/src/node/shell/state.mli +++ b/src/node/shell/state.mli @@ -128,6 +128,8 @@ module Block : sig val level: t -> Int32.t val message: t -> string val max_operations_ttl: t -> int + val max_number_of_operations: t -> int list + val max_operation_data_length: t -> int val is_genesis: t -> bool val predecessor: t -> block option Lwt.t diff --git a/src/node/updater/updater.ml b/src/node/updater/updater.ml index 7071845d6..738074755 100644 --- a/src/node/updater/updater.ml +++ b/src/node/updater/updater.ml @@ -15,6 +15,8 @@ type validation_result = { context: Context.t ; fitness: Fitness.t ; message: string option ; + max_operation_data_length: int ; + max_number_of_operations: int list ; max_operations_ttl: int ; } @@ -149,10 +151,8 @@ end module type RAW_PROTOCOL = sig type error = .. type 'a tzresult = ('a, error list) result - type operation - val max_operation_data_length: int val max_block_length: int - val max_number_of_operations: int + type operation val parse_operation: Operation_hash.t -> Operation.t -> operation tzresult val compare_operations: operation -> operation -> int diff --git a/src/node/updater/updater.mli b/src/node/updater/updater.mli index d1b8e35b6..4faf9747d 100644 --- a/src/node/updater/updater.mli +++ b/src/node/updater/updater.mli @@ -7,7 +7,7 @@ (* *) (**************************************************************************) -(* See `src/environment/v1//updater.mli` for documentation. *) +(* See `src/environment/v1/updater.mli` for documentation. *) val compile: Protocol_hash.t -> Protocol.t -> bool Lwt.t val activate: Context.t -> Protocol_hash.t -> Context.t Lwt.t @@ -21,6 +21,8 @@ type validation_result = { context: Context.t ; fitness: Fitness.t ; message: string option ; + max_operation_data_length: int ; + max_number_of_operations: int list ; max_operations_ttl: int ; } @@ -35,10 +37,8 @@ type rpc_context = { module type RAW_PROTOCOL = sig type error = .. type 'a tzresult = ('a, error list) result - type operation - val max_operation_data_length: int val max_block_length: int - val max_number_of_operations: int + type operation val parse_operation: Operation_hash.t -> Operation.t -> operation tzresult val compare_operations: operation -> operation -> int diff --git a/src/proto/alpha/constants_repr.ml b/src/proto/alpha/constants_repr.ml index 60ce9089f..19d259ba8 100644 --- a/src/proto/alpha/constants_repr.ml +++ b/src/proto/alpha/constants_repr.ml @@ -10,7 +10,6 @@ let version_number = "\000" let max_operation_data_length = 16 * 1024 -let max_number_of_operations = 200 let proof_of_work_nonce_size = 8 let nonce_length = 32 @@ -44,6 +43,7 @@ type constants = { proof_of_work_threshold: int64 ; bootstrap_keys: Ed25519.Public_key.t list ; dictator_pubkey: Ed25519.Public_key.t ; + max_number_of_operations: int list ; } let read_public_key s = @@ -73,7 +73,9 @@ let default = { ] ; dictator_pubkey = read_public_key - "4d5373455738070434f214826d301a1c206780d7f789fcbf94c2149b2e0718cc"; + "4d5373455738070434f214826d301a1c206780d7f789fcbf94c2149b2e0718cc" ; + max_number_of_operations = + [ 300 ] ; } let opt (=) def v = if def = v then None else Some v @@ -83,6 +85,8 @@ let map_option f = function | None -> None | Some x -> Some (f x) +module CompareListInt = Compare.List(Compare.Int) + let constants_encoding = (* let open Data_encoding in *) Data_encoding.conv @@ -120,27 +124,32 @@ let constants_encoding = and dictator_pubkey = opt Ed25519.Public_key.(=) default.dictator_pubkey c.dictator_pubkey + and max_number_of_operations = + opt CompareListInt.(=) + default.max_number_of_operations c.max_number_of_operations in - (( cycle_length, - voting_period_length, - time_before_reward, - slot_durations, - first_free_baking_slot, - max_signing_slot, - instructions_per_transaction, - proof_of_work_threshold, - bootstrap_keys, - dictator_pubkey), ()) ) - (fun (( cycle_length, - voting_period_length, - time_before_reward, - slot_durations, - first_free_baking_slot, - max_signing_slot, - instructions_per_transaction, - proof_of_work_threshold, - bootstrap_keys, - dictator_pubkey), ()) -> + ((( cycle_length, + voting_period_length, + time_before_reward, + slot_durations, + first_free_baking_slot, + max_signing_slot, + instructions_per_transaction, + proof_of_work_threshold, + bootstrap_keys, + dictator_pubkey), + max_number_of_operations), ()) ) + (fun ((( cycle_length, + voting_period_length, + time_before_reward, + slot_durations, + first_free_baking_slot, + max_signing_slot, + instructions_per_transaction, + proof_of_work_threshold, + bootstrap_keys, + dictator_pubkey), + max_number_of_operations), ()) -> { cycle_length = unopt default.cycle_length cycle_length ; voting_period_length = @@ -163,20 +172,25 @@ let constants_encoding = unopt default.bootstrap_keys bootstrap_keys ; dictator_pubkey = unopt default.dictator_pubkey dictator_pubkey ; + max_number_of_operations = + unopt default.max_number_of_operations max_number_of_operations ; } ) Data_encoding.( merge_objs - (obj10 - (opt "cycle_length" int32) - (opt "voting_period_length" int32) - (opt "time_before_reward" int64) - (opt "slot_durations" (list Period_repr.encoding)) - (opt "first_free_baking_slot" uint16) - (opt "max_signing_slot" uint16) - (opt "instructions_per_transaction" int31) - (opt "proof_of_work_threshold" int64) - (opt "bootstrap_keys" (list Ed25519.Public_key.encoding)) - (opt "dictator_pubkey" Ed25519.Public_key.encoding)) + (merge_objs + (obj10 + (opt "cycle_length" int32) + (opt "voting_period_length" int32) + (opt "time_before_reward" int64) + (opt "slot_durations" (list Period_repr.encoding)) + (opt "first_free_baking_slot" uint16) + (opt "max_signing_slot" uint16) + (opt "instructions_per_transaction" int31) + (opt "proof_of_work_threshold" int64) + (opt "bootstrap_keys" (list Ed25519.Public_key.encoding)) + (opt "dictator_pubkey" Ed25519.Public_key.encoding)) + (obj1 + (opt "max_number_of_operations" (list uint16)))) unit) type error += Constant_read of exn diff --git a/src/proto/alpha/main.ml b/src/proto/alpha/main.ml index db1f8164a..ad2f20a30 100644 --- a/src/proto/alpha/main.ml +++ b/src/proto/alpha/main.ml @@ -13,12 +13,6 @@ type operation = Tezos_context.operation let parse_operation = Tezos_context.Operation.parse -let max_operation_data_length = - Tezos_context.Operation.max_operation_data_length - -let max_number_of_operations = - Tezos_context.Constants.max_number_of_operations - let max_block_length = Tezos_context.Block_header.max_header_length diff --git a/src/proto/alpha/tezos_context.ml b/src/proto/alpha/tezos_context.ml index ea563379f..4f61aee89 100644 --- a/src/proto/alpha/tezos_context.ml +++ b/src/proto/alpha/tezos_context.ml @@ -85,6 +85,9 @@ module Constants = struct let dictator_pubkey c = let constants = Raw_context.constants c in constants.dictator_pubkey + let max_number_of_operations c = + let constants = Raw_context.constants c in + constants.max_number_of_operations end module Delegates_pubkey = Public_key_storage @@ -125,7 +128,11 @@ let init = Init_storage.may_initialize let finalize ?commit_message:message c = let fitness = Fitness.from_int64 (Fitness.current c) in let context = Raw_context.recover c in - { Updater.context ; fitness ; message ; max_operations_ttl = 60 } + let constants = Raw_context.constants c in + { Updater.context ; fitness ; message ; max_operations_ttl = 60 ; + max_operation_data_length = 0 ; + max_number_of_operations = constants.max_number_of_operations ; + } let configure_sandbox = Raw_context.configure_sandbox diff --git a/src/proto/alpha/tezos_context.mli b/src/proto/alpha/tezos_context.mli index 15e440179..048d2199d 100644 --- a/src/proto/alpha/tezos_context.mli +++ b/src/proto/alpha/tezos_context.mli @@ -262,7 +262,6 @@ module Constants : sig val proof_of_work_nonce_size: int val baking_reward: Tez.t val endorsement_reward: Tez.t - val max_number_of_operations: int val nonce_length: int val seed_nonce_revelation_tip: Tez.t val origination_burn: Tez.t @@ -279,6 +278,7 @@ module Constants : sig val instructions_per_transaction: context -> int val proof_of_work_threshold: context -> int64 val dictator_pubkey: context -> Ed25519.Public_key.t + val max_number_of_operations: context -> int list end diff --git a/src/proto/demo/main.ml b/src/proto/demo/main.ml index 661285498..2f5ac6355 100644 --- a/src/proto/demo/main.ml +++ b/src/proto/demo/main.ml @@ -88,7 +88,8 @@ let finalize_block ctxt = let message = Some (Format.asprintf "fitness <- %Ld" fitness) in let fitness = Fitness.from_int64 fitness in return { Updater.message ; context = ctxt.context ; fitness ; - max_operations_ttl = 0 } + max_operations_ttl = 0 ; max_operation_data_length = 0 ; + max_number_of_operations = [] } let rpc_services = Services.rpc_services diff --git a/src/proto/genesis/main.ml b/src/proto/genesis/main.ml index 66fd33ff4..f7c2c42a9 100644 --- a/src/proto/genesis/main.ml +++ b/src/proto/genesis/main.ml @@ -94,14 +94,17 @@ let begin_application Some (Format.asprintf "activate %a" Protocol_hash.pp_short hash) in Updater.activate ctxt hash >>= fun ctxt -> return { Updater.message ; context = ctxt ; - fitness ; max_operations_ttl = 0 } + fitness ; max_operations_ttl = 0 ; + max_number_of_operations = [] ; + max_operation_data_length = 0 } | Activate_testnet (hash, delay) -> let message = Some (Format.asprintf "activate testnet %a" Protocol_hash.pp_short hash) in let expiration = Time.add raw_block.shell.timestamp delay in Updater.fork_test_network ctxt hash expiration >>= fun ctxt -> return { Updater.message ; context = ctxt ; fitness ; - max_operations_ttl = 0 } + max_operations_ttl = 0 ; max_operation_data_length = 0 ; + max_number_of_operations = [] } let begin_construction ~predecessor_context:context @@ -114,7 +117,10 @@ let begin_construction () = (* Dummy result. *) return { Updater.message = None ; context ; - fitness ; max_operations_ttl = 0 } + fitness ; max_operations_ttl = 0 ; + max_operation_data_length = 0 ; + max_number_of_operations = [] ; + } let apply_operation _vctxt _ = Lwt.return (Error []) (* absurd *) diff --git a/test/shell/test_store.ml b/test/shell/test_store.ml index 2380369ac..3a20bdb97 100644 --- a/test/shell/test_store.ml +++ b/test/shell/test_store.ml @@ -91,6 +91,8 @@ let lolblock ?(operations = []) header = max_operations_ttl = 0 ; message = "" ; context = Context.dummy_commit ; + max_number_of_operations = [] ; + max_operation_data_length = 0 ; } let b1 = lolblock "Blop !"