P2P: allow to limit the size of operations and operations list
This commit is contained in:
parent
8072d413fc
commit
99f6e40471
@ -40,6 +40,34 @@ let encoding =
|
||||
shell_header_encoding
|
||||
(obj1 (req "data" Variable.bytes)))
|
||||
|
||||
let bounded_encoding ?max_size () =
|
||||
match max_size with
|
||||
| None -> encoding
|
||||
| Some max_size -> Data_encoding.check_size max_size encoding
|
||||
|
||||
let bounded_list_encoding
|
||||
?max_length ?max_size ?max_operation_size ?max_pass () =
|
||||
let open Data_encoding in
|
||||
let op_encoding = bounded_encoding ?max_size:max_operation_size () in
|
||||
let op_list_encoding =
|
||||
match max_size with
|
||||
| None ->
|
||||
Variable.list ?max_length (dynamic_size op_encoding)
|
||||
| Some max_size ->
|
||||
check_size max_size
|
||||
(Variable.list ?max_length (dynamic_size op_encoding)) in
|
||||
obj2
|
||||
(req "operation_hashes_path"
|
||||
(Operation_list_list_hash.bounded_path_encoding ?max_length:max_pass ()))
|
||||
(req "operations" op_list_encoding)
|
||||
|
||||
let bounded_hash_list_encoding ?max_length ?max_pass () =
|
||||
let open Data_encoding in
|
||||
obj2
|
||||
(req "operation_hashes_path"
|
||||
(Operation_list_list_hash.bounded_path_encoding ?max_length:max_pass ()))
|
||||
(req "operation_hashes" (Variable.list ?max_length Operation_hash.encoding))
|
||||
|
||||
let pp fmt op =
|
||||
Data_encoding.Json.pp fmt
|
||||
(Data_encoding.Json.construct encoding op)
|
||||
|
@ -20,3 +20,16 @@ type t = {
|
||||
include S.HASHABLE with type t := t
|
||||
and type hash := Operation_hash.t
|
||||
val of_bytes_exn: MBytes.t -> t
|
||||
|
||||
val bounded_encoding: ?max_size:int -> unit -> t Data_encoding.t
|
||||
val bounded_list_encoding:
|
||||
?max_length:int ->
|
||||
?max_size:int ->
|
||||
?max_operation_size:int ->
|
||||
?max_pass:int ->
|
||||
unit -> (Operation_list_list_hash.path * t list) Data_encoding.t
|
||||
val bounded_hash_list_encoding:
|
||||
?max_length:int ->
|
||||
?max_pass:int ->
|
||||
unit -> (Operation_list_list_hash.path * Operation_hash.t list) Data_encoding.t
|
||||
|
||||
|
@ -274,6 +274,8 @@ module Generic_Merkle_tree (H : sig
|
||||
|
||||
end
|
||||
|
||||
let rec log2 x = if x <= 1 then 0 else 1 + log2 ((x+1) / 2)
|
||||
|
||||
module Make_merkle_tree
|
||||
(R : sig
|
||||
val register_encoding:
|
||||
@ -331,6 +333,13 @@ module Make_merkle_tree
|
||||
(fun () -> Op)
|
||||
])
|
||||
|
||||
let bounded_path_encoding ?max_length () =
|
||||
match max_length with
|
||||
| None -> path_encoding
|
||||
| Some max_length ->
|
||||
let max_depth = log2 max_length in
|
||||
Data_encoding.check_size (max_depth * (size + 1) + 1) path_encoding
|
||||
|
||||
end
|
||||
|
||||
include
|
||||
|
@ -146,6 +146,7 @@ module type MERKLE_TREE = sig
|
||||
| Op
|
||||
|
||||
val path_encoding: path Data_encoding.t
|
||||
val bounded_path_encoding: ?max_length:int -> unit -> path Data_encoding.t
|
||||
|
||||
val compute_path: elt list -> int -> path
|
||||
val check_path: path -> elt -> t * int
|
||||
|
@ -27,6 +27,62 @@ module Bounded_encoding = struct
|
||||
let block_header = delayed (fun () -> !block_header_cache)
|
||||
let block_locator = delayed (fun () -> !block_locator_cache)
|
||||
|
||||
let operation_max_size = ref None
|
||||
let operation_list_max_size = ref None
|
||||
let operation_list_max_length = ref None
|
||||
let operation_max_pass = ref None
|
||||
|
||||
let operation_cache =
|
||||
ref (Operation.bounded_encoding ?max_size:!operation_max_size ())
|
||||
let operation_list_cache =
|
||||
ref (Operation.bounded_list_encoding
|
||||
?max_length:!operation_list_max_length
|
||||
?max_size:!operation_list_max_size
|
||||
?max_operation_size:!operation_max_size
|
||||
?max_pass:!operation_max_pass ())
|
||||
let operation_hash_list_cache =
|
||||
ref (Operation.bounded_hash_list_encoding
|
||||
?max_length:!operation_list_max_length
|
||||
?max_pass:!operation_max_pass ())
|
||||
|
||||
let update_operation_list_encoding () =
|
||||
operation_list_cache :=
|
||||
Operation.bounded_list_encoding
|
||||
?max_length:!operation_list_max_length
|
||||
?max_size:!operation_list_max_size
|
||||
?max_operation_size:!operation_max_size
|
||||
?max_pass:!operation_max_pass
|
||||
()
|
||||
let update_operation_hash_list_encoding () =
|
||||
operation_list_cache :=
|
||||
Operation.bounded_list_encoding
|
||||
?max_length:!operation_list_max_length
|
||||
?max_pass:!operation_max_pass
|
||||
()
|
||||
let update_operation_encoding () =
|
||||
operation_cache :=
|
||||
Operation.bounded_encoding ?max_size:!operation_max_size ()
|
||||
|
||||
let set_operation_max_size max =
|
||||
operation_max_size := max ;
|
||||
update_operation_encoding () ;
|
||||
update_operation_list_encoding ()
|
||||
let set_operation_list_max_size max =
|
||||
operation_list_max_size := max ;
|
||||
update_operation_list_encoding ()
|
||||
let set_operation_list_max_length max =
|
||||
operation_list_max_length := max ;
|
||||
update_operation_list_encoding () ;
|
||||
update_operation_hash_list_encoding ()
|
||||
let set_operation_max_pass max =
|
||||
operation_max_pass := max ;
|
||||
update_operation_list_encoding () ;
|
||||
update_operation_hash_list_encoding ()
|
||||
|
||||
let operation = delayed (fun () -> !operation_cache)
|
||||
let operation_list = delayed (fun () -> !operation_list_cache)
|
||||
let operation_hash_list = delayed (fun () -> !operation_hash_list_cache)
|
||||
|
||||
end
|
||||
|
||||
type t =
|
||||
@ -136,7 +192,7 @@ let encoding =
|
||||
|
||||
case ~tag:0x31
|
||||
~title:"Operation"
|
||||
(obj1 (req "operation" Operation.encoding))
|
||||
(obj1 (req "operation" Bounded_encoding.operation))
|
||||
(function Operation o -> Some o | _ -> None)
|
||||
(fun o -> Operation o);
|
||||
|
||||
@ -166,16 +222,16 @@ let encoding =
|
||||
|
||||
case ~tag:0x51
|
||||
~title:"Operation_hashes_for_blocks"
|
||||
(obj3
|
||||
(req "operation_hashes_for_block"
|
||||
(obj2
|
||||
(req "hash" Block_hash.encoding)
|
||||
(req "validation_pass" int8)))
|
||||
(req "operation_hashes" (list Operation_hash.encoding))
|
||||
(req "operation_hashes_path" Operation_list_list_hash.path_encoding))
|
||||
(merge_objs
|
||||
(obj1
|
||||
(req "operation_hashes_for_block"
|
||||
(obj2
|
||||
(req "hash" Block_hash.encoding)
|
||||
(req "validation_pass" int8))))
|
||||
Bounded_encoding.operation_hash_list)
|
||||
(function Operation_hashes_for_block (block, ofs, ops, path) ->
|
||||
Some ((block, ofs), ops, path) | _ -> None)
|
||||
(fun ((block, ofs), ops, path) ->
|
||||
Some ((block, ofs), (path, ops)) | _ -> None)
|
||||
(fun ((block, ofs), (path, ops)) ->
|
||||
Operation_hashes_for_block (block, ofs, ops, path)) ;
|
||||
|
||||
case ~tag:0x60
|
||||
@ -192,16 +248,16 @@ let encoding =
|
||||
|
||||
case ~tag:0x61
|
||||
~title:"Operations_for_blocks"
|
||||
(obj3
|
||||
(req "operations_for_block"
|
||||
(obj2
|
||||
(req "hash" Block_hash.encoding)
|
||||
(req "validation_pass" int8)))
|
||||
(req "operations" (list (dynamic_size Operation.encoding)))
|
||||
(req "operations_path" Operation_list_list_hash.path_encoding))
|
||||
(merge_objs
|
||||
(obj1
|
||||
(req "operations_for_block"
|
||||
(obj2
|
||||
(req "hash" Block_hash.encoding)
|
||||
(req "validation_pass" int8))))
|
||||
Bounded_encoding.operation_list)
|
||||
(function Operations_for_block (block, ofs, ops, path) ->
|
||||
Some ((block, ofs), ops, path) | _ -> None)
|
||||
(fun ((block, ofs), ops, path) ->
|
||||
Some ((block, ofs), (path, ops)) | _ -> None)
|
||||
(fun ((block, ofs), (path, ops)) ->
|
||||
Operations_for_block (block, ofs, ops, path)) ;
|
||||
|
||||
]
|
||||
|
@ -43,4 +43,8 @@ val pp_json : Format.formatter -> t -> unit
|
||||
|
||||
module Bounded_encoding : sig
|
||||
val set_block_header_max_size: int option -> unit
|
||||
val set_operation_max_size: int option -> unit
|
||||
val set_operation_list_max_size: int option -> unit
|
||||
val set_operation_list_max_length: int option -> unit
|
||||
val set_operation_max_pass: int option -> unit
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user