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.
This commit is contained in:
parent
13dd470d06
commit
06a6cf5b9a
@ -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}. *)
|
||||
|
@ -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))
|
||||
|
@ -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 ;
|
||||
}
|
||||
|
||||
|
@ -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 () ->
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 *)
|
||||
|
@ -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 !"
|
||||
|
Loading…
Reference in New Issue
Block a user