Alpha: fix storage limit check
This commit is contained in:
parent
1ecc5af454
commit
ece5dd2d78
@ -238,17 +238,7 @@ let report_errors ~details ~show_source ?parsed ppf errs =
|
|||||||
"@[<v 0>Gas limit exceeded during typechecking or execution.@,Try again with a higher gas limit.@]" ;
|
"@[<v 0>Gas limit exceeded during typechecking or execution.@,Try again with a higher gas limit.@]" ;
|
||||||
if rest <> [] then Format.fprintf ppf "@," ;
|
if rest <> [] then Format.fprintf ppf "@," ;
|
||||||
print_trace locations rest
|
print_trace locations rest
|
||||||
| Alpha_environment.Ecoproto_error Contract.Storage_limit_too_high :: rest ->
|
| Alpha_environment.Ecoproto_error Fees.Operation_quota_exceeded :: rest ->
|
||||||
Format.fprintf ppf
|
|
||||||
"Storage limit for the block is out of the protocol hard bounds." ;
|
|
||||||
if rest <> [] then Format.fprintf ppf "@," ;
|
|
||||||
print_trace locations rest
|
|
||||||
| Alpha_environment.Ecoproto_error Contract.Block_storage_quota_exceeded :: rest ->
|
|
||||||
Format.fprintf ppf
|
|
||||||
"Storage limit for the block exceeded during typechecking or execution." ;
|
|
||||||
if rest <> [] then Format.fprintf ppf "@," ;
|
|
||||||
print_trace locations rest
|
|
||||||
| Alpha_environment.Ecoproto_error Contract.Operation_storage_quota_exceeded :: rest ->
|
|
||||||
Format.fprintf ppf
|
Format.fprintf ppf
|
||||||
"@[<v 0>Storage limit exceeded during typechecking or execution.@,Try again with a higher storage limit.@]" ;
|
"@[<v 0>Storage limit exceeded during typechecking or execution.@,Try again with a higher storage limit.@]" ;
|
||||||
if rest <> [] then Format.fprintf ppf "@," ;
|
if rest <> [] then Format.fprintf ppf "@," ;
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
"Level_repr",
|
"Level_repr",
|
||||||
"Seed_repr",
|
"Seed_repr",
|
||||||
"Gas_limit_repr",
|
"Gas_limit_repr",
|
||||||
"Storage_limit_repr",
|
|
||||||
"Script_int_repr",
|
"Script_int_repr",
|
||||||
"Script_timestamp_repr",
|
"Script_timestamp_repr",
|
||||||
"Michelson_v1_primitives",
|
"Michelson_v1_primitives",
|
||||||
|
@ -91,11 +91,6 @@ module Contract = struct
|
|||||||
~spendable ~delegatable
|
~spendable ~delegatable
|
||||||
let init_origination_nonce = Raw_context.init_origination_nonce
|
let init_origination_nonce = Raw_context.init_origination_nonce
|
||||||
let unset_origination_nonce = Raw_context.unset_origination_nonce
|
let unset_origination_nonce = Raw_context.unset_origination_nonce
|
||||||
type error += Block_storage_quota_exceeded = Storage_limit_repr.Block_quota_exceeded
|
|
||||||
type error += Operation_storage_quota_exceeded = Storage_limit_repr.Operation_quota_exceeded
|
|
||||||
type error += Storage_limit_too_high = Raw_context.Storage_limit_too_high
|
|
||||||
let set_storage_limit = Raw_context.set_storage_limit
|
|
||||||
let set_storage_unlimited = Raw_context.set_storage_unlimited
|
|
||||||
end
|
end
|
||||||
module Delegate = Delegate_storage
|
module Delegate = Delegate_storage
|
||||||
module Roll = struct
|
module Roll = struct
|
||||||
|
@ -342,7 +342,6 @@ module Constants : sig
|
|||||||
endorsement_reward: Tez.t ;
|
endorsement_reward: Tez.t ;
|
||||||
cost_per_byte: Tez.t ;
|
cost_per_byte: Tez.t ;
|
||||||
hard_storage_limit_per_operation: Z.t ;
|
hard_storage_limit_per_operation: Z.t ;
|
||||||
hard_storage_limit_per_block: Z.t ;
|
|
||||||
}
|
}
|
||||||
val parametric_encoding: parametric Data_encoding.t
|
val parametric_encoding: parametric Data_encoding.t
|
||||||
val parametric: context -> parametric
|
val parametric: context -> parametric
|
||||||
@ -357,7 +356,6 @@ module Constants : sig
|
|||||||
val hard_gas_limit_per_block: context -> Z.t
|
val hard_gas_limit_per_block: context -> Z.t
|
||||||
val cost_per_byte: context -> Tez.t
|
val cost_per_byte: context -> Tez.t
|
||||||
val hard_storage_limit_per_operation: context -> Z.t
|
val hard_storage_limit_per_operation: context -> Z.t
|
||||||
val hard_storage_limit_per_block: context -> Z.t
|
|
||||||
val proof_of_work_threshold: context -> int64
|
val proof_of_work_threshold: context -> int64
|
||||||
val dictator_pubkey: context -> Signature.Public_key.t
|
val dictator_pubkey: context -> Signature.Public_key.t
|
||||||
val tokens_per_roll: context -> Tez.t
|
val tokens_per_roll: context -> Tez.t
|
||||||
@ -570,13 +568,6 @@ module Contract : sig
|
|||||||
Script.expr -> big_map_diff option ->
|
Script.expr -> big_map_diff option ->
|
||||||
context tzresult Lwt.t
|
context tzresult Lwt.t
|
||||||
|
|
||||||
type error += Block_storage_quota_exceeded (* `Temporary *)
|
|
||||||
type error += Operation_storage_quota_exceeded (* `Temporary *)
|
|
||||||
type error += Storage_limit_too_high (* `Permanent *)
|
|
||||||
|
|
||||||
val set_storage_limit: context -> Z.t -> context tzresult
|
|
||||||
val set_storage_unlimited: context -> context
|
|
||||||
|
|
||||||
val used_storage_space: context -> t -> Z.t tzresult Lwt.t
|
val used_storage_space: context -> t -> Z.t tzresult Lwt.t
|
||||||
|
|
||||||
val increment_counter:
|
val increment_counter:
|
||||||
@ -902,10 +893,14 @@ module Fees : sig
|
|||||||
context -> Contract.t -> (context * Z.t * Z.t * Tez.t) tzresult Lwt.t
|
context -> Contract.t -> (context * Z.t * Z.t * Tez.t) tzresult Lwt.t
|
||||||
|
|
||||||
val with_fees_for_storage:
|
val with_fees_for_storage:
|
||||||
context -> payer:Contract.t ->
|
context -> storage_limit:Z.t -> payer:Contract.t ->
|
||||||
(context -> (context * 'a) tzresult Lwt.t) ->
|
(context -> (context * 'a) tzresult Lwt.t) ->
|
||||||
(context * 'a) tzresult Lwt.t
|
(context * 'a) tzresult Lwt.t
|
||||||
|
|
||||||
|
type error += Cannot_pay_storage_fee (* `Temporary *)
|
||||||
|
type error += Operation_quota_exceeded (* `Temporary *)
|
||||||
|
type error += Storage_limit_too_high (* `Permanent *)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Operation : sig
|
module Operation : sig
|
||||||
|
@ -508,9 +508,8 @@ let apply_manager_contents
|
|||||||
let Manager_operation
|
let Manager_operation
|
||||||
{ source ; fee ; operation ; gas_limit ; storage_limit } = op in
|
{ source ; fee ; operation ; gas_limit ; storage_limit } = op in
|
||||||
Lwt.return (Gas.set_limit ctxt gas_limit) >>=? fun ctxt ->
|
Lwt.return (Gas.set_limit ctxt gas_limit) >>=? fun ctxt ->
|
||||||
Lwt.return (Contract.set_storage_limit ctxt storage_limit) >>=? fun ctxt ->
|
|
||||||
let level = Level.current ctxt in
|
let level = Level.current ctxt in
|
||||||
Fees.with_fees_for_storage ctxt ~payer:source begin fun ctxt ->
|
Fees.with_fees_for_storage ctxt ~payer:source ~storage_limit begin fun ctxt ->
|
||||||
apply_manager_operation_content ctxt mode
|
apply_manager_operation_content ctxt mode
|
||||||
~source ~payer:source ~internal:false operation >>= begin function
|
~source ~payer:source ~internal:false operation >>= begin function
|
||||||
| Ok (ctxt, operation_results, internal_operations) -> begin
|
| Ok (ctxt, operation_results, internal_operations) -> begin
|
||||||
@ -790,7 +789,6 @@ let apply_operation ctxt mode pred_block baker hash operation =
|
|||||||
ctxt mode pred_block baker operation
|
ctxt mode pred_block baker operation
|
||||||
operation.protocol_data.contents >>=? fun (ctxt, result) ->
|
operation.protocol_data.contents >>=? fun (ctxt, result) ->
|
||||||
let ctxt = Gas.set_unlimited ctxt in
|
let ctxt = Gas.set_unlimited ctxt in
|
||||||
let ctxt = Contract.set_storage_unlimited ctxt in
|
|
||||||
let ctxt = Contract.unset_origination_nonce ctxt in
|
let ctxt = Contract.unset_origination_nonce ctxt in
|
||||||
return (ctxt, { contents = result })
|
return (ctxt, { contents = result })
|
||||||
|
|
||||||
|
@ -72,7 +72,6 @@ type parametric = {
|
|||||||
endorsement_reward: Tez_repr.t ;
|
endorsement_reward: Tez_repr.t ;
|
||||||
cost_per_byte: Tez_repr.t ;
|
cost_per_byte: Tez_repr.t ;
|
||||||
hard_storage_limit_per_operation: Z.t ;
|
hard_storage_limit_per_operation: Z.t ;
|
||||||
hard_storage_limit_per_block: Z.t ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let default = {
|
let default = {
|
||||||
@ -105,7 +104,6 @@ let default = {
|
|||||||
block_reward = Tez_repr.(mul_exn one 16) ;
|
block_reward = Tez_repr.(mul_exn one 16) ;
|
||||||
endorsement_reward = Tez_repr.(mul_exn one 2) ;
|
endorsement_reward = Tez_repr.(mul_exn one 2) ;
|
||||||
hard_storage_limit_per_operation = Z.of_int 60_000 ;
|
hard_storage_limit_per_operation = Z.of_int 60_000 ;
|
||||||
hard_storage_limit_per_block = Z.of_int 1_000_000 ;
|
|
||||||
cost_per_byte = Tez_repr.of_mutez_exn 1_000L ;
|
cost_per_byte = Tez_repr.of_mutez_exn 1_000L ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,8 +133,7 @@ let parametric_encoding =
|
|||||||
c.block_reward),
|
c.block_reward),
|
||||||
(c.endorsement_reward,
|
(c.endorsement_reward,
|
||||||
c.cost_per_byte,
|
c.cost_per_byte,
|
||||||
c.hard_storage_limit_per_operation,
|
c.hard_storage_limit_per_operation))) )
|
||||||
c.hard_storage_limit_per_block))) )
|
|
||||||
(fun (( preserved_cycles,
|
(fun (( preserved_cycles,
|
||||||
blocks_per_cycle,
|
blocks_per_cycle,
|
||||||
blocks_per_commitment,
|
blocks_per_commitment,
|
||||||
@ -157,8 +154,7 @@ let parametric_encoding =
|
|||||||
block_reward),
|
block_reward),
|
||||||
(endorsement_reward,
|
(endorsement_reward,
|
||||||
cost_per_byte,
|
cost_per_byte,
|
||||||
hard_storage_limit_per_operation,
|
hard_storage_limit_per_operation))) ->
|
||||||
hard_storage_limit_per_block))) ->
|
|
||||||
{ preserved_cycles ;
|
{ preserved_cycles ;
|
||||||
blocks_per_cycle ;
|
blocks_per_cycle ;
|
||||||
blocks_per_commitment ;
|
blocks_per_commitment ;
|
||||||
@ -180,7 +176,6 @@ let parametric_encoding =
|
|||||||
endorsement_reward ;
|
endorsement_reward ;
|
||||||
cost_per_byte ;
|
cost_per_byte ;
|
||||||
hard_storage_limit_per_operation ;
|
hard_storage_limit_per_operation ;
|
||||||
hard_storage_limit_per_block ;
|
|
||||||
} )
|
} )
|
||||||
(merge_objs
|
(merge_objs
|
||||||
(obj9
|
(obj9
|
||||||
@ -204,11 +199,10 @@ let parametric_encoding =
|
|||||||
(req "block_security_deposit" Tez_repr.encoding)
|
(req "block_security_deposit" Tez_repr.encoding)
|
||||||
(req "endorsement_security_deposit" Tez_repr.encoding)
|
(req "endorsement_security_deposit" Tez_repr.encoding)
|
||||||
(req "block_reward" Tez_repr.encoding))
|
(req "block_reward" Tez_repr.encoding))
|
||||||
(obj4
|
(obj3
|
||||||
(req "endorsement_reward" Tez_repr.encoding)
|
(req "endorsement_reward" Tez_repr.encoding)
|
||||||
(req "cost_per_byte" Tez_repr.encoding)
|
(req "cost_per_byte" Tez_repr.encoding)
|
||||||
(req "hard_storage_limit_per_operation" z)
|
(req "hard_storage_limit_per_operation" z))))
|
||||||
(req "hard_storage_limit_per_block" z))))
|
|
||||||
|
|
||||||
type t = {
|
type t = {
|
||||||
fixed : fixed ;
|
fixed : fixed ;
|
||||||
|
@ -40,9 +40,6 @@ let cost_per_byte c =
|
|||||||
let hard_storage_limit_per_operation c =
|
let hard_storage_limit_per_operation c =
|
||||||
let constants = Raw_context.constants c in
|
let constants = Raw_context.constants c in
|
||||||
constants.hard_storage_limit_per_operation
|
constants.hard_storage_limit_per_operation
|
||||||
let hard_storage_limit_per_block c =
|
|
||||||
let constants = Raw_context.constants c in
|
|
||||||
constants.hard_storage_limit_per_block
|
|
||||||
let proof_of_work_threshold c =
|
let proof_of_work_threshold c =
|
||||||
let constants = Raw_context.constants c in
|
let constants = Raw_context.constants c in
|
||||||
constants.proof_of_work_threshold
|
constants.proof_of_work_threshold
|
||||||
|
@ -7,9 +7,12 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
type error += Cannot_pay_storage_fee
|
type error += Cannot_pay_storage_fee (* `Temporary *)
|
||||||
|
type error += Operation_quota_exceeded (* `Temporary *)
|
||||||
|
type error += Storage_limit_too_high (* `Permanent *)
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
|
let open Data_encoding in
|
||||||
register_error_kind
|
register_error_kind
|
||||||
`Temporary
|
`Temporary
|
||||||
~id:"contract.cannot_pay_storage_fee"
|
~id:"contract.cannot_pay_storage_fee"
|
||||||
@ -18,8 +21,26 @@ let () =
|
|||||||
~pp:(fun ppf () -> Format.fprintf ppf "Cannot pay storage storage fee")
|
~pp:(fun ppf () -> Format.fprintf ppf "Cannot pay storage storage fee")
|
||||||
Data_encoding.empty
|
Data_encoding.empty
|
||||||
(function Cannot_pay_storage_fee -> Some () | _ -> None)
|
(function Cannot_pay_storage_fee -> Some () | _ -> None)
|
||||||
(fun () -> Cannot_pay_storage_fee)
|
(fun () -> Cannot_pay_storage_fee) ;
|
||||||
|
register_error_kind
|
||||||
|
`Temporary
|
||||||
|
~id:"storage_exhausted.operation"
|
||||||
|
~title: "Storage quota exceeded for the operation"
|
||||||
|
~description:
|
||||||
|
"A script or one of its callee wrote more \
|
||||||
|
bytes than the operation said it would"
|
||||||
|
Data_encoding.empty
|
||||||
|
(function Operation_quota_exceeded -> Some () | _ -> None)
|
||||||
|
(fun () -> Operation_quota_exceeded) ;
|
||||||
|
register_error_kind
|
||||||
|
`Permanent
|
||||||
|
~id:"storage_limit_too_high"
|
||||||
|
~title: "Storage limit out of protocol hard bounds"
|
||||||
|
~description:
|
||||||
|
"A transaction tried to exceed the hard limit on storage"
|
||||||
|
empty
|
||||||
|
(function Storage_limit_too_high -> Some () | _ -> None)
|
||||||
|
(fun () -> Storage_limit_too_high)
|
||||||
|
|
||||||
let origination_burn c ~payer =
|
let origination_burn c ~payer =
|
||||||
let origination_burn = Constants_storage.origination_burn c in
|
let origination_burn = Constants_storage.origination_burn c in
|
||||||
@ -34,23 +55,33 @@ let record_paid_storage_space c contract =
|
|||||||
Lwt.return (Tez_repr.(cost_per_byte *? (Z.to_int64 to_be_paid))) >>=? fun to_burn ->
|
Lwt.return (Tez_repr.(cost_per_byte *? (Z.to_int64 to_be_paid))) >>=? fun to_burn ->
|
||||||
return (c, size, to_be_paid, to_burn)
|
return (c, size, to_be_paid, to_burn)
|
||||||
|
|
||||||
let burn_fees_for_storage c ~payer =
|
let burn_fees_for_storage c ~storage_limit ~payer =
|
||||||
let c, storage_space_to_pay = Raw_context.clear_storage_space_to_pay c in
|
let c, storage_space_to_pay = Raw_context.clear_storage_space_to_pay c in
|
||||||
let cost_per_byte = Constants_storage.cost_per_byte c in
|
let remaining = Z.sub storage_limit storage_space_to_pay in
|
||||||
Lwt.return (Tez_repr.(cost_per_byte *? (Z.to_int64 storage_space_to_pay))) >>=? fun to_burn ->
|
if Compare.Z.(remaining < Z.zero) then
|
||||||
(* Burning the fees... *)
|
fail Operation_quota_exceeded
|
||||||
if Tez_repr.(to_burn = Tez_repr.zero) then
|
|
||||||
(* If the payer was was deleted by transfering all its balance, and no space was used,
|
|
||||||
burning zero would fail *)
|
|
||||||
return c
|
|
||||||
else
|
else
|
||||||
trace Cannot_pay_storage_fee
|
let cost_per_byte = Constants_storage.cost_per_byte c in
|
||||||
(Contract_storage.must_exist c payer >>=? fun () ->
|
Lwt.return (Tez_repr.(cost_per_byte *? (Z.to_int64 storage_space_to_pay))) >>=? fun to_burn ->
|
||||||
Contract_storage.spend_from_script c payer to_burn) >>=? fun c ->
|
(* Burning the fees... *)
|
||||||
return c
|
if Tez_repr.(to_burn = Tez_repr.zero) then
|
||||||
|
(* If the payer was was deleted by transfering all its balance, and no space was used,
|
||||||
|
burning zero would fail *)
|
||||||
|
return c
|
||||||
|
else
|
||||||
|
trace Cannot_pay_storage_fee
|
||||||
|
(Contract_storage.must_exist c payer >>=? fun () ->
|
||||||
|
Contract_storage.spend_from_script c payer to_burn) >>=? fun c ->
|
||||||
|
return c
|
||||||
|
|
||||||
let with_fees_for_storage c ~payer f =
|
let with_fees_for_storage c ~storage_limit ~payer f =
|
||||||
|
begin if Compare.Z.(storage_limit > (Raw_context.constants c).hard_storage_limit_per_operation)
|
||||||
|
|| Compare.Z.(storage_limit < Z.zero)then
|
||||||
|
fail Storage_limit_too_high
|
||||||
|
else
|
||||||
|
return ()
|
||||||
|
end >>=? fun () ->
|
||||||
Lwt.return (Raw_context.init_storage_space_to_pay c) >>=? fun c ->
|
Lwt.return (Raw_context.init_storage_space_to_pay c) >>=? fun c ->
|
||||||
f c >>=? fun (c, ret) ->
|
f c >>=? fun (c, ret) ->
|
||||||
burn_fees_for_storage c ~payer >>=? fun c ->
|
burn_fees_for_storage c ~storage_limit ~payer >>=? fun c ->
|
||||||
return (c, ret)
|
return (c, ret)
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
type error += Cannot_pay_storage_fee
|
type error += Cannot_pay_storage_fee (* `Temporary *)
|
||||||
|
type error += Operation_quota_exceeded (* `Temporary *)
|
||||||
|
type error += Storage_limit_too_high (* `Permanent *)
|
||||||
|
|
||||||
val origination_burn:
|
val origination_burn:
|
||||||
Raw_context.t -> payer:Contract_repr.t -> (Raw_context.t * Tez_repr.t) tzresult Lwt.t
|
Raw_context.t -> payer:Contract_repr.t -> (Raw_context.t * Tez_repr.t) tzresult Lwt.t
|
||||||
@ -18,6 +20,6 @@ val record_paid_storage_space:
|
|||||||
(Raw_context.t * Z.t * Z.t * Tez_repr.t) tzresult Lwt.t
|
(Raw_context.t * Z.t * Z.t * Tez_repr.t) tzresult Lwt.t
|
||||||
|
|
||||||
val with_fees_for_storage:
|
val with_fees_for_storage:
|
||||||
Raw_context.t -> payer:Contract_repr.t ->
|
Raw_context.t -> storage_limit:Z.t -> payer:Contract_repr.t ->
|
||||||
(Raw_context.t -> (Raw_context.t * 'a) tzresult Lwt.t) ->
|
(Raw_context.t -> (Raw_context.t * 'a) tzresult Lwt.t) ->
|
||||||
(Raw_context.t * 'a) tzresult Lwt.t
|
(Raw_context.t * 'a) tzresult Lwt.t
|
||||||
|
@ -143,9 +143,6 @@ let constants_encoding =
|
|||||||
and hard_storage_limit_per_operation =
|
and hard_storage_limit_per_operation =
|
||||||
opt Compare.Z.(=)
|
opt Compare.Z.(=)
|
||||||
default.hard_storage_limit_per_operation c.hard_storage_limit_per_operation
|
default.hard_storage_limit_per_operation c.hard_storage_limit_per_operation
|
||||||
and hard_storage_limit_per_block =
|
|
||||||
opt Compare.Z.(=)
|
|
||||||
default.hard_storage_limit_per_block c.hard_storage_limit_per_block
|
|
||||||
in
|
in
|
||||||
(( preserved_cycles,
|
(( preserved_cycles,
|
||||||
blocks_per_cycle,
|
blocks_per_cycle,
|
||||||
@ -167,8 +164,7 @@ let constants_encoding =
|
|||||||
block_reward),
|
block_reward),
|
||||||
(endorsement_reward,
|
(endorsement_reward,
|
||||||
cost_per_byte,
|
cost_per_byte,
|
||||||
hard_storage_limit_per_operation,
|
hard_storage_limit_per_operation))))
|
||||||
hard_storage_limit_per_block))))
|
|
||||||
(fun (( preserved_cycles,
|
(fun (( preserved_cycles,
|
||||||
blocks_per_cycle,
|
blocks_per_cycle,
|
||||||
blocks_per_commitment,
|
blocks_per_commitment,
|
||||||
@ -189,8 +185,7 @@ let constants_encoding =
|
|||||||
block_reward),
|
block_reward),
|
||||||
(endorsement_reward,
|
(endorsement_reward,
|
||||||
cost_per_byte,
|
cost_per_byte,
|
||||||
hard_storage_limit_per_operation,
|
hard_storage_limit_per_operation))) ->
|
||||||
hard_storage_limit_per_block))) ->
|
|
||||||
let unopt def = function None -> def | Some v -> v in
|
let unopt def = function None -> def | Some v -> v in
|
||||||
let default = Constants_repr.default in
|
let default = Constants_repr.default in
|
||||||
{ Constants_repr.preserved_cycles =
|
{ Constants_repr.preserved_cycles =
|
||||||
@ -236,8 +231,6 @@ let constants_encoding =
|
|||||||
unopt default.cost_per_byte cost_per_byte ;
|
unopt default.cost_per_byte cost_per_byte ;
|
||||||
hard_storage_limit_per_operation =
|
hard_storage_limit_per_operation =
|
||||||
unopt default.hard_storage_limit_per_operation hard_storage_limit_per_operation ;
|
unopt default.hard_storage_limit_per_operation hard_storage_limit_per_operation ;
|
||||||
hard_storage_limit_per_block =
|
|
||||||
unopt default.hard_storage_limit_per_block hard_storage_limit_per_block ;
|
|
||||||
} )
|
} )
|
||||||
(merge_objs
|
(merge_objs
|
||||||
(obj9
|
(obj9
|
||||||
@ -261,11 +254,10 @@ let constants_encoding =
|
|||||||
(opt "block_security_deposit" Tez_repr.encoding)
|
(opt "block_security_deposit" Tez_repr.encoding)
|
||||||
(opt "endorsement_security_deposit" Tez_repr.encoding)
|
(opt "endorsement_security_deposit" Tez_repr.encoding)
|
||||||
(opt "block_reward" Tez_repr.encoding))
|
(opt "block_reward" Tez_repr.encoding))
|
||||||
(obj4
|
(obj3
|
||||||
(opt "endorsement_reward" Tez_repr.encoding)
|
(opt "endorsement_reward" Tez_repr.encoding)
|
||||||
(opt "cost_per_byte" Tez_repr.encoding)
|
(opt "cost_per_byte" Tez_repr.encoding)
|
||||||
(opt "hard_storage_limit_per_operation" z)
|
(opt "hard_storage_limit_per_operation" z))))
|
||||||
(opt "hard_storage_limit_per_block" z))))
|
|
||||||
|
|
||||||
let encoding =
|
let encoding =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
|
@ -24,8 +24,6 @@ type t = {
|
|||||||
block_gas: Z.t ;
|
block_gas: Z.t ;
|
||||||
operation_gas: Gas_limit_repr.t ;
|
operation_gas: Gas_limit_repr.t ;
|
||||||
storage_space_to_pay: Z.t option ;
|
storage_space_to_pay: Z.t option ;
|
||||||
block_storage: Z.t ;
|
|
||||||
operation_storage: Storage_limit_repr.t ;
|
|
||||||
origination_nonce: Contract_repr.origination_nonce option ;
|
origination_nonce: Contract_repr.origination_nonce option ;
|
||||||
internal_nonce: int ;
|
internal_nonce: int ;
|
||||||
internal_nonces_used: Int_set.t ;
|
internal_nonces_used: Int_set.t ;
|
||||||
@ -180,8 +178,6 @@ let gas_consumed ~since ~until =
|
|||||||
| Limited { remaining = before }, Limited { remaining = after } -> Z.sub before after
|
| Limited { remaining = before }, Limited { remaining = after } -> Z.sub before after
|
||||||
| _, _ -> Z.zero
|
| _, _ -> Z.zero
|
||||||
|
|
||||||
type error += Storage_limit_too_high (* `Permanent *)
|
|
||||||
|
|
||||||
let init_storage_space_to_pay ctxt =
|
let init_storage_space_to_pay ctxt =
|
||||||
match ctxt.storage_space_to_pay with
|
match ctxt.storage_space_to_pay with
|
||||||
| Some _ ->
|
| Some _ ->
|
||||||
@ -203,30 +199,6 @@ let clear_storage_space_to_pay ctxt =
|
|||||||
| Some storage_space_to_pay ->
|
| Some storage_space_to_pay ->
|
||||||
{ ctxt with storage_space_to_pay = None }, storage_space_to_pay
|
{ ctxt with storage_space_to_pay = None }, storage_space_to_pay
|
||||||
|
|
||||||
let () =
|
|
||||||
let open Data_encoding in
|
|
||||||
register_error_kind
|
|
||||||
`Permanent
|
|
||||||
~id:"storage_limit_too_high"
|
|
||||||
~title: "Storage limit out of protocol hard bounds"
|
|
||||||
~description:
|
|
||||||
"A transaction tried to exceed the hard limit on storage"
|
|
||||||
empty
|
|
||||||
(function Storage_limit_too_high -> Some () | _ -> None)
|
|
||||||
(fun () -> Storage_limit_too_high)
|
|
||||||
|
|
||||||
let set_storage_limit ctxt remaining =
|
|
||||||
if Compare.Z.(remaining > ctxt.constants.hard_storage_limit_per_operation)
|
|
||||||
|| Compare.Z.(remaining < Z.zero)then
|
|
||||||
error Storage_limit_too_high
|
|
||||||
else
|
|
||||||
ok { ctxt with operation_storage = Limited { remaining } }
|
|
||||||
let set_storage_unlimited ctxt =
|
|
||||||
{ ctxt with operation_storage = Unaccounted }
|
|
||||||
let record_bytes_stored ctxt bytes =
|
|
||||||
Storage_limit_repr.consume ctxt.block_storage ctxt.operation_storage ~bytes >>? fun (block_storage, operation_storage) ->
|
|
||||||
ok { ctxt with block_storage ; operation_storage }
|
|
||||||
|
|
||||||
type storage_error =
|
type storage_error =
|
||||||
| Incompatible_protocol_version of string
|
| Incompatible_protocol_version of string
|
||||||
| Missing_key of string list * [`Get | `Set | `Del | `Copy]
|
| Missing_key of string list * [`Get | `Set | `Del | `Copy]
|
||||||
@ -451,8 +423,6 @@ let prepare ~level ~timestamp ~fitness ctxt =
|
|||||||
operation_gas = Unaccounted ;
|
operation_gas = Unaccounted ;
|
||||||
storage_space_to_pay = None ;
|
storage_space_to_pay = None ;
|
||||||
block_gas = constants.Constants_repr.hard_gas_limit_per_block ;
|
block_gas = constants.Constants_repr.hard_gas_limit_per_block ;
|
||||||
operation_storage = Unaccounted ;
|
|
||||||
block_storage = constants.Constants_repr.hard_storage_limit_per_block ;
|
|
||||||
origination_nonce = None ;
|
origination_nonce = None ;
|
||||||
internal_nonce = 0 ;
|
internal_nonce = 0 ;
|
||||||
internal_nonces_used = Int_set.empty ;
|
internal_nonces_used = Int_set.empty ;
|
||||||
@ -504,8 +474,6 @@ let register_resolvers enc resolve =
|
|||||||
deposits = Signature.Public_key_hash.Map.empty ;
|
deposits = Signature.Public_key_hash.Map.empty ;
|
||||||
block_gas = Constants_repr.default.hard_gas_limit_per_block ;
|
block_gas = Constants_repr.default.hard_gas_limit_per_block ;
|
||||||
operation_gas = Unaccounted ;
|
operation_gas = Unaccounted ;
|
||||||
block_storage = Constants_repr.default.hard_storage_limit_per_block ;
|
|
||||||
operation_storage = Unaccounted ;
|
|
||||||
origination_nonce = None ;
|
origination_nonce = None ;
|
||||||
internal_nonce = 0 ;
|
internal_nonce = 0 ;
|
||||||
internal_nonces_used = Int_set.empty ;
|
internal_nonces_used = Int_set.empty ;
|
||||||
@ -553,8 +521,6 @@ module type T = sig
|
|||||||
|
|
||||||
val consume_gas: context -> Gas_limit_repr.cost -> context tzresult
|
val consume_gas: context -> Gas_limit_repr.cost -> context tzresult
|
||||||
|
|
||||||
val record_bytes_stored: context -> Z.t -> context tzresult
|
|
||||||
|
|
||||||
val description: context Storage_description.t
|
val description: context Storage_description.t
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -96,15 +96,10 @@ val gas_level: t -> Gas_limit_repr.t
|
|||||||
val gas_consumed: since: t -> until: t -> Z.t
|
val gas_consumed: since: t -> until: t -> Z.t
|
||||||
val block_gas_level: t -> Z.t
|
val block_gas_level: t -> Z.t
|
||||||
|
|
||||||
type error += Storage_limit_too_high (* `Permanent *)
|
|
||||||
|
|
||||||
val init_storage_space_to_pay: t -> t tzresult
|
val init_storage_space_to_pay: t -> t tzresult
|
||||||
val update_storage_space_to_pay: t -> Z.t -> t tzresult
|
val update_storage_space_to_pay: t -> Z.t -> t tzresult
|
||||||
val clear_storage_space_to_pay: t -> t * Z.t
|
val clear_storage_space_to_pay: t -> t * Z.t
|
||||||
|
|
||||||
val set_storage_limit: t -> Z.t -> t tzresult
|
|
||||||
val set_storage_unlimited: t -> t
|
|
||||||
|
|
||||||
type error += Undefined_operation_nonce (* `Permanent *)
|
type error += Undefined_operation_nonce (* `Permanent *)
|
||||||
|
|
||||||
val init_origination_nonce: t -> Operation_hash.t -> t
|
val init_origination_nonce: t -> Operation_hash.t -> t
|
||||||
@ -196,10 +191,6 @@ module type T = sig
|
|||||||
within a view. *)
|
within a view. *)
|
||||||
val consume_gas: context -> Gas_limit_repr.cost -> context tzresult
|
val consume_gas: context -> Gas_limit_repr.cost -> context tzresult
|
||||||
|
|
||||||
(** Internally used in {!Storage_functors} to consume storage from
|
|
||||||
within a view. *)
|
|
||||||
val record_bytes_stored: context -> Z.t -> context tzresult
|
|
||||||
|
|
||||||
val description: context Storage_description.t
|
val description: context Storage_description.t
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -66,7 +66,6 @@ module Make_subcontext (C : Raw_context.T) (N : NAME)
|
|||||||
let project = C.project
|
let project = C.project
|
||||||
let absolute_key c k = C.absolute_key c (to_key k)
|
let absolute_key c k = C.absolute_key c (to_key k)
|
||||||
let consume_gas = C.consume_gas
|
let consume_gas = C.consume_gas
|
||||||
let record_bytes_stored = C.record_bytes_stored
|
|
||||||
let description =
|
let description =
|
||||||
Storage_description.register_named_subcontext C.description N.name
|
Storage_description.register_named_subcontext C.description N.name
|
||||||
end
|
end
|
||||||
@ -359,13 +358,11 @@ module Make_indexed_carbonated_data_storage
|
|||||||
consume_write_gas C.set s i v >>=? fun (s, bytes) ->
|
consume_write_gas C.set s i v >>=? fun (s, bytes) ->
|
||||||
C.set s (name i) bytes >>=? fun t ->
|
C.set s (name i) bytes >>=? fun t ->
|
||||||
let size_diff = MBytes.length bytes - prev_size in
|
let size_diff = MBytes.length bytes - prev_size in
|
||||||
Lwt.return (C.record_bytes_stored t (Z.of_int size_diff)) >>=? fun t ->
|
|
||||||
return (C.project t, size_diff)
|
return (C.project t, size_diff)
|
||||||
let init s i v =
|
let init s i v =
|
||||||
consume_write_gas C.init s i v >>=? fun (s, bytes) ->
|
consume_write_gas C.init s i v >>=? fun (s, bytes) ->
|
||||||
C.init s (name i) bytes >>=? fun t ->
|
C.init s (name i) bytes >>=? fun t ->
|
||||||
let size = MBytes.length bytes in
|
let size = MBytes.length bytes in
|
||||||
Lwt.return (C.record_bytes_stored t (Z.of_int size)) >>=? fun t ->
|
|
||||||
return (C.project t, size)
|
return (C.project t, size)
|
||||||
let init_set s i v =
|
let init_set s i v =
|
||||||
let init_set s i v = C.init_set s i v >>= return in
|
let init_set s i v = C.init_set s i v >>= return in
|
||||||
@ -373,20 +370,17 @@ module Make_indexed_carbonated_data_storage
|
|||||||
consume_write_gas init_set s i v >>=? fun (s, bytes) ->
|
consume_write_gas init_set s i v >>=? fun (s, bytes) ->
|
||||||
init_set s (name i) bytes >>=? fun t ->
|
init_set s (name i) bytes >>=? fun t ->
|
||||||
let size_diff = MBytes.length bytes - prev_size in
|
let size_diff = MBytes.length bytes - prev_size in
|
||||||
Lwt.return (C.record_bytes_stored t (Z.of_int size_diff)) >>=? fun t ->
|
|
||||||
return (C.project t, size_diff)
|
return (C.project t, size_diff)
|
||||||
let remove s i =
|
let remove s i =
|
||||||
let remove s i = C.remove s i >>= return in
|
let remove s i = C.remove s i >>= return in
|
||||||
existing_size s i >>=? fun prev_size ->
|
existing_size s i >>=? fun prev_size ->
|
||||||
consume_remove_gas remove s i >>=? fun s ->
|
consume_remove_gas remove s i >>=? fun s ->
|
||||||
remove s (name i) >>=? fun t ->
|
remove s (name i) >>=? fun t ->
|
||||||
Lwt.return (C.record_bytes_stored t (Z.of_int ~-prev_size)) >>=? fun t ->
|
|
||||||
return (C.project t, prev_size)
|
return (C.project t, prev_size)
|
||||||
let delete s i =
|
let delete s i =
|
||||||
existing_size s i >>=? fun prev_size ->
|
existing_size s i >>=? fun prev_size ->
|
||||||
consume_remove_gas C.delete s i >>=? fun s ->
|
consume_remove_gas C.delete s i >>=? fun s ->
|
||||||
C.delete s (name i) >>=? fun t ->
|
C.delete s (name i) >>=? fun t ->
|
||||||
Lwt.return (C.record_bytes_stored t (Z.of_int ~-prev_size)) >>=? fun t ->
|
|
||||||
return (C.project t, prev_size)
|
return (C.project t, prev_size)
|
||||||
let set_option s i v =
|
let set_option s i v =
|
||||||
match v with
|
match v with
|
||||||
@ -561,10 +555,6 @@ module Make_indexed_subcontext (C : Raw_context.T) (I : INDEX)
|
|||||||
let consume_gas c g =
|
let consume_gas c g =
|
||||||
let (t, i) = unpack c in
|
let (t, i) = unpack c in
|
||||||
C.consume_gas t g >>? fun t -> ok (pack t i)
|
C.consume_gas t g >>? fun t -> ok (pack t i)
|
||||||
let record_bytes_stored c v =
|
|
||||||
let (t, i) = unpack c in
|
|
||||||
C.record_bytes_stored t v >>? fun t ->
|
|
||||||
ok (pack t i)
|
|
||||||
let description = description
|
let description = description
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -784,13 +774,11 @@ module Make_indexed_subcontext (C : Raw_context.T) (I : INDEX)
|
|||||||
consume_write_gas Raw_context.set (pack s i) v >>=? fun (c, bytes) ->
|
consume_write_gas Raw_context.set (pack s i) v >>=? fun (c, bytes) ->
|
||||||
Raw_context.set c data_name bytes >>=? fun c ->
|
Raw_context.set c data_name bytes >>=? fun c ->
|
||||||
let size_diff = MBytes.length bytes - prev_size in
|
let size_diff = MBytes.length bytes - prev_size in
|
||||||
Lwt.return (Raw_context.record_bytes_stored c (Z.of_int size_diff)) >>=? fun c ->
|
|
||||||
return (Raw_context.project c, size_diff)
|
return (Raw_context.project c, size_diff)
|
||||||
let init s i v =
|
let init s i v =
|
||||||
consume_write_gas Raw_context.init (pack s i) v >>=? fun (c, bytes) ->
|
consume_write_gas Raw_context.init (pack s i) v >>=? fun (c, bytes) ->
|
||||||
Raw_context.init c data_name bytes >>=? fun c ->
|
Raw_context.init c data_name bytes >>=? fun c ->
|
||||||
let size = MBytes.length bytes in
|
let size = MBytes.length bytes in
|
||||||
Lwt.return (Raw_context.record_bytes_stored c (Z.of_int size)) >>=? fun c ->
|
|
||||||
return (Raw_context.project c, size)
|
return (Raw_context.project c, size)
|
||||||
let init_set s i v =
|
let init_set s i v =
|
||||||
let init_set c k v = Raw_context.init_set c k v >>= return in
|
let init_set c k v = Raw_context.init_set c k v >>= return in
|
||||||
@ -798,20 +786,17 @@ module Make_indexed_subcontext (C : Raw_context.T) (I : INDEX)
|
|||||||
consume_write_gas init_set (pack s i) v >>=? fun (c, bytes) ->
|
consume_write_gas init_set (pack s i) v >>=? fun (c, bytes) ->
|
||||||
init_set c data_name bytes >>=? fun c ->
|
init_set c data_name bytes >>=? fun c ->
|
||||||
let size_diff = MBytes.length bytes - prev_size in
|
let size_diff = MBytes.length bytes - prev_size in
|
||||||
Lwt.return (Raw_context.record_bytes_stored c (Z.of_int size_diff)) >>=? fun c ->
|
|
||||||
return (Raw_context.project c, size_diff)
|
return (Raw_context.project c, size_diff)
|
||||||
let remove s i =
|
let remove s i =
|
||||||
let remove c k = Raw_context.remove c k >>= return in
|
let remove c k = Raw_context.remove c k >>= return in
|
||||||
existing_size (pack s i) >>=? fun prev_size ->
|
existing_size (pack s i) >>=? fun prev_size ->
|
||||||
consume_remove_gas remove (pack s i) >>=? fun c ->
|
consume_remove_gas remove (pack s i) >>=? fun c ->
|
||||||
remove c data_name >>=? fun c ->
|
remove c data_name >>=? fun c ->
|
||||||
Lwt.return (Raw_context.record_bytes_stored c (Z.of_int ~-prev_size)) >>=? fun c ->
|
|
||||||
return (Raw_context.project c, prev_size)
|
return (Raw_context.project c, prev_size)
|
||||||
let delete s i =
|
let delete s i =
|
||||||
existing_size (pack s i) >>=? fun prev_size ->
|
existing_size (pack s i) >>=? fun prev_size ->
|
||||||
consume_remove_gas Raw_context.delete (pack s i) >>=? fun c ->
|
consume_remove_gas Raw_context.delete (pack s i) >>=? fun c ->
|
||||||
Raw_context.delete c data_name >>=? fun c ->
|
Raw_context.delete c data_name >>=? fun c ->
|
||||||
Lwt.return (Raw_context.record_bytes_stored c (Z.of_int ~-prev_size)) >>=? fun c ->
|
|
||||||
return (Raw_context.project c, prev_size)
|
return (Raw_context.project c, prev_size)
|
||||||
let set_option s i v =
|
let set_option s i v =
|
||||||
match v with
|
match v with
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
(**************************************************************************)
|
|
||||||
(* *)
|
|
||||||
(* Copyright (c) 2014 - 2016. *)
|
|
||||||
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
||||||
(* *)
|
|
||||||
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
||||||
(* *)
|
|
||||||
(**************************************************************************)
|
|
||||||
|
|
||||||
type t =
|
|
||||||
| Unaccounted
|
|
||||||
| Limited of { remaining : Z.t }
|
|
||||||
|
|
||||||
type error += Block_quota_exceeded (* `Temporary *)
|
|
||||||
type error += Operation_quota_exceeded (* `Temporary *)
|
|
||||||
|
|
||||||
let () =
|
|
||||||
let open Data_encoding in
|
|
||||||
register_error_kind
|
|
||||||
`Temporary
|
|
||||||
~id:"storage_exhausted.operation"
|
|
||||||
~title: "Storage quota exceeded for the operation"
|
|
||||||
~description:
|
|
||||||
"A script or one of its callee wrote more \
|
|
||||||
bytes than the operation said it would"
|
|
||||||
empty
|
|
||||||
(function Operation_quota_exceeded -> Some () | _ -> None)
|
|
||||||
(fun () -> Operation_quota_exceeded) ;
|
|
||||||
register_error_kind
|
|
||||||
`Temporary
|
|
||||||
~id:"storage_exhausted.block"
|
|
||||||
~title: "Storage quota exceeded for the block"
|
|
||||||
~description:
|
|
||||||
"The sum of storage consumed by all the operations in the block \
|
|
||||||
exceeds the hard storage limit per block"
|
|
||||||
empty
|
|
||||||
(function Block_quota_exceeded -> Some () | _ -> None)
|
|
||||||
(fun () -> Block_quota_exceeded)
|
|
||||||
|
|
||||||
let consume block_storage operation_storage ~bytes = match operation_storage with
|
|
||||||
| Unaccounted -> ok (block_storage, Unaccounted)
|
|
||||||
| Limited { remaining } ->
|
|
||||||
let remaining =
|
|
||||||
Z.sub remaining bytes in
|
|
||||||
let block_remaining =
|
|
||||||
Z.sub block_storage bytes in
|
|
||||||
if Compare.Z.(remaining < Z.zero)
|
|
||||||
then error Operation_quota_exceeded
|
|
||||||
else if Compare.Z.(block_remaining < Z.zero)
|
|
||||||
then error Block_quota_exceeded
|
|
||||||
else ok (block_remaining, Limited { remaining })
|
|
@ -1,17 +0,0 @@
|
|||||||
(**************************************************************************)
|
|
||||||
(* *)
|
|
||||||
(* Copyright (c) 2014 - 2016. *)
|
|
||||||
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
||||||
(* *)
|
|
||||||
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
||||||
(* *)
|
|
||||||
(**************************************************************************)
|
|
||||||
|
|
||||||
type t =
|
|
||||||
| Unaccounted
|
|
||||||
| Limited of { remaining : Z.t }
|
|
||||||
|
|
||||||
type error += Block_quota_exceeded (* `Temporary *)
|
|
||||||
type error += Operation_quota_exceeded (* `Temporary *)
|
|
||||||
|
|
||||||
val consume : Z.t -> t -> bytes:Z.t -> (Z.t * t) tzresult
|
|
@ -233,7 +233,6 @@ let genesis
|
|||||||
?(endorsement_reward = Constants_repr.default.endorsement_reward)
|
?(endorsement_reward = Constants_repr.default.endorsement_reward)
|
||||||
?(cost_per_byte = Constants_repr.default.cost_per_byte)
|
?(cost_per_byte = Constants_repr.default.cost_per_byte)
|
||||||
?(hard_storage_limit_per_operation = Constants_repr.default.hard_storage_limit_per_operation)
|
?(hard_storage_limit_per_operation = Constants_repr.default.hard_storage_limit_per_operation)
|
||||||
?(hard_storage_limit_per_block = Constants_repr.default.hard_storage_limit_per_block)
|
|
||||||
?(commitments = [])
|
?(commitments = [])
|
||||||
?(security_deposit_ramp_up_cycles = None)
|
?(security_deposit_ramp_up_cycles = None)
|
||||||
?(no_reward_cycles = None)
|
?(no_reward_cycles = None)
|
||||||
@ -278,7 +277,6 @@ let genesis
|
|||||||
endorsement_reward ;
|
endorsement_reward ;
|
||||||
cost_per_byte ;
|
cost_per_byte ;
|
||||||
hard_storage_limit_per_operation ;
|
hard_storage_limit_per_operation ;
|
||||||
hard_storage_limit_per_block ;
|
|
||||||
} in
|
} in
|
||||||
check_constants_consistency constants >>=? fun () ->
|
check_constants_consistency constants >>=? fun () ->
|
||||||
|
|
||||||
|
@ -95,7 +95,6 @@ val genesis:
|
|||||||
?endorsement_reward:Tez_repr.tez ->
|
?endorsement_reward:Tez_repr.tez ->
|
||||||
?cost_per_byte: Tez_repr.t ->
|
?cost_per_byte: Tez_repr.t ->
|
||||||
?hard_storage_limit_per_operation: Z.t ->
|
?hard_storage_limit_per_operation: Z.t ->
|
||||||
?hard_storage_limit_per_block: Z.t ->
|
|
||||||
?commitments:Commitment_repr.t list ->
|
?commitments:Commitment_repr.t list ->
|
||||||
?security_deposit_ramp_up_cycles: int option ->
|
?security_deposit_ramp_up_cycles: int option ->
|
||||||
?no_reward_cycles: int option ->
|
?no_reward_cycles: int option ->
|
||||||
|
Loading…
Reference in New Issue
Block a user