Proto, Gas: Fail at precheck if not enough gas to deserialize parameters
This commit is contained in:
parent
ecbab4fb77
commit
245b888ccc
@ -100,6 +100,11 @@ struct
|
|||||||
splitted ~json ~binary
|
splitted ~json ~binary
|
||||||
let make_lazy encoding value =
|
let make_lazy encoding value =
|
||||||
{ encoding ; state = Value value }
|
{ encoding ; state = Value value }
|
||||||
|
let fold_lazy fun_value fun_bytes fun_combine le =
|
||||||
|
match le.state with
|
||||||
|
| Value value -> fun_value value
|
||||||
|
| Bytes bytes -> fun_bytes bytes
|
||||||
|
| Both (bytes, value) -> fun_combine (fun_value value) (fun_bytes bytes)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -510,6 +510,11 @@ module Encoding: sig
|
|||||||
(** Make a lazy value from an immediate one. *)
|
(** Make a lazy value from an immediate one. *)
|
||||||
val make_lazy : 'a encoding -> 'a -> 'a lazy_t
|
val make_lazy : 'a encoding -> 'a -> 'a lazy_t
|
||||||
|
|
||||||
|
(** Fold on structure of lazy value, and combine results *)
|
||||||
|
val fold_lazy :
|
||||||
|
('a -> 'b) -> (MBytes.t -> 'b) -> ('b -> 'b -> 'b) ->
|
||||||
|
'a lazy_t -> 'b
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
include module type of Encoding with type 'a t = 'a Encoding.t
|
include module type of Encoding with type 'a t = 'a Encoding.t
|
||||||
|
@ -198,6 +198,9 @@ val lazy_encoding : 'a encoding -> 'a lazy_t encoding
|
|||||||
val force_decode : 'a lazy_t -> 'a option
|
val force_decode : 'a lazy_t -> 'a option
|
||||||
val force_bytes : 'a lazy_t -> MBytes.t
|
val force_bytes : 'a lazy_t -> MBytes.t
|
||||||
val make_lazy : 'a encoding -> 'a -> 'a lazy_t
|
val make_lazy : 'a encoding -> 'a -> 'a lazy_t
|
||||||
|
val fold_lazy :
|
||||||
|
('a -> 'b) -> (MBytes.t -> 'b) -> ('b -> 'b -> 'b) ->
|
||||||
|
'a lazy_t -> 'b
|
||||||
|
|
||||||
module Json : sig
|
module Json : sig
|
||||||
|
|
||||||
|
@ -301,6 +301,7 @@ module Script : sig
|
|||||||
val prim_encoding: prim Data_encoding.t
|
val prim_encoding: prim Data_encoding.t
|
||||||
val encoding: t Data_encoding.t
|
val encoding: t Data_encoding.t
|
||||||
val lazy_expr_encoding: lazy_expr Data_encoding.t
|
val lazy_expr_encoding: lazy_expr Data_encoding.t
|
||||||
|
val expr_cost : expr -> Gas.cost
|
||||||
end
|
end
|
||||||
|
|
||||||
module Constants : sig
|
module Constants : sig
|
||||||
|
@ -41,6 +41,7 @@ type error += Outdated_double_baking_evidence
|
|||||||
of { level: Raw_level.t ; last: Raw_level.t } (* `Permanent *)
|
of { level: Raw_level.t ; last: Raw_level.t } (* `Permanent *)
|
||||||
type error += Invalid_activation of { pkh : Ed25519.Public_key_hash.t }
|
type error += Invalid_activation of { pkh : Ed25519.Public_key_hash.t }
|
||||||
type error += Multiple_revelation
|
type error += Multiple_revelation
|
||||||
|
type error += Not_enough_gas_minimal_deserialize
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
register_error_kind
|
register_error_kind
|
||||||
@ -318,7 +319,15 @@ let () =
|
|||||||
"Multiple revelations were included in a manager operation")
|
"Multiple revelations were included in a manager operation")
|
||||||
Data_encoding.empty
|
Data_encoding.empty
|
||||||
(function Multiple_revelation -> Some () | _ -> None)
|
(function Multiple_revelation -> Some () | _ -> None)
|
||||||
(fun () -> Multiple_revelation)
|
(fun () -> Multiple_revelation) ;
|
||||||
|
register_error_kind
|
||||||
|
`Permanent
|
||||||
|
~id:"not_enough_gas.minimal_deserialization"
|
||||||
|
~title:"Not enough gas for minimal deserialization of transaction parameters"
|
||||||
|
~description:"Gas quota is not enough for deserializing the transaction parameters, even for the cheapest case"
|
||||||
|
Data_encoding.empty
|
||||||
|
(function Not_enough_gas_minimal_deserialize -> Some () | _ -> None)
|
||||||
|
(fun () -> Not_enough_gas_minimal_deserialize)
|
||||||
|
|
||||||
open Apply_results
|
open Apply_results
|
||||||
|
|
||||||
@ -491,6 +500,14 @@ let precheck_manager_contents
|
|||||||
match operation with
|
match operation with
|
||||||
| Reveal pk ->
|
| Reveal pk ->
|
||||||
Contract.reveal_manager_key ctxt source pk
|
Contract.reveal_manager_key ctxt source pk
|
||||||
|
| Transaction { parameters = Some arg ; _ } ->
|
||||||
|
let min_gas = Michelson_v1_gas.Cost_of.Typechecking.minimal_deserialize arg in
|
||||||
|
(* Fail if not enough gas for minimal deserialization cost *)
|
||||||
|
begin
|
||||||
|
match Gas.consume ctxt min_gas with
|
||||||
|
| Ok _ -> return ctxt
|
||||||
|
| Error _ -> fail Not_enough_gas_minimal_deserialize
|
||||||
|
end
|
||||||
| _ -> return ctxt
|
| _ -> return ctxt
|
||||||
end >>=? fun ctxt ->
|
end >>=? fun ctxt ->
|
||||||
Contract.get_manager_key ctxt source >>=? fun public_key ->
|
Contract.get_manager_key ctxt source >>=? fun public_key ->
|
||||||
|
@ -233,6 +233,12 @@ module Cost_of = struct
|
|||||||
(* TODO: proper handling of (de)serialization costs *)
|
(* TODO: proper handling of (de)serialization costs *)
|
||||||
let len = MBytes.length b in
|
let len = MBytes.length b in
|
||||||
alloc_cost len +@ step_cost (len * 10)
|
alloc_cost len +@ step_cost (len * 10)
|
||||||
|
let minimal_deserialize expr =
|
||||||
|
Data_encoding.fold_lazy
|
||||||
|
Script.expr_cost
|
||||||
|
(fun b -> alloc_bytes_cost (MBytes.length b))
|
||||||
|
(fun c _ -> c) (* keep expr cost if present *)
|
||||||
|
expr
|
||||||
end
|
end
|
||||||
|
|
||||||
module Unparse = struct
|
module Unparse = struct
|
||||||
|
@ -132,6 +132,8 @@ module Cost_of : sig
|
|||||||
val two_arg_type : Gas.cost
|
val two_arg_type : Gas.cost
|
||||||
|
|
||||||
val operation : MBytes.t -> Gas.cost
|
val operation : MBytes.t -> Gas.cost
|
||||||
|
|
||||||
|
val minimal_deserialize : Script.lazy_expr -> Gas.cost
|
||||||
end
|
end
|
||||||
|
|
||||||
module Unparse : sig
|
module Unparse : sig
|
||||||
|
Loading…
Reference in New Issue
Block a user