Alpha: add storage limits
This commit is contained in:
parent
dd9cd8a1c3
commit
23f9949e70
@ -163,6 +163,20 @@ let gas_limit_arg =
|
|||||||
return v
|
return v
|
||||||
with _ -> failwith "invalid gas limit (must be a positive number)"))
|
with _ -> failwith "invalid gas limit (must be a positive number)"))
|
||||||
|
|
||||||
|
let storage_limit_arg =
|
||||||
|
arg
|
||||||
|
~long:"storage-limit"
|
||||||
|
~short:'S'
|
||||||
|
~placeholder:"amount"
|
||||||
|
~doc:"Set the storage limit of the transaction instead \
|
||||||
|
of letting the client decide based on a simulation"
|
||||||
|
(parameter (fun _ s ->
|
||||||
|
try
|
||||||
|
let v = Int64.of_string s in
|
||||||
|
assert Compare.Int64.(v >= 0L) ;
|
||||||
|
return v
|
||||||
|
with _ -> failwith "invalid storage limit (must be a positive number of bytes)"))
|
||||||
|
|
||||||
let max_priority_arg =
|
let max_priority_arg =
|
||||||
arg
|
arg
|
||||||
~long:"max-priority"
|
~long:"max-priority"
|
||||||
|
@ -15,6 +15,7 @@ val tez_sym: string
|
|||||||
val init_arg: (string, Proto_alpha.full) Clic.arg
|
val init_arg: (string, Proto_alpha.full) Clic.arg
|
||||||
val fee_arg: (Tez.t, Proto_alpha.full) Clic.arg
|
val fee_arg: (Tez.t, Proto_alpha.full) Clic.arg
|
||||||
val gas_limit_arg: (Z.t option, Proto_alpha.full) Clic.arg
|
val gas_limit_arg: (Z.t option, Proto_alpha.full) Clic.arg
|
||||||
|
val storage_limit_arg: (Int64.t option, Proto_alpha.full) Clic.arg
|
||||||
val arg_arg: (string, Proto_alpha.full) Clic.arg
|
val arg_arg: (string, Proto_alpha.full) Clic.arg
|
||||||
val source_arg: (string option, Proto_alpha.full) Clic.arg
|
val source_arg: (string option, Proto_alpha.full) Clic.arg
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ let append_reveal
|
|||||||
let transfer (cctxt : #Proto_alpha.full)
|
let transfer (cctxt : #Proto_alpha.full)
|
||||||
block ?confirmations
|
block ?confirmations
|
||||||
?branch ~source ~src_pk ~src_sk ~destination ?arg
|
?branch ~source ~src_pk ~src_sk ~destination ?arg
|
||||||
~amount ~fee ?(gas_limit = Z.minus_one) () =
|
~amount ~fee ?(gas_limit = Z.minus_one) ?(storage_limit = -1L) () =
|
||||||
begin match arg with
|
begin match arg with
|
||||||
| Some arg ->
|
| Some arg ->
|
||||||
parse_expression arg >>=? fun { expanded = arg } ->
|
parse_expression arg >>=? fun { expanded = arg } ->
|
||||||
@ -54,7 +54,7 @@ let transfer (cctxt : #Proto_alpha.full)
|
|||||||
let contents =
|
let contents =
|
||||||
Sourced_operation
|
Sourced_operation
|
||||||
(Manager_operations { source ; fee ; counter ;
|
(Manager_operations { source ; fee ; counter ;
|
||||||
gas_limit ; operations }) in
|
gas_limit ; storage_limit ; operations }) in
|
||||||
Injection.inject_operation cctxt block ?confirmations
|
Injection.inject_operation cctxt block ?confirmations
|
||||||
?branch ~src_sk contents >>=? fun (_oph, _op, result as res) ->
|
?branch ~src_sk contents >>=? fun (_oph, _op, result as res) ->
|
||||||
Lwt.return (Injection.originated_contracts result) >>=? fun contracts ->
|
Lwt.return (Injection.originated_contracts result) >>=? fun contracts ->
|
||||||
@ -70,18 +70,19 @@ let reveal cctxt
|
|||||||
| [] ->
|
| [] ->
|
||||||
failwith "The manager key was previously revealed."
|
failwith "The manager key was previously revealed."
|
||||||
| _ :: _ ->
|
| _ :: _ ->
|
||||||
let gas_limit = Z.zero in
|
|
||||||
let contents =
|
let contents =
|
||||||
Sourced_operation
|
Sourced_operation
|
||||||
(Manager_operations { source ; fee ; counter ;
|
(Manager_operations { source ; fee ; counter ;
|
||||||
gas_limit ; operations }) in
|
gas_limit = Z.zero ; storage_limit = 0L ;
|
||||||
|
operations }) in
|
||||||
Injection.inject_operation cctxt block ?confirmations
|
Injection.inject_operation cctxt block ?confirmations
|
||||||
?branch ~src_sk contents >>=? fun res ->
|
?branch ~src_sk contents >>=? fun res ->
|
||||||
return res
|
return res
|
||||||
|
|
||||||
let originate
|
let originate
|
||||||
cctxt block ?confirmations
|
cctxt block ?confirmations
|
||||||
?branch ~source ~src_pk ~src_sk ~fee ?(gas_limit = Z.minus_one) origination =
|
?branch ~source ~src_pk ~src_sk ~fee
|
||||||
|
?(gas_limit = Z.minus_one) ?(storage_limit = -1L) origination =
|
||||||
Alpha_services.Contract.counter cctxt block source >>=? fun pcounter ->
|
Alpha_services.Contract.counter cctxt block source >>=? fun pcounter ->
|
||||||
let counter = Int32.succ pcounter in
|
let counter = Int32.succ pcounter in
|
||||||
let operations = [origination] in
|
let operations = [origination] in
|
||||||
@ -90,7 +91,7 @@ let originate
|
|||||||
let contents =
|
let contents =
|
||||||
Sourced_operation
|
Sourced_operation
|
||||||
(Manager_operations { source ; fee ; counter ;
|
(Manager_operations { source ; fee ; counter ;
|
||||||
gas_limit ; operations }) in
|
gas_limit ; storage_limit ; operations }) in
|
||||||
Injection.inject_operation cctxt block ?confirmations
|
Injection.inject_operation cctxt block ?confirmations
|
||||||
?branch ~src_sk contents >>=? fun (_oph, _op, result as res) ->
|
?branch ~src_sk contents >>=? fun (_oph, _op, result as res) ->
|
||||||
Lwt.return (Injection.originated_contracts result) >>=? function
|
Lwt.return (Injection.originated_contracts result) >>=? function
|
||||||
@ -129,7 +130,8 @@ let delegate_contract cctxt
|
|||||||
let contents =
|
let contents =
|
||||||
Sourced_operation
|
Sourced_operation
|
||||||
(Manager_operations { source ; fee ; counter ;
|
(Manager_operations { source ; fee ; counter ;
|
||||||
gas_limit = Z.zero ; operations }) in
|
gas_limit = Z.zero ; storage_limit = 0L ;
|
||||||
|
operations }) in
|
||||||
Injection.inject_operation cctxt block ?confirmations
|
Injection.inject_operation cctxt block ?confirmations
|
||||||
?branch ~src_sk contents >>=? fun res ->
|
?branch ~src_sk contents >>=? fun res ->
|
||||||
return res
|
return res
|
||||||
@ -204,6 +206,7 @@ let originate_contract
|
|||||||
block ?confirmations ?branch
|
block ?confirmations ?branch
|
||||||
~fee
|
~fee
|
||||||
?gas_limit
|
?gas_limit
|
||||||
|
?storage_limit
|
||||||
~delegate
|
~delegate
|
||||||
?(delegatable=true)
|
?(delegatable=true)
|
||||||
?(spendable=false)
|
?(spendable=false)
|
||||||
@ -227,7 +230,7 @@ let originate_contract
|
|||||||
credit = balance ;
|
credit = balance ;
|
||||||
preorigination = None } in
|
preorigination = None } in
|
||||||
originate cctxt block ?confirmations
|
originate cctxt block ?confirmations
|
||||||
?branch ~source ~src_pk ~src_sk ~fee ?gas_limit origination
|
?branch ~source ~src_pk ~src_sk ~fee ?gas_limit ?storage_limit origination
|
||||||
|
|
||||||
type activation_key =
|
type activation_key =
|
||||||
{ pkh : Ed25519.Public_key_hash.t ;
|
{ pkh : Ed25519.Public_key_hash.t ;
|
||||||
|
@ -89,6 +89,7 @@ val originate_contract:
|
|||||||
?branch:int ->
|
?branch:int ->
|
||||||
fee:Tez.t ->
|
fee:Tez.t ->
|
||||||
?gas_limit:Z.t ->
|
?gas_limit:Z.t ->
|
||||||
|
?storage_limit:Int64.t ->
|
||||||
delegate:public_key_hash option ->
|
delegate:public_key_hash option ->
|
||||||
?delegatable:bool ->
|
?delegatable:bool ->
|
||||||
?spendable:bool ->
|
?spendable:bool ->
|
||||||
@ -114,6 +115,7 @@ val transfer :
|
|||||||
amount:Tez.t ->
|
amount:Tez.t ->
|
||||||
fee:Tez.t ->
|
fee:Tez.t ->
|
||||||
?gas_limit:Z.t ->
|
?gas_limit:Z.t ->
|
||||||
|
?storage_limit:Int64.t ->
|
||||||
unit ->
|
unit ->
|
||||||
(Injection.result * Contract.t list) tzresult Lwt.t
|
(Injection.result * Contract.t list) tzresult Lwt.t
|
||||||
|
|
||||||
|
@ -72,6 +72,22 @@ let estimated_gas = function
|
|||||||
(Ok Z.zero) operation_results
|
(Ok Z.zero) operation_results
|
||||||
| _ -> Ok Z.zero
|
| _ -> Ok Z.zero
|
||||||
|
|
||||||
|
let estimated_storage = function
|
||||||
|
| Sourced_operation_result (Manager_operations_result { operation_results }) ->
|
||||||
|
List.fold_left
|
||||||
|
(fun acc (_, r) -> acc >>? fun acc ->
|
||||||
|
match r with
|
||||||
|
| Applied (Transaction_result { storage_size_diff }
|
||||||
|
| Origination_result { storage_size_diff }) ->
|
||||||
|
Ok (Int64.add storage_size_diff acc)
|
||||||
|
| Applied Reveal_result -> Ok acc
|
||||||
|
| Applied Delegation_result -> Ok acc
|
||||||
|
| Skipped -> assert false
|
||||||
|
| Failed errs -> Alpha_environment.wrap_error (Error errs))
|
||||||
|
(Ok 0L) operation_results >>? fun diff ->
|
||||||
|
Ok (max 0L diff)
|
||||||
|
| _ -> Ok 0L
|
||||||
|
|
||||||
let originated_contracts = function
|
let originated_contracts = function
|
||||||
| Sourced_operation_result (Manager_operations_result { operation_results }) ->
|
| Sourced_operation_result (Manager_operations_result { operation_results }) ->
|
||||||
List.fold_left
|
List.fold_left
|
||||||
@ -87,34 +103,53 @@ let originated_contracts = function
|
|||||||
(Ok []) operation_results
|
(Ok []) operation_results
|
||||||
| _ -> Ok []
|
| _ -> Ok []
|
||||||
|
|
||||||
let may_patch_gas_limit
|
let may_patch_limits
|
||||||
(cctxt : #Proto_alpha.full) block ?branch
|
(cctxt : #Proto_alpha.full) block ?branch
|
||||||
?src_sk contents =
|
?src_sk contents =
|
||||||
Alpha_services.Constants.hard_gas_limits cctxt block >>=? fun (_, gas_limit) ->
|
Alpha_services.Constants.hard_gas_limits cctxt block >>=? fun (_, gas_limit) ->
|
||||||
|
Alpha_services.Constants.hard_storage_limits cctxt block >>=? fun (_, storage_limit) ->
|
||||||
match contents with
|
match contents with
|
||||||
| Sourced_operation (Manager_operations c)
|
| Sourced_operation (Manager_operations c)
|
||||||
when c.gas_limit < Z.zero || gas_limit < c.gas_limit ->
|
when c.gas_limit < Z.zero || gas_limit < c.gas_limit
|
||||||
|
|| c.storage_limit < 0L || storage_limit < c.storage_limit ->
|
||||||
let contents =
|
let contents =
|
||||||
Sourced_operation (Manager_operations { c with gas_limit }) in
|
Sourced_operation (Manager_operations { c with gas_limit ; storage_limit }) in
|
||||||
preapply cctxt block ?branch ?src_sk contents >>=? fun (_, _, result) ->
|
preapply cctxt block ?branch ?src_sk contents >>=? fun (_, _, result) ->
|
||||||
Lwt.return (estimated_gas result) >>=? fun gas ->
|
begin if c.gas_limit < Z.zero || gas_limit < c.gas_limit then
|
||||||
begin
|
Lwt.return (estimated_gas result) >>=? fun gas ->
|
||||||
if Z.equal gas Z.zero then
|
begin
|
||||||
cctxt#message "Estimated gas: none" >>= fun () ->
|
if Z.equal gas Z.zero then
|
||||||
return Z.zero
|
cctxt#message "Estimated gas: none" >>= fun () ->
|
||||||
else
|
return Z.zero
|
||||||
cctxt#message
|
else
|
||||||
"Estimated gas: %s units (will add 100 for safety)"
|
cctxt#message
|
||||||
(Z.to_string gas) >>= fun () ->
|
"Estimated gas: %s units (will add 100 for safety)"
|
||||||
return (Z.add gas (Z.of_int 100))
|
(Z.to_string gas) >>= fun () ->
|
||||||
|
return (Z.add gas (Z.of_int 100))
|
||||||
|
end
|
||||||
|
else return c.gas_limit
|
||||||
end >>=? fun gas_limit ->
|
end >>=? fun gas_limit ->
|
||||||
return (Sourced_operation (Manager_operations { c with gas_limit }))
|
begin if c.storage_limit < 0L || storage_limit < c.storage_limit then
|
||||||
|
Lwt.return (estimated_storage result) >>=? fun storage ->
|
||||||
|
begin
|
||||||
|
if Int64.equal storage 0L then
|
||||||
|
cctxt#message "Estimated storage: no bytes added" >>= fun () ->
|
||||||
|
return 0L
|
||||||
|
else
|
||||||
|
cctxt#message
|
||||||
|
"Estimated storage: %Ld bytes added (will add 20 for safety)"
|
||||||
|
storage >>= fun () ->
|
||||||
|
return (Int64.add storage 20L)
|
||||||
|
end
|
||||||
|
else return c.storage_limit
|
||||||
|
end >>=? fun storage_limit ->
|
||||||
|
return (Sourced_operation (Manager_operations { c with gas_limit ; storage_limit }))
|
||||||
| op -> return op
|
| op -> return op
|
||||||
|
|
||||||
let inject_operation
|
let inject_operation
|
||||||
cctxt block
|
cctxt block
|
||||||
?confirmations ?branch ?src_sk contents =
|
?confirmations ?branch ?src_sk contents =
|
||||||
may_patch_gas_limit
|
may_patch_limits
|
||||||
cctxt block ?branch ?src_sk contents >>=? fun contents ->
|
cctxt block ?branch ?src_sk contents >>=? fun contents ->
|
||||||
preapply cctxt block
|
preapply cctxt block
|
||||||
?branch ?src_sk contents >>=? fun (_oph, op, result) ->
|
?branch ?src_sk contents >>=? fun (_oph, op, result) ->
|
||||||
|
@ -204,9 +204,14 @@ let report_errors ~details ~show_source ?parsed ppf errs =
|
|||||||
print_source (parsed, hilights) ;
|
print_source (parsed, hilights) ;
|
||||||
if rest <> [] then Format.fprintf ppf "@," ;
|
if rest <> [] then Format.fprintf ppf "@," ;
|
||||||
print_trace (parsed_locations parsed) rest
|
print_trace (parsed_locations parsed) rest
|
||||||
|
| Alpha_environment.Ecoproto_error Gas.Gas_limit_too_high :: rest ->
|
||||||
|
Format.fprintf ppf
|
||||||
|
"Gas 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 Gas.Block_quota_exceeded :: rest ->
|
| Alpha_environment.Ecoproto_error Gas.Block_quota_exceeded :: rest ->
|
||||||
Format.fprintf ppf
|
Format.fprintf ppf
|
||||||
"@[<v 0>Gas limit for the block exceeded during typechecking or execution.@]" ;
|
"Gas limit for the block exceeded during typechecking or execution." ;
|
||||||
if rest <> [] then Format.fprintf ppf "@," ;
|
if rest <> [] then Format.fprintf ppf "@," ;
|
||||||
print_trace locations rest
|
print_trace locations rest
|
||||||
| Alpha_environment.Ecoproto_error Gas.Operation_quota_exceeded :: rest ->
|
| Alpha_environment.Ecoproto_error Gas.Operation_quota_exceeded :: rest ->
|
||||||
@ -214,6 +219,21 @@ 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 ->
|
||||||
|
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
|
||||||
|
"@[<v 0>Storage limit exceeded during typechecking or execution.@,Try again with a higher storage limit.@]" ;
|
||||||
|
if rest <> [] then Format.fprintf ppf "@," ;
|
||||||
|
print_trace locations rest
|
||||||
| Alpha_environment.Ecoproto_error err :: rest ->
|
| Alpha_environment.Ecoproto_error err :: rest ->
|
||||||
begin match err with
|
begin match err with
|
||||||
| Apply.Bad_contract_parameter (c, None, _) ->
|
| Apply.Bad_contract_parameter (c, None, _) ->
|
||||||
|
@ -229,7 +229,7 @@ let pp_operation_result ppf ({ contents ; _ }, operation_result) =
|
|||||||
"@[<v 2>Dictator test protocol activation:@,\
|
"@[<v 2>Dictator test protocol activation:@,\
|
||||||
Protocol: %a@]"
|
Protocol: %a@]"
|
||||||
Protocol_hash.pp protocol
|
Protocol_hash.pp protocol
|
||||||
| Sourced_operation (Manager_operations { source ; fee ; counter ; operations ; gas_limit }),
|
| Sourced_operation (Manager_operations { source ; fee ; counter ; operations ; gas_limit ; storage_limit }),
|
||||||
Sourced_operation_result (Manager_operations_result { balance_updates ; operation_results }) ->
|
Sourced_operation_result (Manager_operations_result { balance_updates ; operation_results }) ->
|
||||||
let pp_result ppf result =
|
let pp_result ppf result =
|
||||||
Format.fprintf ppf "@," ;
|
Format.fprintf ppf "@," ;
|
||||||
@ -237,10 +237,9 @@ let pp_operation_result ppf ({ contents ; _ }, operation_result) =
|
|||||||
| Skipped ->
|
| Skipped ->
|
||||||
Format.fprintf ppf
|
Format.fprintf ppf
|
||||||
"This operation was skipped"
|
"This operation was skipped"
|
||||||
| Failed errs ->
|
| Failed _errs ->
|
||||||
Format.fprintf ppf
|
Format.fprintf ppf
|
||||||
"@[<v 2>This operation FAILED with the folllowing error:@,%a@]"
|
"This operation FAILED."
|
||||||
(Format.pp_print_list Alpha_environment.Error_monad.pp) errs
|
|
||||||
| Applied Reveal_result ->
|
| Applied Reveal_result ->
|
||||||
Format.fprintf ppf
|
Format.fprintf ppf
|
||||||
"This revelation was successfully applied"
|
"This revelation was successfully applied"
|
||||||
@ -325,12 +324,14 @@ let pp_operation_result ppf ({ contents ; _ }, operation_result) =
|
|||||||
From: %a@,\
|
From: %a@,\
|
||||||
Fee to the baker: %s%a@,\
|
Fee to the baker: %s%a@,\
|
||||||
Expected counter: %ld@,\
|
Expected counter: %ld@,\
|
||||||
Gas limit: %s"
|
Gas limit: %s@,\
|
||||||
|
Storage limit: %Ld bytes"
|
||||||
Contract.pp source
|
Contract.pp source
|
||||||
Client_proto_args.tez_sym
|
Client_proto_args.tez_sym
|
||||||
Tez.pp fee
|
Tez.pp fee
|
||||||
counter
|
counter
|
||||||
(Z.to_string gas_limit) ;
|
(Z.to_string gas_limit)
|
||||||
|
storage_limit ;
|
||||||
begin match balance_updates with
|
begin match balance_updates with
|
||||||
| [] -> ()
|
| [] -> ()
|
||||||
| balance_updates ->
|
| balance_updates ->
|
||||||
|
@ -197,8 +197,8 @@ let commands () =
|
|||||||
end ;
|
end ;
|
||||||
|
|
||||||
command ~group ~desc: "Launch a smart contract on the blockchain."
|
command ~group ~desc: "Launch a smart contract on the blockchain."
|
||||||
(args8
|
(args9
|
||||||
fee_arg gas_limit_arg delegate_arg (Client_keys.force_switch ())
|
fee_arg gas_limit_arg storage_limit_arg delegate_arg (Client_keys.force_switch ())
|
||||||
delegatable_switch spendable_switch init_arg no_print_source_flag)
|
delegatable_switch spendable_switch init_arg no_print_source_flag)
|
||||||
(prefixes [ "originate" ; "contract" ]
|
(prefixes [ "originate" ; "contract" ]
|
||||||
@@ RawContractAlias.fresh_alias_param
|
@@ RawContractAlias.fresh_alias_param
|
||||||
@ -217,13 +217,13 @@ let commands () =
|
|||||||
~name:"prg" ~desc: "script of the account\n\
|
~name:"prg" ~desc: "script of the account\n\
|
||||||
Combine with -init if the storage type is not unit."
|
Combine with -init if the storage type is not unit."
|
||||||
@@ stop)
|
@@ stop)
|
||||||
begin fun (fee, gas_limit, delegate, force, delegatable, spendable, initial_storage, no_print_source)
|
begin fun (fee, gas_limit, storage_limit, delegate, force, delegatable, spendable, initial_storage, no_print_source)
|
||||||
alias_name manager balance (_, source) program (cctxt : Proto_alpha.full) ->
|
alias_name manager balance (_, source) program (cctxt : Proto_alpha.full) ->
|
||||||
RawContractAlias.of_fresh cctxt force alias_name >>=? fun alias_name ->
|
RawContractAlias.of_fresh cctxt force alias_name >>=? fun alias_name ->
|
||||||
Lwt.return (Micheline_parser.no_parsing_error program) >>=? fun { expanded = code } ->
|
Lwt.return (Micheline_parser.no_parsing_error program) >>=? fun { expanded = code } ->
|
||||||
source_to_keys cctxt cctxt#block source >>=? fun (src_pk, src_sk) ->
|
source_to_keys cctxt cctxt#block source >>=? fun (src_pk, src_sk) ->
|
||||||
originate_contract cctxt cctxt#block ?confirmations:cctxt#confirmations
|
originate_contract cctxt cctxt#block ?confirmations:cctxt#confirmations
|
||||||
~fee ?gas_limit ~delegate ~delegatable ~spendable ~initial_storage
|
~fee ?gas_limit ?storage_limit ~delegate ~delegatable ~spendable ~initial_storage
|
||||||
~manager ~balance ~source ~src_pk ~src_sk ~code () >>= fun errors ->
|
~manager ~balance ~source ~src_pk ~src_sk ~code () >>= fun errors ->
|
||||||
report_michelson_errors ~no_print_source ~msg:"origination simulation failed" cctxt errors >>= function
|
report_michelson_errors ~no_print_source ~msg:"origination simulation failed" cctxt errors >>= function
|
||||||
| None -> return ()
|
| None -> return ()
|
||||||
@ -233,7 +233,7 @@ let commands () =
|
|||||||
end ;
|
end ;
|
||||||
|
|
||||||
command ~group ~desc: "Transfer tokens / call a smart contract."
|
command ~group ~desc: "Transfer tokens / call a smart contract."
|
||||||
(args4 fee_arg gas_limit_arg arg_arg no_print_source_flag)
|
(args5 fee_arg gas_limit_arg storage_limit_arg arg_arg no_print_source_flag)
|
||||||
(prefixes [ "transfer" ]
|
(prefixes [ "transfer" ]
|
||||||
@@ tez_param
|
@@ tez_param
|
||||||
~name: "qty" ~desc: "amount taken from source"
|
~name: "qty" ~desc: "amount taken from source"
|
||||||
@ -244,10 +244,10 @@ let commands () =
|
|||||||
@@ ContractAlias.destination_param
|
@@ ContractAlias.destination_param
|
||||||
~name: "dst" ~desc: "name/literal of the destination contract"
|
~name: "dst" ~desc: "name/literal of the destination contract"
|
||||||
@@ stop)
|
@@ stop)
|
||||||
begin fun (fee, gas_limit, arg, no_print_source) amount (_, source) (_, destination) cctxt ->
|
begin fun (fee, gas_limit, storage_limit, arg, no_print_source) amount (_, source) (_, destination) cctxt ->
|
||||||
source_to_keys cctxt cctxt#block source >>=? fun (src_pk, src_sk) ->
|
source_to_keys cctxt cctxt#block source >>=? fun (src_pk, src_sk) ->
|
||||||
transfer cctxt cctxt#block ?confirmations:cctxt#confirmations
|
transfer cctxt cctxt#block ?confirmations:cctxt#confirmations
|
||||||
~source ~fee ~src_pk ~src_sk ~destination ~arg ~amount ?gas_limit () >>=
|
~source ~fee ~src_pk ~src_sk ~destination ~arg ~amount ?gas_limit ?storage_limit () >>=
|
||||||
report_michelson_errors ~no_print_source ~msg:"transfer simulation failed" cctxt >>= function
|
report_michelson_errors ~no_print_source ~msg:"transfer simulation failed" cctxt >>= function
|
||||||
| None -> return ()
|
| None -> return ()
|
||||||
| Some (_res, _contracts) ->
|
| Some (_res, _contracts) ->
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
"Cycle_repr",
|
"Cycle_repr",
|
||||||
"Level_repr",
|
"Level_repr",
|
||||||
"Seed_repr",
|
"Seed_repr",
|
||||||
"Gas_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",
|
||||||
|
@ -62,7 +62,8 @@ end
|
|||||||
module Voting_period = Voting_period_repr
|
module Voting_period = Voting_period_repr
|
||||||
|
|
||||||
module Gas = struct
|
module Gas = struct
|
||||||
include Gas_repr
|
include Gas_limit_repr
|
||||||
|
type error += Gas_limit_too_high = Raw_context.Gas_limit_too_high
|
||||||
let set_limit = Raw_context.set_gas_limit
|
let set_limit = Raw_context.set_gas_limit
|
||||||
let set_unlimited = Raw_context.set_gas_unlimited
|
let set_unlimited = Raw_context.set_gas_unlimited
|
||||||
let consume = Raw_context.consume_gas
|
let consume = Raw_context.consume_gas
|
||||||
@ -78,6 +79,11 @@ module Contract = struct
|
|||||||
include Contract_storage
|
include Contract_storage
|
||||||
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
|
||||||
|
@ -121,6 +121,7 @@ module Gas : sig
|
|||||||
|
|
||||||
type error += Block_quota_exceeded (* `Temporary *)
|
type error += Block_quota_exceeded (* `Temporary *)
|
||||||
type error += Operation_quota_exceeded (* `Temporary *)
|
type error += Operation_quota_exceeded (* `Temporary *)
|
||||||
|
type error += Gas_limit_too_high (* `Permanent *)
|
||||||
|
|
||||||
val free : cost
|
val free : cost
|
||||||
val step_cost : int -> cost
|
val step_cost : int -> cost
|
||||||
@ -323,6 +324,8 @@ module Constants : sig
|
|||||||
block_reward: Tez.t ;
|
block_reward: Tez.t ;
|
||||||
endorsement_reward: Tez.t ;
|
endorsement_reward: Tez.t ;
|
||||||
cost_per_byte: Tez.t ;
|
cost_per_byte: Tez.t ;
|
||||||
|
hard_storage_limit_per_operation: Int64.t ;
|
||||||
|
hard_storage_limit_per_block: Int64.t ;
|
||||||
}
|
}
|
||||||
val parametric_encoding: parametric Data_encoding.t
|
val parametric_encoding: parametric Data_encoding.t
|
||||||
val parametric: context -> parametric
|
val parametric: context -> parametric
|
||||||
@ -338,6 +341,8 @@ module Constants : sig
|
|||||||
val hard_gas_limit_per_operation: context -> Z.t
|
val hard_gas_limit_per_operation: context -> Z.t
|
||||||
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 -> Int64.t
|
||||||
|
val hard_storage_limit_per_block: context -> Int64.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 max_operation_data_length: context -> int
|
val max_operation_data_length: context -> int
|
||||||
@ -542,6 +547,13 @@ 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 -> Int64.t -> context tzresult
|
||||||
|
val set_storage_unlimited: context -> context
|
||||||
|
|
||||||
val used_storage_space: context -> t -> Int64.t tzresult Lwt.t
|
val used_storage_space: context -> t -> Int64.t tzresult Lwt.t
|
||||||
val paid_storage_space_fees: context -> t -> Tez.t tzresult Lwt.t
|
val paid_storage_space_fees: context -> t -> Tez.t tzresult Lwt.t
|
||||||
val pay_for_storage_space: context -> t -> Tez.t -> context tzresult Lwt.t
|
val pay_for_storage_space: context -> t -> Tez.t -> context tzresult Lwt.t
|
||||||
@ -750,6 +762,7 @@ and sourced_operation =
|
|||||||
counter: counter ;
|
counter: counter ;
|
||||||
operations: manager_operation list ;
|
operations: manager_operation list ;
|
||||||
gas_limit: Z.t ;
|
gas_limit: Z.t ;
|
||||||
|
storage_limit: Int64.t;
|
||||||
}
|
}
|
||||||
| Dictator_operation of dictator_operation
|
| Dictator_operation of dictator_operation
|
||||||
|
|
||||||
|
@ -542,7 +542,7 @@ let apply_manager_operations ctxt source ops =
|
|||||||
|
|
||||||
let apply_sourced_operation ctxt pred_block operation ops =
|
let apply_sourced_operation ctxt pred_block operation ops =
|
||||||
match ops with
|
match ops with
|
||||||
| Manager_operations { source ; fee ; counter ; operations ; gas_limit } ->
|
| Manager_operations { source ; fee ; counter ; operations ; gas_limit ; storage_limit } ->
|
||||||
let revealed_public_keys =
|
let revealed_public_keys =
|
||||||
List.fold_left (fun acc op ->
|
List.fold_left (fun acc op ->
|
||||||
match op with
|
match op with
|
||||||
@ -564,6 +564,7 @@ let apply_sourced_operation ctxt pred_block operation ops =
|
|||||||
Contract.spend ctxt source fee >>=? fun ctxt ->
|
Contract.spend ctxt source fee >>=? fun ctxt ->
|
||||||
add_fees ctxt fee >>=? fun ctxt ->
|
add_fees ctxt fee >>=? fun ctxt ->
|
||||||
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 ->
|
||||||
apply_manager_operations ctxt source operations >>= begin function
|
apply_manager_operations ctxt source operations >>= begin function
|
||||||
| Ok (ctxt, operation_results) -> return (ctxt, operation_results)
|
| Ok (ctxt, operation_results) -> return (ctxt, operation_results)
|
||||||
| Error operation_results -> return (ctxt (* backtracked *), operation_results)
|
| Error operation_results -> return (ctxt (* backtracked *), operation_results)
|
||||||
@ -716,6 +717,7 @@ let apply_operation ctxt pred_block hash operation =
|
|||||||
return (ctxt, Sourced_operation_result result)
|
return (ctxt, Sourced_operation_result result)
|
||||||
end >>=? fun (ctxt, result) ->
|
end >>=? 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, result)
|
return (ctxt, result)
|
||||||
|
|
||||||
|
@ -66,6 +66,8 @@ type parametric = {
|
|||||||
block_reward: Tez_repr.t ;
|
block_reward: Tez_repr.t ;
|
||||||
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: Int64.t ;
|
||||||
|
hard_storage_limit_per_block: Int64.t ;
|
||||||
}
|
}
|
||||||
|
|
||||||
let default = {
|
let default = {
|
||||||
@ -100,6 +102,8 @@ let default = {
|
|||||||
endorsement_security_deposit = Tez_repr.(mul_exn one 64) ;
|
endorsement_security_deposit = Tez_repr.(mul_exn one 64) ;
|
||||||
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 = 60_000L ;
|
||||||
|
hard_storage_limit_per_block = 1_000_000L ;
|
||||||
cost_per_byte = Tez_repr.of_mutez_exn 1_000L ;
|
cost_per_byte = Tez_repr.of_mutez_exn 1_000L ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +134,9 @@ let parametric_encoding =
|
|||||||
c.endorsement_security_deposit,
|
c.endorsement_security_deposit,
|
||||||
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_block))) )
|
||||||
(fun (( preserved_cycles,
|
(fun (( preserved_cycles,
|
||||||
blocks_per_cycle,
|
blocks_per_cycle,
|
||||||
blocks_per_commitment,
|
blocks_per_commitment,
|
||||||
@ -152,7 +158,9 @@ let parametric_encoding =
|
|||||||
endorsement_security_deposit,
|
endorsement_security_deposit,
|
||||||
block_reward),
|
block_reward),
|
||||||
(endorsement_reward,
|
(endorsement_reward,
|
||||||
cost_per_byte))) ->
|
cost_per_byte,
|
||||||
|
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 ;
|
||||||
@ -175,6 +183,8 @@ 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_block ;
|
||||||
} )
|
} )
|
||||||
(merge_objs
|
(merge_objs
|
||||||
(obj10
|
(obj10
|
||||||
@ -200,9 +210,11 @@ 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))
|
||||||
(obj2
|
(obj4
|
||||||
(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" int64)
|
||||||
|
(req "hard_storage_limit_per_block" int64))))
|
||||||
|
|
||||||
type t = {
|
type t = {
|
||||||
fixed : fixed ;
|
fixed : fixed ;
|
||||||
|
@ -88,6 +88,14 @@ module S = struct
|
|||||||
~output: (obj2 (req "per_block" z) (req "per_operation" z))
|
~output: (obj2 (req "per_block" z) (req "per_operation" z))
|
||||||
RPC_path.(custom_root / "hard_gas_limits")
|
RPC_path.(custom_root / "hard_gas_limits")
|
||||||
|
|
||||||
|
let hard_storage_limits =
|
||||||
|
RPC_service.post_service
|
||||||
|
~description: "Hard maximum amount of bytes stored per operation and per block"
|
||||||
|
~query: RPC_query.empty
|
||||||
|
~input: empty
|
||||||
|
~output: (obj2 (req "per_block" int64) (req "per_operation" int64))
|
||||||
|
RPC_path.(custom_root / "hard_storage_limits")
|
||||||
|
|
||||||
let cost_per_byte =
|
let cost_per_byte =
|
||||||
RPC_service.post_service
|
RPC_service.post_service
|
||||||
~description: "The cost per bytes added to the storage"
|
~description: "The cost per bytes added to the storage"
|
||||||
@ -201,6 +209,10 @@ let () =
|
|||||||
return (Constants.hard_gas_limit_per_block ctxt,
|
return (Constants.hard_gas_limit_per_block ctxt,
|
||||||
Constants.hard_gas_limit_per_operation ctxt)
|
Constants.hard_gas_limit_per_operation ctxt)
|
||||||
end ;
|
end ;
|
||||||
|
register0 S.hard_storage_limits begin fun ctxt () () ->
|
||||||
|
return (Constants.hard_storage_limit_per_block ctxt,
|
||||||
|
Constants.hard_storage_limit_per_operation ctxt)
|
||||||
|
end ;
|
||||||
register0 S.cost_per_byte begin fun ctxt () () ->
|
register0 S.cost_per_byte begin fun ctxt () () ->
|
||||||
return (Constants.cost_per_byte ctxt)
|
return (Constants.cost_per_byte ctxt)
|
||||||
end ;
|
end ;
|
||||||
@ -254,6 +266,8 @@ let hard_gas_limits ctxt block =
|
|||||||
RPC_context.make_call0 S.hard_gas_limits ctxt block () ()
|
RPC_context.make_call0 S.hard_gas_limits ctxt block () ()
|
||||||
let cost_per_byte ctxt block =
|
let cost_per_byte ctxt block =
|
||||||
RPC_context.make_call0 S.cost_per_byte ctxt block () ()
|
RPC_context.make_call0 S.cost_per_byte ctxt block () ()
|
||||||
|
let hard_storage_limits ctxt block =
|
||||||
|
RPC_context.make_call0 S.hard_storage_limits ctxt block () ()
|
||||||
let proof_of_work_threshold ctxt block =
|
let proof_of_work_threshold ctxt block =
|
||||||
RPC_context.make_call0 S.proof_of_work_threshold ctxt block () ()
|
RPC_context.make_call0 S.proof_of_work_threshold ctxt block () ()
|
||||||
let seed_nonce_revelation_tip ctxt block =
|
let seed_nonce_revelation_tip ctxt block =
|
||||||
|
@ -36,6 +36,8 @@ val endorsers_per_block:
|
|||||||
val hard_gas_limits:
|
val hard_gas_limits:
|
||||||
'a #RPC_context.simple -> 'a -> (Z.t * Z.t) shell_tzresult Lwt.t
|
'a #RPC_context.simple -> 'a -> (Z.t * Z.t) shell_tzresult Lwt.t
|
||||||
|
|
||||||
|
val hard_storage_limits:
|
||||||
|
'a #RPC_context.simple -> 'a -> (Int64.t * Int64.t) shell_tzresult Lwt.t
|
||||||
|
|
||||||
val cost_per_byte:
|
val cost_per_byte:
|
||||||
'a #RPC_context.simple -> 'a -> Tez.t shell_tzresult Lwt.t
|
'a #RPC_context.simple -> 'a -> Tez.t shell_tzresult Lwt.t
|
||||||
|
@ -40,6 +40,12 @@ let hard_gas_limit_per_block c =
|
|||||||
let cost_per_byte c =
|
let cost_per_byte c =
|
||||||
let constants = Raw_context.constants c in
|
let constants = Raw_context.constants c in
|
||||||
constants.cost_per_byte
|
constants.cost_per_byte
|
||||||
|
let hard_storage_limit_per_operation c =
|
||||||
|
let constants = Raw_context.constants c in
|
||||||
|
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
|
||||||
|
@ -89,9 +89,9 @@ let consume block_gas operation_gas cost = match operation_gas with
|
|||||||
Z.sub remaining weighted_cost in
|
Z.sub remaining weighted_cost in
|
||||||
let block_remaining =
|
let block_remaining =
|
||||||
Z.sub block_gas weighted_cost in
|
Z.sub block_gas weighted_cost in
|
||||||
if Compare.Z.(remaining <= Z.zero)
|
if Compare.Z.(remaining < Z.zero)
|
||||||
then error Operation_quota_exceeded
|
then error Operation_quota_exceeded
|
||||||
else if Compare.Z.(block_remaining <= Z.zero)
|
else if Compare.Z.(block_remaining < Z.zero)
|
||||||
then error Block_quota_exceeded
|
then error Block_quota_exceeded
|
||||||
else ok (block_remaining, Limited { remaining })
|
else ok (block_remaining, Limited { remaining })
|
||||||
|
|
@ -300,7 +300,8 @@ module Forge = struct
|
|||||||
module Manager = struct
|
module Manager = struct
|
||||||
|
|
||||||
let operations ctxt
|
let operations ctxt
|
||||||
block ~branch ~source ?sourcePubKey ~counter ~fee ~gas_limit operations =
|
block ~branch ~source ?sourcePubKey ~counter ~fee
|
||||||
|
~gas_limit ~storage_limit operations =
|
||||||
Contract_services.manager_key ctxt block source >>= function
|
Contract_services.manager_key ctxt block source >>= function
|
||||||
| Error _ as e -> Lwt.return e
|
| Error _ as e -> Lwt.return e
|
||||||
| Ok (_, revealed) ->
|
| Ok (_, revealed) ->
|
||||||
@ -313,18 +314,22 @@ module Forge = struct
|
|||||||
| Some pk -> Reveal pk :: operations in
|
| Some pk -> Reveal pk :: operations in
|
||||||
let ops =
|
let ops =
|
||||||
Manager_operations { source ;
|
Manager_operations { source ;
|
||||||
counter ; operations ; fee ; gas_limit } in
|
counter ; operations ; fee ;
|
||||||
|
gas_limit ; storage_limit } in
|
||||||
(RPC_context.make_call0 S.operations ctxt block
|
(RPC_context.make_call0 S.operations ctxt block
|
||||||
() ({ branch }, Sourced_operation ops))
|
() ({ branch }, Sourced_operation ops))
|
||||||
|
|
||||||
let reveal ctxt
|
let reveal ctxt
|
||||||
block ~branch ~source ~sourcePubKey ~counter ~fee ()=
|
block ~branch ~source ~sourcePubKey ~counter ~fee ()=
|
||||||
operations ctxt block ~branch ~source ~sourcePubKey ~counter ~fee ~gas_limit:Z.zero []
|
operations ctxt block ~branch ~source ~sourcePubKey ~counter ~fee
|
||||||
|
~gas_limit:Z.zero ~storage_limit:0L []
|
||||||
|
|
||||||
let transaction ctxt
|
let transaction ctxt
|
||||||
block ~branch ~source ?sourcePubKey ~counter
|
block ~branch ~source ?sourcePubKey ~counter
|
||||||
~amount ~destination ?parameters ~gas_limit ~fee ()=
|
~amount ~destination ?parameters
|
||||||
operations ctxt block ~branch ~source ?sourcePubKey ~counter ~fee ~gas_limit
|
~gas_limit ~storage_limit ~fee ()=
|
||||||
|
operations ctxt block ~branch ~source ?sourcePubKey ~counter
|
||||||
|
~fee ~gas_limit ~storage_limit
|
||||||
Alpha_context.[Transaction { amount ; parameters ; destination }]
|
Alpha_context.[Transaction { amount ; parameters ; destination }]
|
||||||
|
|
||||||
let origination ctxt
|
let origination ctxt
|
||||||
@ -334,8 +339,9 @@ module Forge = struct
|
|||||||
?(spendable = true)
|
?(spendable = true)
|
||||||
?(delegatable = true)
|
?(delegatable = true)
|
||||||
?delegatePubKey ?script
|
?delegatePubKey ?script
|
||||||
~gas_limit ~fee () =
|
~gas_limit ~storage_limit ~fee () =
|
||||||
operations ctxt block ~branch ~source ?sourcePubKey ~counter ~fee ~gas_limit
|
operations ctxt block ~branch ~source ?sourcePubKey ~counter
|
||||||
|
~fee ~gas_limit ~storage_limit
|
||||||
Alpha_context.[
|
Alpha_context.[
|
||||||
Origination { manager = managerPubKey ;
|
Origination { manager = managerPubKey ;
|
||||||
delegate = delegatePubKey ;
|
delegate = delegatePubKey ;
|
||||||
@ -348,7 +354,8 @@ module Forge = struct
|
|||||||
|
|
||||||
let delegation ctxt
|
let delegation ctxt
|
||||||
block ~branch ~source ?sourcePubKey ~counter ~fee delegate =
|
block ~branch ~source ?sourcePubKey ~counter ~fee delegate =
|
||||||
operations ctxt block ~branch ~source ?sourcePubKey ~counter ~fee ~gas_limit:Z.zero
|
operations ctxt block ~branch ~source ?sourcePubKey ~counter ~fee
|
||||||
|
~gas_limit:Z.zero ~storage_limit:0L
|
||||||
Alpha_context.[Delegation delegate]
|
Alpha_context.[Delegation delegate]
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -72,6 +72,7 @@ module Forge : sig
|
|||||||
counter:int32 ->
|
counter:int32 ->
|
||||||
fee:Tez.t ->
|
fee:Tez.t ->
|
||||||
gas_limit:Z.t ->
|
gas_limit:Z.t ->
|
||||||
|
storage_limit:Int64.t ->
|
||||||
manager_operation list -> MBytes.t shell_tzresult Lwt.t
|
manager_operation list -> MBytes.t shell_tzresult Lwt.t
|
||||||
|
|
||||||
val reveal:
|
val reveal:
|
||||||
@ -93,6 +94,7 @@ module Forge : sig
|
|||||||
destination:Contract.t ->
|
destination:Contract.t ->
|
||||||
?parameters:Script.expr ->
|
?parameters:Script.expr ->
|
||||||
gas_limit:Z.t ->
|
gas_limit:Z.t ->
|
||||||
|
storage_limit:Int64.t ->
|
||||||
fee:Tez.t ->
|
fee:Tez.t ->
|
||||||
unit -> MBytes.t shell_tzresult Lwt.t
|
unit -> MBytes.t shell_tzresult Lwt.t
|
||||||
|
|
||||||
@ -109,6 +111,7 @@ module Forge : sig
|
|||||||
?delegatePubKey: public_key_hash ->
|
?delegatePubKey: public_key_hash ->
|
||||||
?script:Script.t ->
|
?script:Script.t ->
|
||||||
gas_limit:Z.t ->
|
gas_limit:Z.t ->
|
||||||
|
storage_limit:Int64.t ->
|
||||||
fee:Tez.t->
|
fee:Tez.t->
|
||||||
unit -> MBytes.t shell_tzresult Lwt.t
|
unit -> MBytes.t shell_tzresult Lwt.t
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ and sourced_operation =
|
|||||||
counter: counter ;
|
counter: counter ;
|
||||||
operations: manager_operation list ;
|
operations: manager_operation list ;
|
||||||
gas_limit: Z.t;
|
gas_limit: Z.t;
|
||||||
|
storage_limit: Int64.t;
|
||||||
}
|
}
|
||||||
| Dictator_operation of dictator_operation
|
| Dictator_operation of dictator_operation
|
||||||
|
|
||||||
@ -186,7 +187,7 @@ module Encoding = struct
|
|||||||
(fun ((), key) -> Delegation key)
|
(fun ((), key) -> Delegation key)
|
||||||
|
|
||||||
let manager_kind_encoding =
|
let manager_kind_encoding =
|
||||||
obj6
|
obj7
|
||||||
(req "kind" (constant "manager"))
|
(req "kind" (constant "manager"))
|
||||||
(req "source" Contract_repr.encoding)
|
(req "source" Contract_repr.encoding)
|
||||||
(req "fee" Tez_repr.encoding)
|
(req "fee" Tez_repr.encoding)
|
||||||
@ -199,15 +200,16 @@ module Encoding = struct
|
|||||||
delegation_case (Tag 3) ;
|
delegation_case (Tag 3) ;
|
||||||
])))
|
])))
|
||||||
(req "gas_limit" z)
|
(req "gas_limit" z)
|
||||||
|
(req "storage_limit" int64)
|
||||||
|
|
||||||
let manager_kind_case tag =
|
let manager_kind_case tag =
|
||||||
case tag ~name:"Manager operations" manager_kind_encoding
|
case tag ~name:"Manager operations" manager_kind_encoding
|
||||||
(function
|
(function
|
||||||
| Manager_operations { source; fee ; counter ; operations ; gas_limit } ->
|
| Manager_operations { source; fee ; counter ; operations ; gas_limit ; storage_limit } ->
|
||||||
Some ((), source, fee, counter, operations, gas_limit)
|
Some ((), source, fee, counter, operations, gas_limit, storage_limit)
|
||||||
| _ -> None)
|
| _ -> None)
|
||||||
(fun ((), source, fee, counter, operations, gas_limit) ->
|
(fun ((), source, fee, counter, operations, gas_limit, storage_limit) ->
|
||||||
Manager_operations { source; fee ; counter ; operations ; gas_limit })
|
Manager_operations { source; fee ; counter ; operations ; gas_limit ; storage_limit })
|
||||||
|
|
||||||
let endorsement_encoding =
|
let endorsement_encoding =
|
||||||
(* describe ~title:"Endorsement operation" @@ *)
|
(* describe ~title:"Endorsement operation" @@ *)
|
||||||
|
@ -56,6 +56,7 @@ and sourced_operation =
|
|||||||
counter: counter ;
|
counter: counter ;
|
||||||
operations: manager_operation list ;
|
operations: manager_operation list ;
|
||||||
gas_limit: Z.t ;
|
gas_limit: Z.t ;
|
||||||
|
storage_limit: Int64.t;
|
||||||
}
|
}
|
||||||
| Dictator_operation of dictator_operation
|
| Dictator_operation of dictator_operation
|
||||||
|
|
||||||
|
@ -105,6 +105,12 @@ let constants_encoding =
|
|||||||
and cost_per_byte =
|
and cost_per_byte =
|
||||||
opt Tez_repr.(=)
|
opt Tez_repr.(=)
|
||||||
default.cost_per_byte c.cost_per_byte
|
default.cost_per_byte c.cost_per_byte
|
||||||
|
and hard_storage_limit_per_operation =
|
||||||
|
opt Compare.Int64.(=)
|
||||||
|
default.hard_storage_limit_per_operation c.hard_storage_limit_per_operation
|
||||||
|
and hard_storage_limit_per_block =
|
||||||
|
opt Compare.Int64.(=)
|
||||||
|
default.hard_storage_limit_per_block c.hard_storage_limit_per_block
|
||||||
in
|
in
|
||||||
(( preserved_cycles,
|
(( preserved_cycles,
|
||||||
blocks_per_cycle,
|
blocks_per_cycle,
|
||||||
@ -127,7 +133,9 @@ let constants_encoding =
|
|||||||
endorsement_security_deposit,
|
endorsement_security_deposit,
|
||||||
block_reward),
|
block_reward),
|
||||||
(endorsement_reward,
|
(endorsement_reward,
|
||||||
cost_per_byte))))
|
cost_per_byte,
|
||||||
|
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,
|
||||||
@ -149,7 +157,9 @@ let constants_encoding =
|
|||||||
endorsement_security_deposit,
|
endorsement_security_deposit,
|
||||||
block_reward),
|
block_reward),
|
||||||
(endorsement_reward,
|
(endorsement_reward,
|
||||||
cost_per_byte))) ->
|
cost_per_byte,
|
||||||
|
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 =
|
||||||
@ -197,6 +207,10 @@ let constants_encoding =
|
|||||||
unopt default.endorsement_reward endorsement_reward ;
|
unopt default.endorsement_reward endorsement_reward ;
|
||||||
cost_per_byte =
|
cost_per_byte =
|
||||||
unopt default.cost_per_byte cost_per_byte ;
|
unopt default.cost_per_byte cost_per_byte ;
|
||||||
|
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
|
||||||
(obj10
|
(obj10
|
||||||
@ -222,9 +236,11 @@ 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))
|
||||||
(obj2
|
(obj4
|
||||||
(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" int64)
|
||||||
|
(opt "hard_storage_limit_per_block" int64))))
|
||||||
|
|
||||||
let encoding =
|
let encoding =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
|
@ -20,7 +20,9 @@ type t = {
|
|||||||
fees: Tez_repr.t ;
|
fees: Tez_repr.t ;
|
||||||
rewards: Tez_repr.t ;
|
rewards: Tez_repr.t ;
|
||||||
block_gas: Z.t ;
|
block_gas: Z.t ;
|
||||||
operation_gas: Gas_repr.t ;
|
operation_gas: Gas_limit_repr.t ;
|
||||||
|
block_storage: Int64.t ;
|
||||||
|
operation_storage: Storage_limit_repr.t ;
|
||||||
origination_nonce: Contract_repr.origination_nonce option ;
|
origination_nonce: Contract_repr.origination_nonce option ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +94,7 @@ let () =
|
|||||||
register_error_kind
|
register_error_kind
|
||||||
`Permanent
|
`Permanent
|
||||||
~id:"gas_limit_too_high"
|
~id:"gas_limit_too_high"
|
||||||
~title: "Gas limit higher than the hard limit"
|
~title: "Gas limit out of protocol hard bounds"
|
||||||
~description:
|
~description:
|
||||||
"A transaction tried to exceed the hard limit on gas"
|
"A transaction tried to exceed the hard limit on gas"
|
||||||
empty
|
empty
|
||||||
@ -100,18 +102,44 @@ let () =
|
|||||||
(fun () -> Gas_limit_too_high)
|
(fun () -> Gas_limit_too_high)
|
||||||
|
|
||||||
let set_gas_limit ctxt remaining =
|
let set_gas_limit ctxt remaining =
|
||||||
if Compare.Z.(remaining > ctxt.constants.hard_gas_limit_per_operation) then
|
if Compare.Z.(remaining > ctxt.constants.hard_gas_limit_per_operation)
|
||||||
|
|| Compare.Z.(remaining < Z.zero) then
|
||||||
error Gas_limit_too_high
|
error Gas_limit_too_high
|
||||||
else
|
else
|
||||||
ok { ctxt with operation_gas = Limited { remaining } }
|
ok { ctxt with operation_gas = Limited { remaining } }
|
||||||
let set_gas_unlimited ctxt =
|
let set_gas_unlimited ctxt =
|
||||||
{ ctxt with operation_gas = Unaccounted }
|
{ ctxt with operation_gas = Unaccounted }
|
||||||
let consume_gas ctxt cost =
|
let consume_gas ctxt cost =
|
||||||
Gas_repr.consume ctxt.block_gas ctxt.operation_gas cost >>? fun (block_gas, operation_gas) ->
|
Gas_limit_repr.consume ctxt.block_gas ctxt.operation_gas cost >>? fun (block_gas, operation_gas) ->
|
||||||
ok { ctxt with block_gas ; operation_gas }
|
ok { ctxt with block_gas ; operation_gas }
|
||||||
let gas_level ctxt = ctxt.operation_gas
|
let gas_level ctxt = ctxt.operation_gas
|
||||||
let block_gas_level ctxt = ctxt.block_gas
|
let block_gas_level ctxt = ctxt.block_gas
|
||||||
|
|
||||||
|
type error += Storage_limit_too_high (* `Permanent *)
|
||||||
|
|
||||||
|
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.Int64.(remaining > ctxt.constants.hard_storage_limit_per_operation)
|
||||||
|
|| Compare.Int64.(remaining < 0L)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
|
||||||
@ -331,6 +359,8 @@ let prepare ~level ~timestamp ~fitness ctxt =
|
|||||||
rewards = Tez_repr.zero ;
|
rewards = Tez_repr.zero ;
|
||||||
operation_gas = Unaccounted ;
|
operation_gas = Unaccounted ;
|
||||||
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 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,6 +408,8 @@ let register_resolvers enc resolve =
|
|||||||
rewards = Tez_repr.zero ;
|
rewards = Tez_repr.zero ;
|
||||||
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 ;
|
||||||
} in
|
} in
|
||||||
resolve faked_context str in
|
resolve faked_context str in
|
||||||
@ -421,7 +453,9 @@ module type T = sig
|
|||||||
|
|
||||||
val absolute_key: context -> key -> key
|
val absolute_key: context -> key -> key
|
||||||
|
|
||||||
val consume_gas: context -> Gas_repr.cost -> context tzresult
|
val consume_gas: context -> Gas_limit_repr.cost -> context tzresult
|
||||||
|
|
||||||
|
val record_bytes_stored: context -> Int64.t -> context tzresult
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -79,9 +79,14 @@ type error += Gas_limit_too_high (* `Permanent *)
|
|||||||
|
|
||||||
val set_gas_limit: t -> Z.t -> t tzresult
|
val set_gas_limit: t -> Z.t -> t tzresult
|
||||||
val set_gas_unlimited: t -> t
|
val set_gas_unlimited: t -> t
|
||||||
val gas_level: t -> Gas_repr.t
|
val gas_level: t -> Gas_limit_repr.t
|
||||||
val block_gas_level: t -> Z.t
|
val block_gas_level: t -> Z.t
|
||||||
|
|
||||||
|
type error += Storage_limit_too_high (* `Permanent *)
|
||||||
|
|
||||||
|
val set_storage_limit: t -> Int64.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
|
||||||
@ -171,7 +176,11 @@ module type T = sig
|
|||||||
|
|
||||||
(** Internally used in {!Storage_functors} to consume gas from
|
(** Internally used in {!Storage_functors} to consume gas from
|
||||||
within a view. *)
|
within a view. *)
|
||||||
val consume_gas: context -> Gas_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 -> Int64.t -> context tzresult
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -89,6 +89,7 @@ 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
|
||||||
end
|
end
|
||||||
|
|
||||||
module Make_single_data_storage (C : Raw_context.T) (N : NAME) (V : VALUE)
|
module Make_single_data_storage (C : Raw_context.T) (N : NAME) (V : VALUE)
|
||||||
@ -139,7 +140,7 @@ module Make_single_carbonated_data_storage
|
|||||||
type context = t
|
type context = t
|
||||||
type value = V.t
|
type value = V.t
|
||||||
let consume_mem_gas c =
|
let consume_mem_gas c =
|
||||||
Lwt.return (C.consume_gas c (Gas_repr.read_bytes_cost Z.zero))
|
Lwt.return (C.consume_gas c (Gas_limit_repr.read_bytes_cost Z.zero))
|
||||||
let existing_size c =
|
let existing_size c =
|
||||||
match V.size with
|
match V.size with
|
||||||
| Fixed len ->
|
| Fixed len ->
|
||||||
@ -152,26 +153,26 @@ module Make_single_carbonated_data_storage
|
|||||||
let consume_read_gas get c =
|
let consume_read_gas get c =
|
||||||
match V.size with
|
match V.size with
|
||||||
| Fixed len ->
|
| Fixed len ->
|
||||||
Lwt.return (C.consume_gas c (Gas_repr.read_bytes_cost (Z.of_int len)))
|
Lwt.return (C.consume_gas c (Gas_limit_repr.read_bytes_cost (Z.of_int len)))
|
||||||
| Variable ->
|
| Variable ->
|
||||||
get c (len_name N.name) >>=? fun len ->
|
get c (len_name N.name) >>=? fun len ->
|
||||||
decode_len_value N.name len >>=? fun len ->
|
decode_len_value N.name len >>=? fun len ->
|
||||||
Lwt.return (C.consume_gas c (Gas_repr.read_bytes_cost (Z.of_int len)))
|
Lwt.return (C.consume_gas c (Gas_limit_repr.read_bytes_cost (Z.of_int len)))
|
||||||
let consume_write_gas set c v =
|
let consume_write_gas set c v =
|
||||||
match V.size with
|
match V.size with
|
||||||
| Fixed s ->
|
| Fixed s ->
|
||||||
Lwt.return (C.consume_gas c (Gas_repr.write_bytes_cost (Z.of_int s))) >>=? fun c ->
|
Lwt.return (C.consume_gas c (Gas_limit_repr.write_bytes_cost (Z.of_int s))) >>=? fun c ->
|
||||||
return (c, V.to_bytes v)
|
return (c, V.to_bytes v)
|
||||||
| Variable ->
|
| Variable ->
|
||||||
let bytes = V.to_bytes v in
|
let bytes = V.to_bytes v in
|
||||||
let len = MBytes.length bytes in
|
let len = MBytes.length bytes in
|
||||||
Lwt.return (C.consume_gas c (Gas_repr.write_bytes_cost (Z.of_int len))) >>=? fun c ->
|
Lwt.return (C.consume_gas c (Gas_limit_repr.write_bytes_cost (Z.of_int len))) >>=? fun c ->
|
||||||
set c (len_name N.name) (encode_len_value bytes) >>=? fun c ->
|
set c (len_name N.name) (encode_len_value bytes) >>=? fun c ->
|
||||||
return (c, bytes)
|
return (c, bytes)
|
||||||
let consume_remove_gas del c =
|
let consume_remove_gas del c =
|
||||||
match V.size with
|
match V.size with
|
||||||
| Fixed _ | Variable ->
|
| Fixed _ | Variable ->
|
||||||
Lwt.return (C.consume_gas c (Gas_repr.write_bytes_cost Z.zero)) >>=? fun c ->
|
Lwt.return (C.consume_gas c (Gas_limit_repr.write_bytes_cost Z.zero)) >>=? fun c ->
|
||||||
del c (len_name N.name)
|
del c (len_name N.name)
|
||||||
let mem c =
|
let mem c =
|
||||||
consume_mem_gas c >>=? fun c ->
|
consume_mem_gas c >>=? fun c ->
|
||||||
@ -192,30 +193,38 @@ module Make_single_carbonated_data_storage
|
|||||||
else
|
else
|
||||||
return (C.project c, None)
|
return (C.project c, None)
|
||||||
let init c v =
|
let init c v =
|
||||||
|
consume_write_gas C.set c v >>=? fun (c, bytes) ->
|
||||||
|
C.init c N.name bytes >>=? fun c ->
|
||||||
|
let size = MBytes.length bytes in
|
||||||
|
Lwt.return (C.record_bytes_stored c (Int64.of_int size)) >>=? fun c ->
|
||||||
|
return (C.project c, size)
|
||||||
|
let set c v =
|
||||||
consume_write_gas C.init c v >>=? fun (c, bytes) ->
|
consume_write_gas C.init c v >>=? fun (c, bytes) ->
|
||||||
existing_size c >>=? fun prev_size ->
|
existing_size c >>=? fun prev_size ->
|
||||||
C.init c N.name bytes >>=? fun c ->
|
|
||||||
return (C.project c, MBytes.length bytes - prev_size)
|
|
||||||
let set c v =
|
|
||||||
consume_write_gas C.set c v >>=? fun (c, bytes) ->
|
|
||||||
C.set c N.name bytes >>=? fun c ->
|
C.set c N.name bytes >>=? fun c ->
|
||||||
return (C.project c, MBytes.length bytes)
|
let size_diff = MBytes.length bytes - prev_size in
|
||||||
|
Lwt.return (C.record_bytes_stored c (Int64.of_int size_diff)) >>=? fun c ->
|
||||||
|
return (C.project c, size_diff)
|
||||||
let init_set c v =
|
let init_set c v =
|
||||||
let init_set c k v = C.init_set c k v >>= return in
|
let init_set c k v = C.init_set c k v >>= return in
|
||||||
consume_write_gas init_set c v >>=? fun (c, bytes) ->
|
consume_write_gas init_set c v >>=? fun (c, bytes) ->
|
||||||
existing_size c >>=? fun prev_size ->
|
existing_size c >>=? fun prev_size ->
|
||||||
init_set c N.name bytes >>=? fun c ->
|
init_set c N.name bytes >>=? fun c ->
|
||||||
return (C.project c, MBytes.length bytes - prev_size)
|
let size_diff = MBytes.length bytes - prev_size in
|
||||||
|
Lwt.return (C.record_bytes_stored c (Int64.of_int size_diff)) >>=? fun c ->
|
||||||
|
return (C.project c, size_diff)
|
||||||
let remove c =
|
let remove c =
|
||||||
let remove c k = C.remove c k >>= return in
|
let remove c k = C.remove c k >>= return in
|
||||||
consume_remove_gas remove c >>=? fun c ->
|
consume_remove_gas remove c >>=? fun c ->
|
||||||
existing_size c >>=? fun prev_size ->
|
existing_size c >>=? fun prev_size ->
|
||||||
remove c N.name >>=? fun c ->
|
remove c N.name >>=? fun c ->
|
||||||
|
Lwt.return (C.record_bytes_stored c (Int64.of_int ~-prev_size)) >>=? fun c ->
|
||||||
return (C.project c, prev_size)
|
return (C.project c, prev_size)
|
||||||
let delete c =
|
let delete c =
|
||||||
consume_remove_gas C.delete c >>=? fun c ->
|
consume_remove_gas C.delete c >>=? fun c ->
|
||||||
existing_size c >>=? fun prev_size ->
|
existing_size c >>=? fun prev_size ->
|
||||||
C.delete c N.name >>=? fun c ->
|
C.delete c N.name >>=? fun c ->
|
||||||
|
Lwt.return (C.record_bytes_stored c (Int64.of_int ~-prev_size)) >>=? fun c ->
|
||||||
return (C.project c, prev_size)
|
return (C.project c, prev_size)
|
||||||
let set_option c v =
|
let set_option c v =
|
||||||
match v with
|
match v with
|
||||||
@ -392,7 +401,7 @@ module Make_indexed_carbonated_data_storage
|
|||||||
| [ last ] -> Compare.Char.(=) (String.get last (String.length last - 1)) '$'
|
| [ last ] -> Compare.Char.(=) (String.get last (String.length last - 1)) '$'
|
||||||
| _ :: rest -> is_len_name rest
|
| _ :: rest -> is_len_name rest
|
||||||
let consume_mem_gas c =
|
let consume_mem_gas c =
|
||||||
Lwt.return (C.consume_gas c (Gas_repr.read_bytes_cost Z.zero))
|
Lwt.return (C.consume_gas c (Gas_limit_repr.read_bytes_cost Z.zero))
|
||||||
let existing_size c i =
|
let existing_size c i =
|
||||||
match V.size with
|
match V.size with
|
||||||
| Fixed len ->
|
| Fixed len ->
|
||||||
@ -405,26 +414,26 @@ module Make_indexed_carbonated_data_storage
|
|||||||
let consume_read_gas get c i =
|
let consume_read_gas get c i =
|
||||||
match V.size with
|
match V.size with
|
||||||
| Fixed len ->
|
| Fixed len ->
|
||||||
Lwt.return (C.consume_gas c (Gas_repr.read_bytes_cost (Z.of_int len)))
|
Lwt.return (C.consume_gas c (Gas_limit_repr.read_bytes_cost (Z.of_int len)))
|
||||||
| Variable ->
|
| Variable ->
|
||||||
get c (len_name i) >>=? fun len ->
|
get c (len_name i) >>=? fun len ->
|
||||||
decode_len_value (name i) len >>=? fun len ->
|
decode_len_value (name i) len >>=? fun len ->
|
||||||
Lwt.return (C.consume_gas c (Gas_repr.read_bytes_cost (Z.of_int len)))
|
Lwt.return (C.consume_gas c (Gas_limit_repr.read_bytes_cost (Z.of_int len)))
|
||||||
let consume_write_gas set c i v =
|
let consume_write_gas set c i v =
|
||||||
match V.size with
|
match V.size with
|
||||||
| Fixed s ->
|
| Fixed s ->
|
||||||
Lwt.return (C.consume_gas c (Gas_repr.write_bytes_cost (Z.of_int s))) >>=? fun c ->
|
Lwt.return (C.consume_gas c (Gas_limit_repr.write_bytes_cost (Z.of_int s))) >>=? fun c ->
|
||||||
return (c, V.to_bytes v)
|
return (c, V.to_bytes v)
|
||||||
| Variable ->
|
| Variable ->
|
||||||
let bytes = V.to_bytes v in
|
let bytes = V.to_bytes v in
|
||||||
let len = MBytes.length bytes in
|
let len = MBytes.length bytes in
|
||||||
Lwt.return (C.consume_gas c (Gas_repr.write_bytes_cost (Z.of_int len))) >>=? fun c ->
|
Lwt.return (C.consume_gas c (Gas_limit_repr.write_bytes_cost (Z.of_int len))) >>=? fun c ->
|
||||||
set c (len_name i) (encode_len_value bytes) >>=? fun c ->
|
set c (len_name i) (encode_len_value bytes) >>=? fun c ->
|
||||||
return (c, bytes)
|
return (c, bytes)
|
||||||
let consume_remove_gas del c i =
|
let consume_remove_gas del c i =
|
||||||
match V.size with
|
match V.size with
|
||||||
| Fixed _ | Variable ->
|
| Fixed _ | Variable ->
|
||||||
Lwt.return (C.consume_gas c (Gas_repr.write_bytes_cost Z.zero)) >>=? fun c ->
|
Lwt.return (C.consume_gas c (Gas_limit_repr.write_bytes_cost Z.zero)) >>=? fun c ->
|
||||||
del c (len_name i)
|
del c (len_name i)
|
||||||
let mem s i =
|
let mem s i =
|
||||||
consume_mem_gas s >>=? fun s ->
|
consume_mem_gas s >>=? fun s ->
|
||||||
@ -448,27 +457,35 @@ 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) ->
|
||||||
existing_size s i >>=? fun prev_size ->
|
existing_size s i >>=? fun prev_size ->
|
||||||
C.set s (name i) bytes >>=? fun t ->
|
C.set s (name i) bytes >>=? fun t ->
|
||||||
return (C.project t, MBytes.length bytes - prev_size)
|
let size_diff = MBytes.length bytes - prev_size in
|
||||||
|
Lwt.return (C.record_bytes_stored t (Int64.of_int size_diff)) >>=? fun t ->
|
||||||
|
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 ->
|
||||||
return (C.project t, MBytes.length bytes)
|
let size = MBytes.length bytes in
|
||||||
|
Lwt.return (C.record_bytes_stored t (Int64.of_int size)) >>=? fun t ->
|
||||||
|
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
|
||||||
consume_write_gas init_set s i v >>=? fun (s, bytes) ->
|
consume_write_gas init_set s i v >>=? fun (s, bytes) ->
|
||||||
existing_size s i >>=? fun prev_size ->
|
existing_size s i >>=? fun prev_size ->
|
||||||
init_set s (name i) bytes >>=? fun t ->
|
init_set s (name i) bytes >>=? fun t ->
|
||||||
return (C.project t, MBytes.length bytes - prev_size)
|
let size_diff = MBytes.length bytes - prev_size in
|
||||||
|
Lwt.return (C.record_bytes_stored t (Int64.of_int size_diff)) >>=? fun t ->
|
||||||
|
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
|
||||||
consume_remove_gas remove s i >>=? fun s ->
|
consume_remove_gas remove s i >>=? fun s ->
|
||||||
existing_size s i >>=? fun prev_size ->
|
existing_size s i >>=? fun prev_size ->
|
||||||
remove s (name i) >>=? fun t ->
|
remove s (name i) >>=? fun t ->
|
||||||
|
Lwt.return (C.record_bytes_stored t (Int64.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 =
|
||||||
consume_remove_gas C.delete s i >>=? fun s ->
|
consume_remove_gas C.delete s i >>=? fun s ->
|
||||||
existing_size s i >>=? fun prev_size ->
|
existing_size s i >>=? fun prev_size ->
|
||||||
C.delete s (name i) >>=? fun t ->
|
C.delete s (name i) >>=? fun t ->
|
||||||
|
Lwt.return (C.record_bytes_stored t (Int64.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
|
||||||
@ -512,6 +529,7 @@ module Make_indexed_carbonated_data_storage
|
|||||||
consume_remove_gas C.delete s path >>=? fun s ->
|
consume_remove_gas C.delete s path >>=? fun s ->
|
||||||
existing_size s path >>=? fun prev_size ->
|
existing_size s path >>=? fun prev_size ->
|
||||||
C.delete s (name path) >>=? fun s ->
|
C.delete s (name path) >>=? fun s ->
|
||||||
|
Lwt.return (C.record_bytes_stored s (Int64.of_int ~-prev_size)) >>=? fun s ->
|
||||||
return (s, Z.add (Z.of_int prev_size) total) in
|
return (s, Z.add (Z.of_int prev_size) total) in
|
||||||
fold_keys_unaccounted s ~init:Z.zero ~f
|
fold_keys_unaccounted s ~init:Z.zero ~f
|
||||||
let fold s ~init ~f =
|
let fold s ~init ~f =
|
||||||
@ -610,6 +628,7 @@ module Make_indexed_subcontext (C : Raw_context.T) (I : INDEX)
|
|||||||
let project (t, _) = C.project t
|
let project (t, _) = C.project t
|
||||||
let absolute_key (t, i) k = C.absolute_key t (to_key i k)
|
let absolute_key (t, i) k = C.absolute_key t (to_key i k)
|
||||||
let consume_gas (t, k) c = C.consume_gas t c >>? fun t -> ok (t, k)
|
let consume_gas (t, k) c = C.consume_gas t c >>? fun t -> ok (t, k)
|
||||||
|
let record_bytes_stored (t, k) c = C.record_bytes_stored t c >>? fun t -> ok (t, k)
|
||||||
end
|
end
|
||||||
|
|
||||||
let fold_keys t ~init ~f =
|
let fold_keys t ~init ~f =
|
||||||
@ -766,7 +785,7 @@ module Make_indexed_subcontext (C : Raw_context.T) (I : INDEX)
|
|||||||
type key = I.t
|
type key = I.t
|
||||||
type value = V.t
|
type value = V.t
|
||||||
let consume_mem_gas c =
|
let consume_mem_gas c =
|
||||||
Lwt.return (Raw_context.consume_gas c (Gas_repr.read_bytes_cost Z.zero))
|
Lwt.return (Raw_context.consume_gas c (Gas_limit_repr.read_bytes_cost Z.zero))
|
||||||
let existing_size c =
|
let existing_size c =
|
||||||
match V.size with
|
match V.size with
|
||||||
| Fixed len ->
|
| Fixed len ->
|
||||||
@ -779,26 +798,26 @@ module Make_indexed_subcontext (C : Raw_context.T) (I : INDEX)
|
|||||||
let consume_read_gas get c =
|
let consume_read_gas get c =
|
||||||
match V.size with
|
match V.size with
|
||||||
| Fixed len ->
|
| Fixed len ->
|
||||||
Lwt.return (Raw_context.consume_gas c (Gas_repr.read_bytes_cost (Z.of_int len)))
|
Lwt.return (Raw_context.consume_gas c (Gas_limit_repr.read_bytes_cost (Z.of_int len)))
|
||||||
| Variable ->
|
| Variable ->
|
||||||
get c (len_name N.name) >>=? fun len ->
|
get c (len_name N.name) >>=? fun len ->
|
||||||
decode_len_value N.name len >>=? fun len ->
|
decode_len_value N.name len >>=? fun len ->
|
||||||
Lwt.return (Raw_context.consume_gas c (Gas_repr.read_bytes_cost (Z.of_int len)))
|
Lwt.return (Raw_context.consume_gas c (Gas_limit_repr.read_bytes_cost (Z.of_int len)))
|
||||||
let consume_write_gas set c v =
|
let consume_write_gas set c v =
|
||||||
match V.size with
|
match V.size with
|
||||||
| Fixed s ->
|
| Fixed s ->
|
||||||
Lwt.return (Raw_context.consume_gas c (Gas_repr.write_bytes_cost (Z.of_int s))) >>=? fun c ->
|
Lwt.return (Raw_context.consume_gas c (Gas_limit_repr.write_bytes_cost (Z.of_int s))) >>=? fun c ->
|
||||||
return (c, V.to_bytes v)
|
return (c, V.to_bytes v)
|
||||||
| Variable ->
|
| Variable ->
|
||||||
let bytes = V.to_bytes v in
|
let bytes = V.to_bytes v in
|
||||||
let len = MBytes.length bytes in
|
let len = MBytes.length bytes in
|
||||||
Lwt.return (Raw_context.consume_gas c (Gas_repr.write_bytes_cost (Z.of_int len))) >>=? fun c ->
|
Lwt.return (Raw_context.consume_gas c (Gas_limit_repr.write_bytes_cost (Z.of_int len))) >>=? fun c ->
|
||||||
set c (len_name N.name) (encode_len_value bytes) >>=? fun c ->
|
set c (len_name N.name) (encode_len_value bytes) >>=? fun c ->
|
||||||
return (c, bytes)
|
return (c, bytes)
|
||||||
let consume_remove_gas del c =
|
let consume_remove_gas del c =
|
||||||
match V.size with
|
match V.size with
|
||||||
| Fixed _ | Variable ->
|
| Fixed _ | Variable ->
|
||||||
Lwt.return (Raw_context.consume_gas c (Gas_repr.write_bytes_cost Z.zero)) >>=? fun c ->
|
Lwt.return (Raw_context.consume_gas c (Gas_limit_repr.write_bytes_cost Z.zero)) >>=? fun c ->
|
||||||
del c (len_name N.name)
|
del c (len_name N.name)
|
||||||
let mem s i =
|
let mem s i =
|
||||||
consume_mem_gas (s, i) >>=? fun c ->
|
consume_mem_gas (s, i) >>=? fun c ->
|
||||||
@ -822,27 +841,35 @@ module Make_indexed_subcontext (C : Raw_context.T) (I : INDEX)
|
|||||||
consume_write_gas Raw_context.set (s, i) v >>=? fun (c, bytes) ->
|
consume_write_gas Raw_context.set (s, i) v >>=? fun (c, bytes) ->
|
||||||
existing_size (s, i) >>=? fun prev_size ->
|
existing_size (s, i) >>=? fun prev_size ->
|
||||||
Raw_context.set c N.name bytes >>=? fun c ->
|
Raw_context.set c N.name bytes >>=? fun c ->
|
||||||
return (Raw_context.project c, MBytes.length bytes - prev_size)
|
let size_diff = MBytes.length bytes - prev_size in
|
||||||
|
Lwt.return (Raw_context.record_bytes_stored c (Int64.of_int size_diff)) >>=? fun c ->
|
||||||
|
return (Raw_context.project c, size_diff)
|
||||||
let init s i v =
|
let init s i v =
|
||||||
consume_write_gas Raw_context.init (s, i) v >>=? fun (c, bytes) ->
|
consume_write_gas Raw_context.init (s, i) v >>=? fun (c, bytes) ->
|
||||||
Raw_context.init c N.name bytes >>=? fun c ->
|
Raw_context.init c N.name bytes >>=? fun c ->
|
||||||
return (Raw_context.project c, MBytes.length bytes)
|
let size = MBytes.length bytes in
|
||||||
|
Lwt.return (Raw_context.record_bytes_stored c (Int64.of_int size)) >>=? fun c ->
|
||||||
|
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
|
||||||
consume_write_gas init_set (s, i) v >>=? fun (c, bytes) ->
|
consume_write_gas init_set (s, i) v >>=? fun (c, bytes) ->
|
||||||
existing_size c >>=? fun prev_size ->
|
existing_size c >>=? fun prev_size ->
|
||||||
init_set c N.name bytes >>=? fun c ->
|
init_set c N.name bytes >>=? fun c ->
|
||||||
return (Raw_context.project c, MBytes.length bytes - prev_size)
|
let size_diff = MBytes.length bytes - prev_size in
|
||||||
|
Lwt.return (Raw_context.record_bytes_stored c (Int64.of_int size_diff)) >>=? fun c ->
|
||||||
|
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
|
||||||
consume_remove_gas remove (s, i) >>=? fun c ->
|
consume_remove_gas remove (s, i) >>=? fun c ->
|
||||||
existing_size (s, i) >>=? fun prev_size ->
|
existing_size (s, i) >>=? fun prev_size ->
|
||||||
remove c N.name >>=? fun c ->
|
remove c N.name >>=? fun c ->
|
||||||
|
Lwt.return (Raw_context.record_bytes_stored c (Int64.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 =
|
||||||
consume_remove_gas Raw_context.delete (s, i) >>=? fun c ->
|
consume_remove_gas Raw_context.delete (s, i) >>=? fun c ->
|
||||||
existing_size (s, i) >>=? fun prev_size ->
|
existing_size (s, i) >>=? fun prev_size ->
|
||||||
Raw_context.delete c N.name >>=? fun c ->
|
Raw_context.delete c N.name >>=? fun c ->
|
||||||
|
Lwt.return (Raw_context.record_bytes_stored c (Int64.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
|
||||||
@ -856,6 +883,7 @@ module Make_indexed_subcontext (C : Raw_context.T) (I : INDEX)
|
|||||||
consume_remove_gas remove (s, i) >>=? fun (s, _) ->
|
consume_remove_gas remove (s, i) >>=? fun (s, _) ->
|
||||||
existing_size (s, i) >>=? fun prev_size ->
|
existing_size (s, i) >>=? fun prev_size ->
|
||||||
remove (s,i) N.name >>=? fun (s, _) ->
|
remove (s,i) N.name >>=? fun (s, _) ->
|
||||||
|
Lwt.return (Raw_context.record_bytes_stored (s, i) (Int64.of_int ~-prev_size)) >>=? fun (s, _) ->
|
||||||
return (s, Z.add total (Z.of_int prev_size))
|
return (s, Z.add total (Z.of_int prev_size))
|
||||||
end >>=? fun (s, total) ->
|
end >>=? fun (s, total) ->
|
||||||
return (C.project s, total)
|
return (C.project s, total)
|
||||||
|
51
src/proto_alpha/lib_protocol/src/storage_limit_repr.ml
Normal file
51
src/proto_alpha/lib_protocol/src/storage_limit_repr.ml
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* 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 : Int64.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 =
|
||||||
|
Int64.sub remaining bytes in
|
||||||
|
let block_remaining =
|
||||||
|
Int64.sub block_storage bytes in
|
||||||
|
if Compare.Int64.(remaining < 0L)
|
||||||
|
then error Operation_quota_exceeded
|
||||||
|
else if Compare.Int64.(block_remaining < 0L)
|
||||||
|
then error Block_quota_exceeded
|
||||||
|
else ok (block_remaining, Limited { remaining })
|
17
src/proto_alpha/lib_protocol/src/storage_limit_repr.mli
Normal file
17
src/proto_alpha/lib_protocol/src/storage_limit_repr.mli
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* 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 : Int64.t }
|
||||||
|
|
||||||
|
type error += Block_quota_exceeded (* `Temporary *)
|
||||||
|
type error += Operation_quota_exceeded (* `Temporary *)
|
||||||
|
|
||||||
|
val consume : Int64.t -> t -> bytes:Int64.t -> (Int64.t * t) tzresult
|
@ -26,6 +26,7 @@ let manager (src : Helpers_account.t) ?(fee = Tez.zero) operations context gas_l
|
|||||||
counter ;
|
counter ;
|
||||||
operations = (if revealed then operations else Reveal src.pub :: operations) ;
|
operations = (if revealed then operations else Reveal src.pub :: operations) ;
|
||||||
gas_limit ;
|
gas_limit ;
|
||||||
|
storage_limit = 30_000L ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user