Alpha: classify and document contract errors.
This commit is contained in:
parent
d845dc9740
commit
9caef6fae4
@ -128,7 +128,7 @@ let originate_contract cctxt
|
|||||||
~source ~src_pk ~src_sk ~manager_pkh ~balance ?delegatable ?delegatePubKey
|
~source ~src_pk ~src_sk ~manager_pkh ~balance ?delegatable ?delegatePubKey
|
||||||
~(code:Script.code) ~init ~fee () =
|
~(code:Script.code) ~init ~fee () =
|
||||||
Client_proto_programs.parse_data cctxt init >>= fun storage ->
|
Client_proto_programs.parse_data cctxt init >>= fun storage ->
|
||||||
let init = Script.{ storage ; storage_type = code.storage_type } in
|
let storage = Script.{ storage ; storage_type = code.storage_type } in
|
||||||
Client_proto_rpcs.Context.Contract.counter cctxt block source >>=? fun pcounter ->
|
Client_proto_rpcs.Context.Contract.counter cctxt block source >>=? fun pcounter ->
|
||||||
let counter = Int32.succ pcounter in
|
let counter = Int32.succ pcounter in
|
||||||
cctxt.message "Acquired the source's sequence counter (%ld -> %ld)."
|
cctxt.message "Acquired the source's sequence counter (%ld -> %ld)."
|
||||||
@ -138,7 +138,7 @@ let originate_contract cctxt
|
|||||||
~net ~source ~sourcePubKey:src_pk ~managerPubKey:manager_pkh
|
~net ~source ~sourcePubKey:src_pk ~managerPubKey:manager_pkh
|
||||||
~counter ~balance ~spendable:!spendable
|
~counter ~balance ~spendable:!spendable
|
||||||
?delegatable ?delegatePubKey
|
?delegatable ?delegatePubKey
|
||||||
~script:(code, init) ~fee () >>=? fun bytes ->
|
~script:{ code ; storage } ~fee () >>=? fun bytes ->
|
||||||
let signature = Ed25519.sign src_sk bytes in
|
let signature = Ed25519.sign src_sk bytes in
|
||||||
originate cctxt ?force ~block ~signature bytes
|
originate cctxt ?force ~block ~signature bytes
|
||||||
|
|
||||||
|
@ -471,7 +471,7 @@ let parse_data_type cctxt s =
|
|||||||
with
|
with
|
||||||
| exn -> report_parse_error cctxt "data_type: " exn lexbuf
|
| exn -> report_parse_error cctxt "data_type: " exn lexbuf
|
||||||
|
|
||||||
let unexpand_macros type_map program =
|
let unexpand_macros type_map (program : Script.code) =
|
||||||
let open Script in
|
let open Script in
|
||||||
let rec caddr type_map acc = function
|
let rec caddr type_map acc = function
|
||||||
| [] -> Some (List.rev acc)
|
| [] -> Some (List.rev acc)
|
||||||
|
@ -108,7 +108,7 @@ module Context = struct
|
|||||||
balance: Tez.t ;
|
balance: Tez.t ;
|
||||||
spendable: bool ;
|
spendable: bool ;
|
||||||
delegate: bool * public_key_hash option ;
|
delegate: bool * public_key_hash option ;
|
||||||
script: Script.t ;
|
script: Script.t option ;
|
||||||
assets: Asset.Map.t ;
|
assets: Asset.Map.t ;
|
||||||
counter: int32 ;
|
counter: int32 ;
|
||||||
}
|
}
|
||||||
@ -180,10 +180,6 @@ module Helpers = struct
|
|||||||
|
|
||||||
module Forge = struct
|
module Forge = struct
|
||||||
|
|
||||||
let script_of_option = function
|
|
||||||
| None -> Script.No_script
|
|
||||||
| Some (code, storage) -> Script { code ; storage }
|
|
||||||
|
|
||||||
open Operation
|
open Operation
|
||||||
|
|
||||||
module Manager = struct
|
module Manager = struct
|
||||||
@ -206,7 +202,6 @@ module Helpers = struct
|
|||||||
?(spendable = true)
|
?(spendable = true)
|
||||||
?(delegatable = true)
|
?(delegatable = true)
|
||||||
?delegatePubKey ?script ~fee () =
|
?delegatePubKey ?script ~fee () =
|
||||||
let script = script_of_option script in
|
|
||||||
operations cctxt block ~net ~source ?sourcePubKey ~counter ~fee
|
operations cctxt block ~net ~source ?sourcePubKey ~counter ~fee
|
||||||
Tezos_context.[
|
Tezos_context.[
|
||||||
Origination { manager = managerPubKey ;
|
Origination { manager = managerPubKey ;
|
||||||
|
@ -91,7 +91,7 @@ module Context : sig
|
|||||||
balance: Tez.t ;
|
balance: Tez.t ;
|
||||||
spendable: bool ;
|
spendable: bool ;
|
||||||
delegate: bool * public_key_hash option ;
|
delegate: bool * public_key_hash option ;
|
||||||
script: Script.t ;
|
script: Script.t option ;
|
||||||
assets: Asset.Map.t ;
|
assets: Asset.Map.t ;
|
||||||
counter: int32 ;
|
counter: int32 ;
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ module Context : sig
|
|||||||
bool tzresult Lwt.t
|
bool tzresult Lwt.t
|
||||||
val script:
|
val script:
|
||||||
Client_commands.context ->
|
Client_commands.context ->
|
||||||
block -> Contract.t -> Script.t tzresult Lwt.t
|
block -> Contract.t -> Script.t option tzresult Lwt.t
|
||||||
val assets:
|
val assets:
|
||||||
Client_commands.context ->
|
Client_commands.context ->
|
||||||
block -> Contract.t ->
|
block -> Contract.t ->
|
||||||
@ -222,7 +222,7 @@ module Helpers : sig
|
|||||||
?spendable:bool ->
|
?spendable:bool ->
|
||||||
?delegatable:bool ->
|
?delegatable:bool ->
|
||||||
?delegatePubKey: public_key_hash ->
|
?delegatePubKey: public_key_hash ->
|
||||||
?script:(Script.code * Script.storage) ->
|
?script:Script.t ->
|
||||||
fee:Tez.t->
|
fee:Tez.t->
|
||||||
unit ->
|
unit ->
|
||||||
MBytes.t tzresult Lwt.t
|
MBytes.t tzresult Lwt.t
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
open Tezos_context
|
open Tezos_context
|
||||||
|
|
||||||
type error += Bad_endorsement (* TODO: doc *)
|
type error += Bad_endorsement (* TODO: doc *)
|
||||||
type error += Insert_coin (* TODO: doc *)
|
|
||||||
type error += Contract_not_delegatable (* TODO: doc *)
|
type error += Contract_not_delegatable (* TODO: doc *)
|
||||||
type error += Unimplemented
|
type error += Unimplemented
|
||||||
type error += Invalid_voting_period
|
type error += Invalid_voting_period
|
||||||
@ -53,13 +52,13 @@ let apply_manager_operation_content ctxt origination_nonce accept_failing_script
|
|||||||
Contract.spend ctxt source amount >>=? fun ctxt ->
|
Contract.spend ctxt source amount >>=? fun ctxt ->
|
||||||
Contract.credit ctxt destination amount >>=? fun ctxt ->
|
Contract.credit ctxt destination amount >>=? fun ctxt ->
|
||||||
Contract.get_script ctxt destination >>=? function
|
Contract.get_script ctxt destination >>=? function
|
||||||
| No_script -> begin
|
| None -> begin
|
||||||
match parameters with
|
match parameters with
|
||||||
| None | Some (Prim (_, "Unit", [])) ->
|
| None | Some (Prim (_, "Unit", [])) ->
|
||||||
return (ctxt, origination_nonce)
|
return (ctxt, origination_nonce)
|
||||||
| Some _ -> fail Non_scripted_contract_with_parameter
|
| Some _ -> fail Non_scripted_contract_with_parameter
|
||||||
end
|
end
|
||||||
| Script { code ; storage } ->
|
| Some { code ; storage } ->
|
||||||
match parameters with
|
match parameters with
|
||||||
| None -> fail Scripted_contract_without_paramater
|
| None -> fail Scripted_contract_without_paramater
|
||||||
| Some parameters ->
|
| Some parameters ->
|
||||||
@ -71,8 +70,9 @@ let apply_manager_operation_content ctxt origination_nonce accept_failing_script
|
|||||||
| Ok (storage_res, _res, _steps, ctxt, origination_nonce) ->
|
| Ok (storage_res, _res, _steps, ctxt, origination_nonce) ->
|
||||||
(* TODO: pay for the steps and the storage diff:
|
(* TODO: pay for the steps and the storage diff:
|
||||||
update_script_storage checks the storage cost *)
|
update_script_storage checks the storage cost *)
|
||||||
Contract.update_script_storage
|
Contract.update_script_storage_and_fees
|
||||||
ctxt destination storage_res >>=? fun ctxt ->
|
ctxt destination
|
||||||
|
Script_interpreter.dummy_storage_fee storage_res >>=? fun ctxt ->
|
||||||
return (ctxt, origination_nonce)
|
return (ctxt, origination_nonce)
|
||||||
| Error err ->
|
| Error err ->
|
||||||
if accept_failing_script && is_reject err then
|
if accept_failing_script && is_reject err then
|
||||||
@ -81,24 +81,18 @@ let apply_manager_operation_content ctxt origination_nonce accept_failing_script
|
|||||||
Lwt.return (Error err)
|
Lwt.return (Error err)
|
||||||
end
|
end
|
||||||
| Origination { manager ; delegate ; script ;
|
| Origination { manager ; delegate ; script ;
|
||||||
spendable ; delegatable ; credit } -> begin
|
spendable ; delegatable ; credit } ->
|
||||||
match script with
|
let script = match script with
|
||||||
| No_script -> return ()
|
| None -> None
|
||||||
| Script { code ; storage } ->
|
| Some script ->
|
||||||
Script_ir_translator.parse_script ctxt storage code >>=? fun _ ->
|
Some (script, (Script_interpreter.dummy_code_fee, Script_interpreter.dummy_storage_fee)) in
|
||||||
let storage_fee = Script.storage_cost storage in
|
|
||||||
let code_fee = Script.code_cost code in
|
|
||||||
Lwt.return Tez.(code_fee +? storage_fee) >>=? fun script_fee ->
|
|
||||||
Lwt.return Tez.(script_fee +? Constants.origination_burn) >>=? fun total_fee ->
|
|
||||||
fail_unless Tez.(credit > total_fee) Insert_coin >>=? fun () ->
|
|
||||||
return ()
|
|
||||||
end >>=? fun () ->
|
|
||||||
Contract.spend ctxt source credit >>=? fun ctxt ->
|
Contract.spend ctxt source credit >>=? fun ctxt ->
|
||||||
Lwt.return Tez.(credit -? Constants.origination_burn) >>=? fun balance ->
|
Lwt.return Tez.(credit -? Constants.origination_burn) >>=? fun balance ->
|
||||||
Contract.originate ctxt
|
Contract.originate ctxt
|
||||||
origination_nonce
|
origination_nonce
|
||||||
~manager ~delegate ~balance
|
~manager ~delegate ~balance
|
||||||
~script ~spendable ~delegatable >>=? fun (ctxt, _, origination_nonce) ->
|
?script
|
||||||
|
~spendable ~delegatable >>=? fun (ctxt, _, origination_nonce) ->
|
||||||
return (ctxt, origination_nonce)
|
return (ctxt, origination_nonce)
|
||||||
| Issuance { asset = (asset, key); amount } ->
|
| Issuance { asset = (asset, key); amount } ->
|
||||||
Contract.issue ctxt source asset key amount >>=? fun ctxt ->
|
Contract.issue ctxt source asset key amount >>=? fun ctxt ->
|
||||||
@ -127,6 +121,7 @@ let apply_sourced_operation
|
|||||||
operation origination_nonce ops =
|
operation origination_nonce ops =
|
||||||
match ops with
|
match ops with
|
||||||
| Manager_operations { source ; public_key ; fee ; counter ; operations = contents } ->
|
| Manager_operations { source ; public_key ; fee ; counter ; operations = contents } ->
|
||||||
|
Contract.must_exist ctxt source >>=? fun () ->
|
||||||
Contract.get_manager ctxt source >>=? fun manager ->
|
Contract.get_manager ctxt source >>=? fun manager ->
|
||||||
check_signature_and_update_public_key
|
check_signature_and_update_public_key
|
||||||
ctxt manager public_key operation >>=? fun ctxt ->
|
ctxt manager public_key operation >>=? fun ctxt ->
|
||||||
@ -139,6 +134,7 @@ let apply_sourced_operation
|
|||||||
| Some contract ->
|
| Some contract ->
|
||||||
Contract.credit ctxt contract fee) >>=? fun ctxt ->
|
Contract.credit ctxt contract fee) >>=? fun ctxt ->
|
||||||
fold_left_s (fun (ctxt, origination_nonce) content ->
|
fold_left_s (fun (ctxt, origination_nonce) content ->
|
||||||
|
Contract.must_exist ctxt source >>=? fun () ->
|
||||||
apply_manager_operation_content ctxt origination_nonce
|
apply_manager_operation_content ctxt origination_nonce
|
||||||
accept_failing_script source content)
|
accept_failing_script source content)
|
||||||
(ctxt, origination_nonce) contents
|
(ctxt, origination_nonce) contents
|
||||||
@ -190,7 +186,7 @@ let apply_anonymous_operation ctxt miner_contract origination_nonce kind =
|
|||||||
end >>=? fun delegate ->
|
end >>=? fun delegate ->
|
||||||
Contract.originate ctxt
|
Contract.originate ctxt
|
||||||
origination_nonce
|
origination_nonce
|
||||||
~manager ~delegate ~balance:Constants.faucet_credit ~script:No_script
|
~manager ~delegate ~balance:Constants.faucet_credit ?script:None
|
||||||
~spendable:true ~delegatable:true >>=? fun (ctxt, _, origination_nonce) ->
|
~spendable:true ~delegatable:true >>=? fun (ctxt, _, origination_nonce) ->
|
||||||
return (ctxt, origination_nonce)
|
return (ctxt, origination_nonce)
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ type t =
|
|||||||
| Originated of Contract_hash.t
|
| Originated of Contract_hash.t
|
||||||
type contract = t
|
type contract = t
|
||||||
|
|
||||||
type error += Invalid_contract_notation of string
|
type error += Invalid_contract_notation of string (* `Permanent *)
|
||||||
|
|
||||||
let to_b58check = function
|
let to_b58check = function
|
||||||
| Default pbk -> Ed25519.Public_key_hash.to_b58check pbk
|
| Default pbk -> Ed25519.Public_key_hash.to_b58check pbk
|
||||||
@ -26,17 +26,23 @@ let of_b58check s =
|
|||||||
| Some (Contract_hash.Hash h) -> ok (Originated h)
|
| Some (Contract_hash.Hash h) -> ok (Originated h)
|
||||||
| _ -> error (Invalid_contract_notation s)
|
| _ -> error (Invalid_contract_notation s)
|
||||||
|
|
||||||
|
let pp ppf = function
|
||||||
|
| Default pbk -> Ed25519.Public_key_hash.pp ppf pbk
|
||||||
|
| Originated h -> Contract_hash.pp ppf h
|
||||||
|
|
||||||
|
let pp_short ppf = function
|
||||||
|
| Default pbk -> Ed25519.Public_key_hash.pp_short ppf pbk
|
||||||
|
| Originated h -> Contract_hash.pp_short ppf h
|
||||||
|
|
||||||
let encoding =
|
let encoding =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
describe
|
describe
|
||||||
~title:
|
~title:
|
||||||
"A contract handle"
|
"A contract handle"
|
||||||
~description:
|
~description:
|
||||||
"A contract notation as given to a RPC or inside scripts. \
|
"A contract notation as given to an RPC or inside scripts. \
|
||||||
Contract handles can be written 'd<base64 encoded ID>d' \
|
Can be a base58 public key hash, representing the default contract \
|
||||||
for the default contract of some ID (public key hash) or \
|
of this identity, or a base58 originated contract hash." @@
|
||||||
'h<base64 encoded contract ID>h' for a created contract or account, \
|
|
||||||
as replied by the contract origination RPC." @@
|
|
||||||
splitted
|
splitted
|
||||||
~binary:
|
~binary:
|
||||||
(union ~tag_size:`Uint8 [
|
(union ~tag_size:`Uint8 [
|
||||||
@ -60,14 +66,11 @@ let () =
|
|||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
register_error_kind
|
register_error_kind
|
||||||
`Permanent
|
`Permanent
|
||||||
~id:"InvalidContractNotationError"
|
~id:"contract.invalid_contract_notation"
|
||||||
~title: "Invalid contract notation"
|
~title: "Invalid contract notation"
|
||||||
|
~pp: (fun ppf x -> Format.fprintf ppf "Invalid contract notation %S" x)
|
||||||
~description:
|
~description:
|
||||||
"A malformed contract notation was given to a RPC or by a script. \
|
"A malformed contract notation was given to an RPC or in a script."
|
||||||
Contract handles can be written 'd<base encoded ID>d' \
|
|
||||||
for the default contract of some ID (public key hash) or \
|
|
||||||
'h<base encoded contract ID>h' for a created contract or account, \
|
|
||||||
as replied by the contract origination RPC."
|
|
||||||
(obj1 (req "notation" string))
|
(obj1 (req "notation" string))
|
||||||
(function Invalid_contract_notation loc -> Some loc | _ -> None)
|
(function Invalid_contract_notation loc -> Some loc | _ -> None)
|
||||||
(fun loc -> Invalid_contract_notation loc)
|
(fun loc -> Invalid_contract_notation loc)
|
||||||
@ -78,7 +81,6 @@ let is_default = function
|
|||||||
| Default m -> Some m
|
| Default m -> Some m
|
||||||
| Originated _ -> None
|
| Originated _ -> None
|
||||||
|
|
||||||
|
|
||||||
type origination_nonce =
|
type origination_nonce =
|
||||||
{ operation_hash: Operation_hash.t ;
|
{ operation_hash: Operation_hash.t ;
|
||||||
origination_index: int32 }
|
origination_index: int32 }
|
||||||
|
@ -16,27 +16,42 @@ type contract = t
|
|||||||
|
|
||||||
include Compare.S with type t := contract
|
include Compare.S with type t := contract
|
||||||
|
|
||||||
|
(** {2 Default contracts} *****************************************************)
|
||||||
|
|
||||||
val default_contract : Ed25519.Public_key_hash.t -> contract
|
val default_contract : Ed25519.Public_key_hash.t -> contract
|
||||||
|
|
||||||
val is_default : contract -> Ed25519.Public_key_hash.t option
|
val is_default : contract -> Ed25519.Public_key_hash.t option
|
||||||
|
|
||||||
|
(** {2 Originated contracts} **************************************************)
|
||||||
|
|
||||||
|
(** Originated contracts handles are crafted from the hash of the
|
||||||
|
operation that triggered their origination (and nothing else).
|
||||||
|
As a single operation can trigger several originations, the
|
||||||
|
corresponding handles are forged from a deterministic sequence of
|
||||||
|
nonces, initialized with the hash of the operation. *)
|
||||||
type origination_nonce
|
type origination_nonce
|
||||||
|
|
||||||
val originated_contract : origination_nonce -> contract
|
val originated_contract : origination_nonce -> contract
|
||||||
|
|
||||||
val originated_contracts : origination_nonce -> contract list
|
val originated_contracts : origination_nonce -> contract list
|
||||||
|
|
||||||
val initial_origination_nonce : Operation_hash.t -> origination_nonce
|
val initial_origination_nonce : Operation_hash.t -> origination_nonce
|
||||||
|
|
||||||
val incr_origination_nonce : origination_nonce -> origination_nonce
|
val incr_origination_nonce : origination_nonce -> origination_nonce
|
||||||
|
|
||||||
|
|
||||||
(** {2 Human readable notation} ***********************************************)
|
(** {2 Human readable notation} ***********************************************)
|
||||||
|
|
||||||
type error += Invalid_contract_notation of string
|
type error += Invalid_contract_notation of string (* `Permanent *)
|
||||||
|
|
||||||
val to_b58check: contract -> string
|
val to_b58check: contract -> string
|
||||||
|
|
||||||
val of_b58check: string -> contract tzresult
|
val of_b58check: string -> contract tzresult
|
||||||
|
|
||||||
|
val pp: Format.formatter -> contract -> unit
|
||||||
|
|
||||||
|
val pp_short: Format.formatter -> contract -> unit
|
||||||
|
|
||||||
(** {2 Serializers} ***********************************************************)
|
(** {2 Serializers} ***********************************************************)
|
||||||
|
|
||||||
val encoding : contract Data_encoding.t
|
val encoding : contract Data_encoding.t
|
||||||
|
@ -8,64 +8,71 @@
|
|||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
type error +=
|
type error +=
|
||||||
| Balance_too_low of Contract_repr.contract * Tez_repr.t * Tez_repr.t
|
| Initial_amount_too_low of Contract_repr.contract * Tez_repr.t * Tez_repr.t (* `Permanent *)
|
||||||
| Initial_amount_too_low of Tez_repr.t * Tez_repr.t
|
| Balance_too_low of Contract_repr.contract * Tez_repr.t * Tez_repr.t (* `Temporary *)
|
||||||
| Counter_in_the_past of Contract_repr.contract * int32 * int32
|
| Cannot_pay_storage_fee of Contract_repr.contract * Tez_repr.t * Tez_repr.t (* `Temporary *)
|
||||||
| Counter_in_the_future of Contract_repr.contract * int32 * int32
|
| Counter_in_the_past of Contract_repr.contract * int32 * int32 (* `Branch *)
|
||||||
| Unspendable_contract of Contract_repr.contract
|
| Counter_in_the_future of Contract_repr.contract * int32 * int32 (* `Temporary *)
|
||||||
| Non_existing_contract (* TODO: DOC *)
|
| Unspendable_contract of Contract_repr.contract (* `Permanent *)
|
||||||
| No_delegate (* TODO: DOC *)
|
| Non_existing_contract of Contract_repr.contract (* `Temporary *)
|
||||||
| Undelagatable_contract (* TODO: DOC *)
|
| Undelagatable_contract of Contract_repr.contract (* `Permanent *)
|
||||||
| Failure of string
|
| Failure of string (* `Permanent *)
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
register_error_kind
|
|
||||||
`Permanent
|
|
||||||
~id:"contract.failure"
|
|
||||||
~title:"Contract storage failure"
|
|
||||||
~description:"Unexpected contract storage error"
|
|
||||||
~pp:(fun ppf s -> Format.fprintf ppf "Contract_storage.Failure %S" s)
|
|
||||||
Data_encoding.(obj1 (req "message" string))
|
|
||||||
(function Failure s -> Some s | _ -> None)
|
|
||||||
(fun s -> Failure s) ;
|
|
||||||
register_error_kind
|
register_error_kind
|
||||||
`Permanent
|
`Permanent
|
||||||
~id:"contract.initial_amount_too_low"
|
~id:"contract.initial_amount_too_low"
|
||||||
~title:"Initial amount too low"
|
~title:"Initial amount too low"
|
||||||
~description:"Not enough tokens provided for an origination"
|
~description:"Not enough tokens provided for an origination"
|
||||||
~pp:(fun ppf (r, p) ->
|
~pp:(fun ppf (c, r, p) ->
|
||||||
Format.fprintf ppf "Initial amount too low (required %a but provided %a)"
|
Format.fprintf ppf "Initial amount of contract %a too low (required %a but provided %a)"
|
||||||
|
Contract_repr.pp c
|
||||||
Tez_repr.pp r Tez_repr.pp p)
|
Tez_repr.pp r Tez_repr.pp p)
|
||||||
Data_encoding.(obj2
|
Data_encoding.(obj3
|
||||||
|
(req "contract" Contract_repr.encoding)
|
||||||
(req "required" Tez_repr.encoding)
|
(req "required" Tez_repr.encoding)
|
||||||
(req "provided" Tez_repr.encoding))
|
(req "provided" Tez_repr.encoding))
|
||||||
(function Initial_amount_too_low (r, p) -> Some (r, p) | _ -> None)
|
(function Initial_amount_too_low (c, r, p) -> Some (c, r, p) | _ -> None)
|
||||||
(fun (r, p) -> Initial_amount_too_low (r, p)) ;
|
(fun (c, r, p) -> Initial_amount_too_low (c, r, p)) ;
|
||||||
register_error_kind
|
register_error_kind
|
||||||
`Branch
|
`Permanent
|
||||||
~id:"contract.unspendable_contract"
|
~id:"contract.unspendable_contract"
|
||||||
~title:"Unspendable contract"
|
~title:"Unspendable contract"
|
||||||
~description:"An operation tried to spend tokens from an unspendable contract"
|
~description:"An operation tried to spend tokens from an unspendable contract"
|
||||||
~pp:(fun ppf c ->
|
~pp:(fun ppf c ->
|
||||||
Format.fprintf ppf "The tokens of contract %s can only be spent by its script"
|
Format.fprintf ppf "The tokens of contract %a can only be spent by its script"
|
||||||
(Contract_repr.to_b58check c))
|
Contract_repr.pp c)
|
||||||
Data_encoding.(obj1 (req "contract" Contract_repr.encoding))
|
Data_encoding.(obj1 (req "contract" Contract_repr.encoding))
|
||||||
(function Unspendable_contract c -> Some c | _ -> None)
|
(function Unspendable_contract c -> Some c | _ -> None)
|
||||||
(fun c -> Unspendable_contract c) ;
|
(fun c -> Unspendable_contract c) ;
|
||||||
register_error_kind
|
register_error_kind
|
||||||
`Temporary
|
`Temporary
|
||||||
~id:"contract.balance_too_low"
|
~id:"contract.balance_too_low"
|
||||||
~title:"Too low balance"
|
~title:"Balance too low"
|
||||||
~description:"An operation tried to spend more tokens than the contract has"
|
~description:"An operation tried to spend more tokens than the contract has"
|
||||||
~pp:(fun ppf (c, b, a) ->
|
~pp:(fun ppf (c, b, a) ->
|
||||||
Format.fprintf ppf "Balance of contract %s too low (%a) to spend %a"
|
Format.fprintf ppf "Balance of contract %a too low (%a) to spend %a"
|
||||||
(Contract_repr.to_b58check c) Tez_repr.pp b Tez_repr.pp a)
|
Contract_repr.pp c Tez_repr.pp b Tez_repr.pp a)
|
||||||
Data_encoding.(obj3
|
Data_encoding.(obj3
|
||||||
(req "contract" Contract_repr.encoding)
|
(req "contract" Contract_repr.encoding)
|
||||||
(req "balance" Tez_repr.encoding)
|
(req "balance" Tez_repr.encoding)
|
||||||
(req "amount" Tez_repr.encoding))
|
(req "amount" Tez_repr.encoding))
|
||||||
(function Balance_too_low (c, b, a) -> Some (c, b, a) | _ -> None)
|
(function Balance_too_low (c, b, a) -> Some (c, b, a) | _ -> None)
|
||||||
(fun (c, b, a) -> Balance_too_low (c, b, a)) ;
|
(fun (c, b, a) -> Balance_too_low (c, b, a)) ;
|
||||||
|
register_error_kind
|
||||||
|
`Temporary
|
||||||
|
~id:"contract.cannot_pay_storage_fee"
|
||||||
|
~title:"Cannot pay storage fee"
|
||||||
|
~description:"The storage fee is higher than the contract balance"
|
||||||
|
~pp:(fun ppf (c, b, a) ->
|
||||||
|
Format.fprintf ppf "Balance of contract %a too low (%a) to pay storage fee %a"
|
||||||
|
Contract_repr.pp c Tez_repr.pp b Tez_repr.pp a)
|
||||||
|
Data_encoding.(obj3
|
||||||
|
(req "contract" Contract_repr.encoding)
|
||||||
|
(req "balance" Tez_repr.encoding)
|
||||||
|
(req "storage_fee" Tez_repr.encoding))
|
||||||
|
(function Cannot_pay_storage_fee (c, b, a) -> Some (c, b, a) | _ -> None)
|
||||||
|
(fun (c, b, a) -> Cannot_pay_storage_fee (c, b, a)) ;
|
||||||
register_error_kind
|
register_error_kind
|
||||||
`Temporary
|
`Temporary
|
||||||
~id:"contract.counter_in_the_future"
|
~id:"contract.counter_in_the_future"
|
||||||
@ -73,8 +80,8 @@ let () =
|
|||||||
~description:"An operation assumed a contract counter in the future"
|
~description:"An operation assumed a contract counter in the future"
|
||||||
~pp:(fun ppf (contract, exp, found) ->
|
~pp:(fun ppf (contract, exp, found) ->
|
||||||
Format.fprintf ppf
|
Format.fprintf ppf
|
||||||
"Counter %ld not yet reached for contract %s (expected %ld)"
|
"Counter %ld not yet reached for contract %a (expected %ld)"
|
||||||
found (Contract_repr.to_b58check contract) exp)
|
found Contract_repr.pp contract exp)
|
||||||
Data_encoding.
|
Data_encoding.
|
||||||
(obj3
|
(obj3
|
||||||
(req "contract" Contract_repr.encoding)
|
(req "contract" Contract_repr.encoding)
|
||||||
@ -89,26 +96,57 @@ let () =
|
|||||||
~description:"An operation assumed a contract counter in the past"
|
~description:"An operation assumed a contract counter in the past"
|
||||||
~pp:(fun ppf (contract, exp, found) ->
|
~pp:(fun ppf (contract, exp, found) ->
|
||||||
Format.fprintf ppf
|
Format.fprintf ppf
|
||||||
"Counter %ld already used for contract %s (expected %ld)"
|
"Counter %ld already used for contract %a (expected %ld)"
|
||||||
found (Contract_repr.to_b58check contract) exp)
|
found Contract_repr.pp contract exp)
|
||||||
Data_encoding.
|
Data_encoding.
|
||||||
(obj3
|
(obj3
|
||||||
(req "contract" Contract_repr.encoding)
|
(req "contract" Contract_repr.encoding)
|
||||||
(req "expected" int32)
|
(req "expected" int32)
|
||||||
(req "found" int32))
|
(req "found" int32))
|
||||||
(function Counter_in_the_past (c, x, y) -> Some (c, x, y) | _ -> None)
|
(function Counter_in_the_past (c, x, y) -> Some (c, x, y) | _ -> None)
|
||||||
(fun (c, x, y) -> Counter_in_the_past (c, x, y))
|
(fun (c, x, y) -> Counter_in_the_past (c, x, y)) ;
|
||||||
|
register_error_kind
|
||||||
|
`Temporary
|
||||||
|
~id:"contract.non_existing_contract"
|
||||||
|
~title:"Non existing contract"
|
||||||
|
~description:"A non default contract handle is not present in the context \
|
||||||
|
(either it never was or it has been destroyed)"
|
||||||
|
~pp:(fun ppf contract ->
|
||||||
|
Format.fprintf ppf "Contract %a does not exist"
|
||||||
|
Contract_repr.pp contract)
|
||||||
|
Data_encoding.(obj1 (req "contract" Contract_repr.encoding))
|
||||||
|
(function Non_existing_contract c -> Some c | _ -> None)
|
||||||
|
(fun c -> Non_existing_contract c) ;
|
||||||
|
register_error_kind
|
||||||
|
`Permanent
|
||||||
|
~id:"contract.undelagatable_contract"
|
||||||
|
~title:"Non delegatable contract"
|
||||||
|
~description:"Tried to delegate a default contract \
|
||||||
|
or a non delegatable originated contract"
|
||||||
|
~pp:(fun ppf contract ->
|
||||||
|
Format.fprintf ppf "Contract %a is not delegatable"
|
||||||
|
Contract_repr.pp contract)
|
||||||
|
Data_encoding.(obj1 (req "contract" Contract_repr.encoding))
|
||||||
|
(function Non_existing_contract c -> Some c | _ -> None)
|
||||||
|
(fun c -> Non_existing_contract c) ;
|
||||||
|
register_error_kind
|
||||||
|
`Permanent
|
||||||
|
~id:"contract.failure"
|
||||||
|
~title:"Contract storage failure"
|
||||||
|
~description:"Unexpected contract storage error"
|
||||||
|
~pp:(fun ppf s -> Format.fprintf ppf "Contract_storage.Failure %S" s)
|
||||||
|
Data_encoding.(obj1 (req "message" string))
|
||||||
|
(function Failure s -> Some s | _ -> None)
|
||||||
|
(fun s -> Failure s)
|
||||||
|
|
||||||
let failwith msg = fail (Failure msg)
|
let failwith msg = fail (Failure msg)
|
||||||
|
|
||||||
let create_base c contract ~balance ~manager ~delegate ~script ~spendable ~delegatable =
|
let create_base c contract ~balance ~manager ~delegate ?script ~spendable ~delegatable =
|
||||||
(match Contract_repr.is_default contract with
|
(match Contract_repr.is_default contract with
|
||||||
| None -> return 0l
|
| None -> return 0l
|
||||||
| Some _ -> Storage.Contract.Global_counter.get c) >>=? fun counter ->
|
| Some _ -> Storage.Contract.Global_counter.get c) >>=? fun counter ->
|
||||||
Storage.Contract.Balance.init c contract balance >>=? fun c ->
|
Storage.Contract.Balance.init c contract balance >>=? fun c ->
|
||||||
Storage.Contract.Manager.init c contract manager >>=? fun c ->
|
Storage.Contract.Manager.init c contract manager >>=? fun c ->
|
||||||
(* TODO, to answer:
|
|
||||||
If the contract is not delegatable, can it be created with a delegate ? *)
|
|
||||||
begin
|
begin
|
||||||
match delegate with
|
match delegate with
|
||||||
| None -> return c
|
| None -> return c
|
||||||
@ -120,26 +158,28 @@ let create_base c contract ~balance ~manager ~delegate ~script ~spendable ~deleg
|
|||||||
Storage.Contract.Assets.init c contract Asset_repr.Map.empty >>=? fun c ->
|
Storage.Contract.Assets.init c contract Asset_repr.Map.empty >>=? fun c ->
|
||||||
Storage.Contract.Counter.init c contract counter >>=? fun c ->
|
Storage.Contract.Counter.init c contract counter >>=? fun c ->
|
||||||
(match script with
|
(match script with
|
||||||
| Script_repr.Script { code ; storage } ->
|
| Some ({ Script_repr.code ; storage }, (code_fees, storage_fees)) ->
|
||||||
Storage.Contract.Code.init c contract code >>=? fun c ->
|
Storage.Contract.Code.init c contract code >>=? fun c ->
|
||||||
Storage.Contract.Storage.init c contract storage
|
Storage.Contract.Storage.init c contract storage >>=? fun c ->
|
||||||
| No_script ->
|
Storage.Contract.Code_fees.init c contract code_fees >>=? fun c ->
|
||||||
|
Storage.Contract.Storage_fees.init c contract storage_fees
|
||||||
|
| None ->
|
||||||
return c) >>=? fun c ->
|
return c) >>=? fun c ->
|
||||||
Roll_storage.Contract.init c contract >>=? fun c ->
|
Roll_storage.Contract.init c contract >>=? fun c ->
|
||||||
Roll_storage.Contract.add_amount c contract balance >>=? fun c ->
|
Roll_storage.Contract.add_amount c contract balance >>=? fun c ->
|
||||||
Storage.Contract.Set.add c contract >>=? fun c ->
|
Storage.Contract.Set.add c contract >>=? fun c ->
|
||||||
Lwt.return (Ok (c, contract))
|
Lwt.return (Ok (c, contract))
|
||||||
|
|
||||||
let create c nonce ~balance ~manager ~delegate ~script ~spendable ~delegatable =
|
let create c nonce ~balance ~manager ~delegate ?script ~spendable ~delegatable =
|
||||||
let contract = Contract_repr.originated_contract nonce in
|
let contract = Contract_repr.originated_contract nonce in
|
||||||
create_base c contract ~balance ~manager ~delegate ~script ~spendable ~delegatable >>=? fun (ctxt, contract) ->
|
create_base c contract ~balance ~manager ~delegate ?script ~spendable ~delegatable >>=? fun (ctxt, contract) ->
|
||||||
return (ctxt, contract, Contract_repr.incr_origination_nonce nonce)
|
return (ctxt, contract, Contract_repr.incr_origination_nonce nonce)
|
||||||
|
|
||||||
let create_default c manager ~balance =
|
let create_default c manager ~balance =
|
||||||
let contract = Contract_repr.default_contract manager in
|
create_base c (Contract_repr.default_contract manager)
|
||||||
create_base c contract ~manager ~delegate:(Some manager)
|
~balance ~manager ~delegate:(Some manager)
|
||||||
~spendable:true ~delegatable:false ~script:Script_repr.No_script
|
?script:None
|
||||||
~balance
|
~spendable:true ~delegatable:false
|
||||||
|
|
||||||
let delete c contract =
|
let delete c contract =
|
||||||
Storage.Contract.Balance.get c contract >>=? fun balance ->
|
Storage.Contract.Balance.get c contract >>=? fun balance ->
|
||||||
@ -153,6 +193,8 @@ let delete c contract =
|
|||||||
Storage.Contract.Counter.delete c contract >>=? fun c ->
|
Storage.Contract.Counter.delete c contract >>=? fun c ->
|
||||||
Storage.Contract.Code.remove c contract >>= fun c ->
|
Storage.Contract.Code.remove c contract >>= fun c ->
|
||||||
Storage.Contract.Storage.remove c contract >>= fun c ->
|
Storage.Contract.Storage.remove c contract >>= fun c ->
|
||||||
|
Storage.Contract.Code_fees.remove c contract >>= fun c ->
|
||||||
|
Storage.Contract.Storage_fees.remove c contract >>= fun c ->
|
||||||
Storage.Contract.Set.del c contract
|
Storage.Contract.Set.del c contract
|
||||||
|
|
||||||
let exists c contract =
|
let exists c contract =
|
||||||
@ -163,6 +205,11 @@ let exists c contract =
|
|||||||
| None -> return false
|
| None -> return false
|
||||||
| Some _ -> return true
|
| Some _ -> return true
|
||||||
|
|
||||||
|
let must_exist c contract =
|
||||||
|
exists c contract >>=? function
|
||||||
|
| true -> return ()
|
||||||
|
| false -> fail (Non_existing_contract contract)
|
||||||
|
|
||||||
let list c =
|
let list c =
|
||||||
Storage.Contract.Set.elements c
|
Storage.Contract.Set.elements c
|
||||||
|
|
||||||
@ -186,8 +233,8 @@ let get_script c contract =
|
|||||||
Storage.Contract.Code.get_option c contract >>=? fun code ->
|
Storage.Contract.Code.get_option c contract >>=? fun code ->
|
||||||
Storage.Contract.Storage.get_option c contract >>=? fun storage ->
|
Storage.Contract.Storage.get_option c contract >>=? fun storage ->
|
||||||
match code, storage with
|
match code, storage with
|
||||||
| None, None -> return Script_repr.No_script
|
| None, None -> return None
|
||||||
| Some code, Some storage -> return (Script_repr.Script { code ; storage })
|
| Some code, Some storage -> return (Some { Script_repr.code ; storage })
|
||||||
| None, Some _ | Some _, None -> failwith "get_script"
|
| None, Some _ | Some _, None -> failwith "get_script"
|
||||||
|
|
||||||
let get_counter c contract =
|
let get_counter c contract =
|
||||||
@ -210,11 +257,6 @@ let get_manager c contract =
|
|||||||
|
|
||||||
let get_delegate_opt = Roll_storage.get_contract_delegate
|
let get_delegate_opt = Roll_storage.get_contract_delegate
|
||||||
|
|
||||||
let get_delegate c contract =
|
|
||||||
get_delegate_opt c contract >>=? function
|
|
||||||
| None -> fail No_delegate
|
|
||||||
| Some delegate -> return delegate
|
|
||||||
|
|
||||||
let get_balance c contract =
|
let get_balance c contract =
|
||||||
Storage.Contract.Balance.get_option c contract >>=? function
|
Storage.Contract.Balance.get_option c contract >>=? function
|
||||||
| None -> begin
|
| None -> begin
|
||||||
@ -255,7 +297,7 @@ let set_delegate c contract delegate =
|
|||||||
(* A contract delegate can be set only if the contract is delegatable *)
|
(* A contract delegate can be set only if the contract is delegatable *)
|
||||||
Storage.Contract.Delegatable.get c contract >>=? fun delegatable ->
|
Storage.Contract.Delegatable.get c contract >>=? fun delegatable ->
|
||||||
if not delegatable
|
if not delegatable
|
||||||
then fail Undelagatable_contract
|
then fail (Undelagatable_contract contract)
|
||||||
else
|
else
|
||||||
match delegate with
|
match delegate with
|
||||||
| None ->
|
| None ->
|
||||||
@ -264,61 +306,56 @@ let set_delegate c contract delegate =
|
|||||||
| Some delegate ->
|
| Some delegate ->
|
||||||
Storage.Contract.Delegate.init_set c contract delegate
|
Storage.Contract.Delegate.init_set c contract delegate
|
||||||
|
|
||||||
let script_storage_fee script =
|
let contract_fee c contract =
|
||||||
match script with
|
Storage.Contract.Code_fees.get_option c contract >>=? fun code_fees ->
|
||||||
| Script_repr.No_script -> return Constants_repr.minimal_contract_balance
|
Storage.Contract.Storage_fees.get_option c contract >>=? fun storage_fees ->
|
||||||
| Script { code ; storage } ->
|
match code_fees, storage_fees with
|
||||||
let storage_fee = Script_repr.storage_cost storage in
|
| (None, Some _) | (Some _, None) -> failwith "contract_fee"
|
||||||
let code_fee = Script_repr.code_cost code in
|
| None, None ->
|
||||||
Lwt.return Tez_repr.(code_fee +? storage_fee) >>=? fun script_fee ->
|
return Constants_repr.minimal_contract_balance
|
||||||
Lwt.return Tez_repr.(Constants_repr.minimal_contract_balance +? script_fee)
|
| Some code_fees, Some storage_fees ->
|
||||||
|
Lwt.return Tez_repr.(code_fees +? storage_fees) >>=? fun script_fees ->
|
||||||
|
Lwt.return Tez_repr.(Constants_repr.minimal_contract_balance +? script_fees)
|
||||||
|
|
||||||
let update_script_storage c contract storage =
|
let update_script_storage_and_fees c contract storage_fees storage =
|
||||||
let open Script_repr in
|
let open Script_repr in
|
||||||
Storage.Contract.Balance.get_option c contract >>=? function
|
Storage.Contract.Balance.get_option c contract >>=? function
|
||||||
| None ->
|
| None ->
|
||||||
(* The contract was destroyed *)
|
(* The contract was destroyed *)
|
||||||
return c
|
return c
|
||||||
| Some balance ->
|
| Some balance ->
|
||||||
get_script c contract >>=? function
|
Storage.Contract.Storage.get c contract >>=? fun { storage_type } ->
|
||||||
| No_script -> failwith "update_script_storage"
|
Storage.Contract.Storage_fees.set c contract storage_fees >>=? fun c ->
|
||||||
| Script { code ; storage = { storage_type } } ->
|
contract_fee c contract >>=? fun fee ->
|
||||||
script_storage_fee
|
fail_unless Tez_repr.(balance > fee)
|
||||||
(Script_repr.Script { code ; storage = { storage; storage_type }}) >>=? fun fee ->
|
(Cannot_pay_storage_fee (contract, balance, fee)) >>=? fun () ->
|
||||||
fail_unless Tez_repr.(balance > fee)
|
Storage.Contract.Storage.set c contract { storage; storage_type }
|
||||||
(Balance_too_low (contract, balance, fee)) >>=? fun () ->
|
|
||||||
Storage.Contract.Storage.set c contract { storage; storage_type }
|
|
||||||
|
|
||||||
let unconditional_spend c contract amount =
|
let spend_from_script c contract amount =
|
||||||
Storage.Contract.Balance.get c contract >>=? fun balance ->
|
Storage.Contract.Balance.get c contract >>=? fun balance ->
|
||||||
match Tez_repr.(balance - amount) with
|
Lwt.return Tez_repr.(balance -? amount) |>
|
||||||
| None ->
|
trace (Balance_too_low (contract, balance, amount)) >>=? fun new_balance ->
|
||||||
fail (Balance_too_low (contract, balance, amount))
|
contract_fee c contract >>=? fun fee ->
|
||||||
| Some new_balance ->
|
if Tez_repr.(new_balance > fee) then
|
||||||
get_script c contract >>=? fun script ->
|
Storage.Contract.Balance.set c contract new_balance >>=? fun c ->
|
||||||
script_storage_fee script >>=? fun fee ->
|
Roll_storage.Contract.remove_amount c contract amount
|
||||||
if Tez_repr.(fee <= new_balance) then
|
else
|
||||||
Storage.Contract.Balance.set c contract new_balance >>=? fun c ->
|
(* TODO: do we really want to allow overspending ? *)
|
||||||
Roll_storage.Contract.remove_amount c contract amount
|
delete c contract
|
||||||
else
|
|
||||||
delete c contract
|
|
||||||
|
|
||||||
let credit c contract amount =
|
let credit c contract amount =
|
||||||
Storage.Contract.Balance.get_option c contract >>=? function
|
Storage.Contract.Balance.get_option c contract >>=? function
|
||||||
| None -> begin
|
| None -> begin
|
||||||
(* If the contract does not exists and it is a default contract,
|
|
||||||
create it *)
|
|
||||||
match Contract_repr.is_default contract with
|
match Contract_repr.is_default contract with
|
||||||
| None -> fail Non_existing_contract
|
| None -> fail (Non_existing_contract contract)
|
||||||
| Some manager ->
|
| Some manager ->
|
||||||
if Tez_repr.(amount < Constants_repr.minimal_contract_balance)
|
if Tez_repr.(amount < Constants_repr.minimal_contract_balance)
|
||||||
then
|
then
|
||||||
(* If this is not enough to maintain the contract alive,
|
(* Not enough to keep a default contract alive: burn the tokens *)
|
||||||
we just drop the money *)
|
|
||||||
return c
|
return c
|
||||||
else
|
else
|
||||||
|
(* Otherwise, create the default contract. *)
|
||||||
create_default c manager ~balance:amount >>=? fun (c, _) ->
|
create_default c manager ~balance:amount >>=? fun (c, _) ->
|
||||||
(* TODO: fail_unless Contract_repr.(contract = new_contract) still needed ?? *)
|
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
| Some balance ->
|
| Some balance ->
|
||||||
@ -339,16 +376,15 @@ let spend c contract amount =
|
|||||||
Storage.Contract.Spendable.get c contract >>=? fun spendable ->
|
Storage.Contract.Spendable.get c contract >>=? fun spendable ->
|
||||||
if not spendable
|
if not spendable
|
||||||
then fail (Unspendable_contract contract)
|
then fail (Unspendable_contract contract)
|
||||||
else unconditional_spend c contract amount
|
else spend_from_script c contract amount
|
||||||
|
|
||||||
let originate c nonce ~balance ~manager ~script ~delegate ~spendable ~delegatable =
|
let originate c nonce ~balance ~manager ?script ~delegate ~spendable ~delegatable =
|
||||||
script_storage_fee script >>=? fun fee ->
|
create c nonce ~balance ~manager ~delegate ?script ~spendable ~delegatable >>=? fun (c, contract, nonce) ->
|
||||||
|
(* check contract fee *)
|
||||||
|
contract_fee c contract >>=? fun fee ->
|
||||||
fail_unless Tez_repr.(balance > fee)
|
fail_unless Tez_repr.(balance > fee)
|
||||||
(Initial_amount_too_low (fee, balance)) >>=? fun () ->
|
(Initial_amount_too_low (contract, balance, fee)) >>=? fun () ->
|
||||||
create c nonce ~balance ~manager ~delegate ~script ~spendable ~delegatable
|
return (c, contract, nonce)
|
||||||
|
|
||||||
let init c =
|
let init c =
|
||||||
Storage.Contract.Global_counter.init c 0l
|
Storage.Contract.Global_counter.init c 0l
|
||||||
|
|
||||||
let pp fmt c =
|
|
||||||
Format.pp_print_string fmt (Contract_repr.to_b58check c)
|
|
||||||
|
@ -8,19 +8,20 @@
|
|||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
type error +=
|
type error +=
|
||||||
| Balance_too_low of Contract_repr.contract * Tez_repr.t * Tez_repr.t
|
| Initial_amount_too_low of Contract_repr.contract * Tez_repr.t * Tez_repr.t (* `Permanent *)
|
||||||
| Initial_amount_too_low of Tez_repr.t * Tez_repr.t
|
| Balance_too_low of Contract_repr.contract * Tez_repr.t * Tez_repr.t (* `Temporary *)
|
||||||
| Counter_in_the_past of Contract_repr.contract * int32 * int32
|
| Cannot_pay_storage_fee of Contract_repr.contract * Tez_repr.t * Tez_repr.t (* `Temporary *)
|
||||||
| Counter_in_the_future of Contract_repr.contract * int32 * int32
|
| Counter_in_the_past of Contract_repr.contract * int32 * int32 (* `Branch *)
|
||||||
| Unspendable_contract of Contract_repr.contract
|
| Counter_in_the_future of Contract_repr.contract * int32 * int32 (* `Temporary *)
|
||||||
| Non_existing_contract
|
| Unspendable_contract of Contract_repr.contract (* `Permanent *)
|
||||||
| No_delegate
|
| Non_existing_contract of Contract_repr.contract (* `Temporary *)
|
||||||
| Undelagatable_contract
|
| Undelagatable_contract of Contract_repr.contract (* `Permanent *)
|
||||||
| Failure of string
|
| Failure of string (* `Permanent *)
|
||||||
|
|
||||||
val delete : Storage.t -> Contract_repr.t -> Storage.t tzresult Lwt.t
|
val delete : Storage.t -> Contract_repr.t -> Storage.t tzresult Lwt.t
|
||||||
|
|
||||||
val exists: Storage.t -> Contract_repr.t -> bool tzresult Lwt.t
|
val exists: Storage.t -> Contract_repr.t -> bool tzresult Lwt.t
|
||||||
|
val must_exist: Storage.t -> Contract_repr.t -> unit tzresult Lwt.t
|
||||||
|
|
||||||
val list: Storage.t -> Contract_repr.t list tzresult Lwt.t
|
val list: Storage.t -> Contract_repr.t list tzresult Lwt.t
|
||||||
|
|
||||||
@ -31,19 +32,14 @@ val is_delegatable : Storage.t -> Contract_repr.t -> bool tzresult Lwt.t
|
|||||||
val is_spendable : Storage.t -> Contract_repr.t -> bool tzresult Lwt.t
|
val is_spendable : Storage.t -> Contract_repr.t -> bool tzresult Lwt.t
|
||||||
|
|
||||||
val get_manager: Storage.t -> Contract_repr.t -> Ed25519.Public_key_hash.t tzresult Lwt.t
|
val get_manager: Storage.t -> Contract_repr.t -> Ed25519.Public_key_hash.t tzresult Lwt.t
|
||||||
val get_delegate: Storage.t -> Contract_repr.t -> Ed25519.Public_key_hash.t tzresult Lwt.t
|
|
||||||
val get_delegate_opt: Storage.t -> Contract_repr.t -> Ed25519.Public_key_hash.t option tzresult Lwt.t
|
val get_delegate_opt: Storage.t -> Contract_repr.t -> Ed25519.Public_key_hash.t option tzresult Lwt.t
|
||||||
val get_balance: Storage.t -> Contract_repr.t -> Tez_repr.t tzresult Lwt.t
|
val get_balance: Storage.t -> Contract_repr.t -> Tez_repr.t tzresult Lwt.t
|
||||||
val get_assets: Storage.t -> Contract_repr.t -> Asset_repr.Map.t tzresult Lwt.t
|
val get_assets: Storage.t -> Contract_repr.t -> Asset_repr.Map.t tzresult Lwt.t
|
||||||
val get_counter: Storage.t -> Contract_repr.t -> int32 tzresult Lwt.t
|
val get_counter: Storage.t -> Contract_repr.t -> int32 tzresult Lwt.t
|
||||||
|
|
||||||
val get_script: Storage.t -> Contract_repr.t -> Script_repr.t tzresult Lwt.t
|
val get_script: Storage.t -> Contract_repr.t -> Script_repr.t option tzresult Lwt.t
|
||||||
|
|
||||||
(** Update_script_storage fails if the contract has not enouth tez to
|
val update_script_storage_and_fees: Storage.t -> Contract_repr.t -> Tez_repr.t -> Script_repr.expr -> Storage.t tzresult Lwt.t
|
||||||
store the new data.
|
|
||||||
It does not fail if the contract does not exists *)
|
|
||||||
val update_script_storage: Storage.t -> Contract_repr.t -> Script_repr.expr ->
|
|
||||||
Storage.t tzresult Lwt.t
|
|
||||||
|
|
||||||
(** fails if the contract is not delegatable *)
|
(** fails if the contract is not delegatable *)
|
||||||
val set_delegate : Storage.t -> Contract_repr.t -> Ed25519.Public_key_hash.t option -> Storage.t tzresult Lwt.t
|
val set_delegate : Storage.t -> Contract_repr.t -> Ed25519.Public_key_hash.t option -> Storage.t tzresult Lwt.t
|
||||||
@ -53,8 +49,8 @@ val credit : Storage.t -> Contract_repr.t -> Tez_repr.t -> Storage.t tzresult Lw
|
|||||||
(** checks that the contract is spendable and decrease_balance *)
|
(** checks that the contract is spendable and decrease_balance *)
|
||||||
val spend : Storage.t -> Contract_repr.t -> Tez_repr.t -> Storage.t tzresult Lwt.t
|
val spend : Storage.t -> Contract_repr.t -> Tez_repr.t -> Storage.t tzresult Lwt.t
|
||||||
|
|
||||||
(* decrease balance uncondionally *)
|
(** decrease_balance even if the contract is not spendable *)
|
||||||
val unconditional_spend : Storage.t -> Contract_repr.t -> Tez_repr.t -> Storage.t tzresult Lwt.t
|
val spend_from_script : Storage.t -> Contract_repr.t -> Tez_repr.t -> Storage.t tzresult Lwt.t
|
||||||
|
|
||||||
val issue :
|
val issue :
|
||||||
Storage.t -> Contract_repr.t -> Asset_repr.t -> Ed25519.Public_key_hash.t -> Tez_repr.t -> Storage.t tzresult Lwt.t
|
Storage.t -> Contract_repr.t -> Asset_repr.t -> Ed25519.Public_key_hash.t -> Tez_repr.t -> Storage.t tzresult Lwt.t
|
||||||
@ -64,7 +60,7 @@ val originate :
|
|||||||
Contract_repr.origination_nonce ->
|
Contract_repr.origination_nonce ->
|
||||||
balance:Tez_repr.t ->
|
balance:Tez_repr.t ->
|
||||||
manager:Ed25519.Public_key_hash.t ->
|
manager:Ed25519.Public_key_hash.t ->
|
||||||
script:Script_repr.t ->
|
?script:(Script_repr.t * (Tez_repr.t * Tez_repr.t)) ->
|
||||||
delegate:Ed25519.Public_key_hash.t option ->
|
delegate:Ed25519.Public_key_hash.t option ->
|
||||||
spendable:bool ->
|
spendable:bool ->
|
||||||
delegatable:bool ->
|
delegatable:bool ->
|
||||||
@ -72,5 +68,3 @@ val originate :
|
|||||||
|
|
||||||
val init :
|
val init :
|
||||||
Storage.t -> Storage.t tzresult Lwt.t
|
Storage.t -> Storage.t tzresult Lwt.t
|
||||||
|
|
||||||
val pp: Format.formatter -> Contract_repr.t -> unit
|
|
||||||
|
@ -76,13 +76,12 @@ let pay_mining_bond c
|
|||||||
if Compare.Int32.(priority >= Constants.first_free_mining_slot c)
|
if Compare.Int32.(priority >= Constants.first_free_mining_slot c)
|
||||||
then return c
|
then return c
|
||||||
else
|
else
|
||||||
Contract.unconditional_spend c
|
Contract.spend c (Contract.default_contract id) Constants.mining_bond_cost
|
||||||
(Contract.default_contract id) Constants.mining_bond_cost
|
|
||||||
|> trace Cannot_pay_mining_bond
|
|> trace Cannot_pay_mining_bond
|
||||||
|
|
||||||
let pay_endorsement_bond c id =
|
let pay_endorsement_bond c id =
|
||||||
let bond = Constants.endorsement_bond_cost in
|
let bond = Constants.endorsement_bond_cost in
|
||||||
Contract.unconditional_spend c (Contract.default_contract id) bond
|
Contract.spend c (Contract.default_contract id) bond
|
||||||
|> trace Cannot_pay_endorsement_bond >>=? fun c ->
|
|> trace Cannot_pay_endorsement_bond >>=? fun c ->
|
||||||
return (c, bond)
|
return (c, bond)
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ and manager_operation =
|
|||||||
| Origination of {
|
| Origination of {
|
||||||
manager: Ed25519.Public_key_hash.t ;
|
manager: Ed25519.Public_key_hash.t ;
|
||||||
delegate: Ed25519.Public_key_hash.t option ;
|
delegate: Ed25519.Public_key_hash.t option ;
|
||||||
script: Script_repr.t ;
|
script: Script_repr.t option ;
|
||||||
spendable: bool ;
|
spendable: bool ;
|
||||||
delegatable: bool ;
|
delegatable: bool ;
|
||||||
credit: Tez_repr.tez ;
|
credit: Tez_repr.tez ;
|
||||||
@ -113,7 +113,7 @@ module Encoding = struct
|
|||||||
(opt "spendable" bool)
|
(opt "spendable" bool)
|
||||||
(opt "delegatable" bool)
|
(opt "delegatable" bool)
|
||||||
(opt "delegate" Ed25519.Public_key_hash.encoding)
|
(opt "delegate" Ed25519.Public_key_hash.encoding)
|
||||||
(req "script" Script_repr.encoding))
|
(opt "script" Script_repr.encoding))
|
||||||
|
|
||||||
let origination_case tag =
|
let origination_case tag =
|
||||||
case ~tag origination_encoding
|
case ~tag origination_encoding
|
||||||
|
@ -53,7 +53,7 @@ and manager_operation =
|
|||||||
| Origination of {
|
| Origination of {
|
||||||
manager: Ed25519.Public_key_hash.t ;
|
manager: Ed25519.Public_key_hash.t ;
|
||||||
delegate: Ed25519.Public_key_hash.t option ;
|
delegate: Ed25519.Public_key_hash.t option ;
|
||||||
script: Script_repr.t ;
|
script: Script_repr.t option ;
|
||||||
spendable: bool ;
|
spendable: bool ;
|
||||||
delegatable: bool ;
|
delegatable: bool ;
|
||||||
credit: Tez_repr.tez ;
|
credit: Tez_repr.tez ;
|
||||||
|
@ -13,6 +13,9 @@ open Script
|
|||||||
open Script_typed_ir
|
open Script_typed_ir
|
||||||
open Script_ir_translator
|
open Script_ir_translator
|
||||||
|
|
||||||
|
let dummy_code_fee = Tez.zero
|
||||||
|
let dummy_storage_fee = Tez.zero
|
||||||
|
|
||||||
(* ---- Run-time errors -----------------------------------------------------*)
|
(* ---- Run-time errors -----------------------------------------------------*)
|
||||||
|
|
||||||
type error += Quota_exceeded
|
type error += Quota_exceeded
|
||||||
@ -394,65 +397,64 @@ let rec interp
|
|||||||
logged_return (Item (manager, rest), qta - 1, ctxt)
|
logged_return (Item (manager, rest), qta - 1, ctxt)
|
||||||
| Transfer_tokens storage_type,
|
| Transfer_tokens storage_type,
|
||||||
Item (p, Item (amount, Item ((tp, Unit_t, destination), Item (sto, Empty)))) -> begin
|
Item (p, Item (amount, Item ((tp, Unit_t, destination), Item (sto, Empty)))) -> begin
|
||||||
Contract.unconditional_spend ctxt source amount >>=? fun ctxt ->
|
Contract.spend_from_script ctxt source amount >>=? fun ctxt ->
|
||||||
|
Lwt.return Tez.(amount -? Constants.origination_burn) >>=? fun amount ->
|
||||||
Contract.credit ctxt destination amount >>=? fun ctxt ->
|
Contract.credit ctxt destination amount >>=? fun ctxt ->
|
||||||
Contract.get_script ctxt destination >>=? fun destination_script ->
|
Contract.get_script ctxt destination >>=? fun destination_script ->
|
||||||
let sto = unparse_data storage_type sto in
|
let sto = unparse_data storage_type sto in
|
||||||
Contract.update_script_storage ctxt source sto >>=? fun ctxt ->
|
Contract.update_script_storage_and_fees ctxt source dummy_storage_fee sto >>=? fun ctxt ->
|
||||||
begin match destination_script with
|
begin match destination_script with
|
||||||
| No_script ->
|
| None ->
|
||||||
(* we see non scripted contracts as (unit, unit) contract *)
|
(* we see non scripted contracts as (unit, unit) contract *)
|
||||||
Lwt.return (ty_eq tp Unit_t |>
|
Lwt.return (ty_eq tp Unit_t |>
|
||||||
record_trace (Invalid_contract (loc, destination))) >>=? fun (Eq _) ->
|
record_trace (Invalid_contract (loc, destination))) >>=? fun (Eq _) ->
|
||||||
return (ctxt, qta, origination)
|
return (ctxt, qta, origination)
|
||||||
| Script { code ; storage } ->
|
| Some { code ; storage } ->
|
||||||
let p = unparse_data tp p in
|
let p = unparse_data tp p in
|
||||||
execute origination source destination ctxt storage code amount p qta
|
execute origination source destination ctxt storage code amount p qta
|
||||||
>>=? fun (csto, ret, qta, ctxt, origination) ->
|
>>=? fun (csto, ret, qta, ctxt, origination) ->
|
||||||
Contract.update_script_storage
|
Contract.update_script_storage_and_fees ctxt destination dummy_storage_fee csto >>=? fun ctxt ->
|
||||||
ctxt destination csto >>=? fun ctxt ->
|
|
||||||
trace
|
trace
|
||||||
(Invalid_contract (loc, destination))
|
(Invalid_contract (loc, destination))
|
||||||
(parse_data ctxt Unit_t ret) >>=? fun () ->
|
(parse_data ctxt Unit_t ret) >>=? fun () ->
|
||||||
return (ctxt, qta, origination)
|
return (ctxt, qta, origination)
|
||||||
end >>=? fun (ctxt, qta, origination) ->
|
end >>=? fun (ctxt, qta, origination) ->
|
||||||
Contract.get_script ctxt source >>=? (function
|
Contract.get_script ctxt source >>=? (function
|
||||||
| No_script -> assert false
|
| None -> assert false
|
||||||
| Script { storage = { storage } } ->
|
| Some { storage = { storage } } ->
|
||||||
parse_data ctxt storage_type storage >>=? fun sto ->
|
parse_data ctxt storage_type storage >>=? fun sto ->
|
||||||
logged_return ~origination (Item ((), Item (sto, Empty)), qta - 1, ctxt))
|
logged_return ~origination (Item ((), Item (sto, Empty)), qta - 1, ctxt))
|
||||||
end
|
end
|
||||||
| Transfer_tokens storage_type,
|
| Transfer_tokens storage_type,
|
||||||
Item (p, Item (amount, Item ((tp, tr, destination), Item (sto, Empty)))) -> begin
|
Item (p, Item (amount, Item ((tp, tr, destination), Item (sto, Empty)))) -> begin
|
||||||
Contract.unconditional_spend ctxt source amount >>=? fun ctxt ->
|
Contract.spend_from_script ctxt source amount >>=? fun ctxt ->
|
||||||
Contract.credit ctxt destination amount >>=? fun ctxt ->
|
Contract.credit ctxt destination amount >>=? fun ctxt ->
|
||||||
Contract.get_script ctxt destination >>=? function
|
Contract.get_script ctxt destination >>=? function
|
||||||
| No_script -> fail (Invalid_contract (loc, destination))
|
| None -> fail (Invalid_contract (loc, destination))
|
||||||
| Script { code ; storage } ->
|
| Some { code ; storage } ->
|
||||||
let sto = unparse_data storage_type sto in
|
let sto = unparse_data storage_type sto in
|
||||||
Contract.update_script_storage ctxt source sto >>=? fun ctxt ->
|
Contract.update_script_storage_and_fees ctxt source dummy_storage_fee sto >>=? fun ctxt ->
|
||||||
let p = unparse_data tp p in
|
let p = unparse_data tp p in
|
||||||
execute origination source destination ctxt storage code amount p qta
|
execute origination source destination ctxt storage code amount p qta
|
||||||
>>=? fun (sto, ret, qta, ctxt, origination) ->
|
>>=? fun (sto, ret, qta, ctxt, origination) ->
|
||||||
Contract.update_script_storage
|
Contract.update_script_storage_and_fees ctxt destination dummy_storage_fee sto >>=? fun ctxt ->
|
||||||
ctxt destination sto >>=? fun ctxt ->
|
|
||||||
trace
|
trace
|
||||||
(Invalid_contract (loc, destination))
|
(Invalid_contract (loc, destination))
|
||||||
(parse_data ctxt tr ret) >>=? fun v ->
|
(parse_data ctxt tr ret) >>=? fun v ->
|
||||||
Contract.get_script ctxt source >>=? (function
|
Contract.get_script ctxt source >>=? (function
|
||||||
| No_script -> assert false
|
| None -> assert false
|
||||||
| Script { storage = { storage } } ->
|
| Some { storage = { storage } } ->
|
||||||
parse_data ctxt storage_type storage >>=? fun sto ->
|
parse_data ctxt storage_type storage >>=? fun sto ->
|
||||||
logged_return ~origination (Item (v, Item (sto, Empty)), qta - 1, ctxt))
|
logged_return ~origination (Item (v, Item (sto, Empty)), qta - 1, ctxt))
|
||||||
end
|
end
|
||||||
| Create_account,
|
| Create_account,
|
||||||
Item (manager, Item (delegate, Item (delegatable, Item (credit, rest)))) ->
|
Item (manager, Item (delegate, Item (delegatable, Item (credit, rest)))) ->
|
||||||
Contract.unconditional_spend ctxt source credit >>=? fun ctxt ->
|
Contract.spend_from_script ctxt source credit >>=? fun ctxt ->
|
||||||
Lwt.return Tez.(credit -? Constants.origination_burn) >>=? fun balance ->
|
Lwt.return Tez.(credit -? Constants.origination_burn) >>=? fun balance ->
|
||||||
Contract.originate ctxt
|
Contract.originate ctxt
|
||||||
origination
|
origination
|
||||||
~manager ~delegate ~balance
|
~manager ~delegate ~balance
|
||||||
~script:No_script ~spendable:true ~delegatable >>=? fun (ctxt, contract, origination) ->
|
?script:None ~spendable:true ~delegatable >>=? fun (ctxt, contract, origination) ->
|
||||||
logged_return ~origination (Item ((Unit_t, Unit_t, contract), rest), qta - 1, ctxt)
|
logged_return ~origination (Item ((Unit_t, Unit_t, contract), rest), qta - 1, ctxt)
|
||||||
| Create_contract (g, p, r),
|
| Create_contract (g, p, r),
|
||||||
Item (manager, Item (delegate, Item (delegatable, Item (credit,
|
Item (manager, Item (delegate, Item (delegatable, Item (credit,
|
||||||
@ -460,19 +462,13 @@ let rec interp
|
|||||||
let code, storage =
|
let code, storage =
|
||||||
{ code; arg_type = unparse_ty p; ret_type = unparse_ty r; storage_type = unparse_ty g },
|
{ code; arg_type = unparse_ty p; ret_type = unparse_ty r; storage_type = unparse_ty g },
|
||||||
{ storage = unparse_data g init; storage_type = unparse_ty g } in
|
{ storage = unparse_data g init; storage_type = unparse_ty g } in
|
||||||
let storage_fee = Script.storage_cost storage in
|
Contract.spend_from_script ctxt source credit >>=? fun ctxt ->
|
||||||
let code_fee = Script.code_cost code in
|
|
||||||
Lwt.return Tez.(code_fee +? storage_fee) >>=? fun script_fee ->
|
|
||||||
Lwt.return Tez.(script_fee +?
|
|
||||||
Constants.origination_burn) >>=? fun total_fee ->
|
|
||||||
fail_unless Tez.(credit > total_fee)
|
|
||||||
(Contract.Initial_amount_too_low (total_fee, credit)) >>=? fun () ->
|
|
||||||
Contract.unconditional_spend ctxt source credit >>=? fun ctxt ->
|
|
||||||
Lwt.return Tez.(credit -? Constants.origination_burn) >>=? fun balance ->
|
Lwt.return Tez.(credit -? Constants.origination_burn) >>=? fun balance ->
|
||||||
Contract.originate ctxt
|
Contract.originate ctxt
|
||||||
origination
|
origination
|
||||||
~manager ~delegate ~balance
|
~manager ~delegate ~balance
|
||||||
~script:(Script { code ; storage }) ~spendable:true ~delegatable
|
~script:({ code ; storage }, (dummy_code_fee, dummy_storage_fee))
|
||||||
|
~spendable:true ~delegatable
|
||||||
>>=? fun (ctxt, contract, origination) ->
|
>>=? fun (ctxt, contract, origination) ->
|
||||||
logged_return ~origination (Item ((p, r, contract), rest), qta - 1, ctxt)
|
logged_return ~origination (Item ((p, r, contract), rest), qta - 1, ctxt)
|
||||||
| Balance, rest ->
|
| Balance, rest ->
|
||||||
|
@ -14,6 +14,9 @@ type error += Overflow of Script.location
|
|||||||
type error += Reject of Script.location
|
type error += Reject of Script.location
|
||||||
type error += Division_by_zero of Script.location
|
type error += Division_by_zero of Script.location
|
||||||
|
|
||||||
|
val dummy_code_fee : Tez.t
|
||||||
|
val dummy_storage_fee : Tez.t
|
||||||
|
|
||||||
(* calling convention :
|
(* calling convention :
|
||||||
((amount, arg), globals)) -> (ret, globals) *)
|
((amount, arg), globals)) -> (ret, globals) *)
|
||||||
|
|
||||||
|
@ -1388,14 +1388,14 @@ and parse_contract
|
|||||||
trace
|
trace
|
||||||
(Invalid_contract (loc, contract)) @@
|
(Invalid_contract (loc, contract)) @@
|
||||||
Contract.get_script ctxt contract >>=? function
|
Contract.get_script ctxt contract >>=? function
|
||||||
| No_script ->
|
| None ->
|
||||||
Lwt.return
|
Lwt.return
|
||||||
(ty_eq arg Unit_t >>? fun (Eq _) ->
|
(ty_eq arg Unit_t >>? fun (Eq _) ->
|
||||||
ty_eq ret Unit_t >>? fun (Eq _) ->
|
ty_eq ret Unit_t >>? fun (Eq _) ->
|
||||||
let contract : (arg, ret) typed_contract =
|
let contract : (arg, ret) typed_contract =
|
||||||
(arg, ret, contract) in
|
(arg, ret, contract) in
|
||||||
ok contract)
|
ok contract)
|
||||||
| Script { code = { arg_type; ret_type} } ->
|
| Some { code = { arg_type; ret_type} } ->
|
||||||
Lwt.return
|
Lwt.return
|
||||||
(parse_ty arg_type >>? fun (Ex_ty targ) ->
|
(parse_ty arg_type >>? fun (Ex_ty targ) ->
|
||||||
parse_ty ret_type >>? fun (Ex_ty tret) ->
|
parse_ty ret_type >>? fun (Ex_ty tret) ->
|
||||||
|
@ -110,9 +110,6 @@ type storage =
|
|||||||
{ storage : expr ;
|
{ storage : expr ;
|
||||||
storage_type : expr }
|
storage_type : expr }
|
||||||
|
|
||||||
let storage_cost _ = Tez_repr.of_cents_exn 50L (* FIXME *)
|
|
||||||
let code_cost _ = Tez_repr.of_cents_exn 50L (* FIXME *)
|
|
||||||
|
|
||||||
open Data_encoding
|
open Data_encoding
|
||||||
|
|
||||||
let storage_encoding =
|
let storage_encoding =
|
||||||
@ -140,22 +137,14 @@ let hash_expr data =
|
|||||||
Script_expr_hash.(hash_bytes [ bytes ] |> to_b58check)
|
Script_expr_hash.(hash_bytes [ bytes ] |> to_b58check)
|
||||||
|
|
||||||
type t =
|
type t =
|
||||||
| No_script
|
{ code : code ;
|
||||||
| Script of {
|
storage : storage }
|
||||||
code: code ;
|
|
||||||
storage: storage ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let encoding =
|
let encoding =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
union ~tag_size:`Uint8 [
|
conv
|
||||||
case ~tag:0 empty
|
(function { code ; storage } -> (code, storage))
|
||||||
(function No_script -> Some () | _ -> None)
|
(fun (code, storage) -> { code ; storage })
|
||||||
(fun () -> No_script) ;
|
(obj2
|
||||||
case ~tag:1
|
(req "code" code_encoding)
|
||||||
(obj2
|
(req "storage" storage_encoding))
|
||||||
(req "code" code_encoding)
|
|
||||||
(req "storage" storage_encoding))
|
|
||||||
(function Script { code ; storage } -> Some (code, storage) | _ -> None)
|
|
||||||
(fun (code, storage) -> Script { code ; storage })
|
|
||||||
]
|
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
(** Tezos protocol 1234abc1212 - untyped script representation *)
|
|
||||||
|
|
||||||
type location =
|
type location =
|
||||||
int
|
int
|
||||||
|
|
||||||
@ -29,11 +27,8 @@ type storage =
|
|||||||
storage_type : expr }
|
storage_type : expr }
|
||||||
|
|
||||||
type t =
|
type t =
|
||||||
| No_script
|
{ code : code ;
|
||||||
| Script of {
|
storage : storage }
|
||||||
code: code ;
|
|
||||||
storage: storage ;
|
|
||||||
}
|
|
||||||
|
|
||||||
val location_encoding : location Data_encoding.t
|
val location_encoding : location Data_encoding.t
|
||||||
val expr_encoding : expr Data_encoding.t
|
val expr_encoding : expr Data_encoding.t
|
||||||
@ -41,7 +36,4 @@ val storage_encoding : storage Data_encoding.t
|
|||||||
val code_encoding : code Data_encoding.t
|
val code_encoding : code Data_encoding.t
|
||||||
val encoding : t Data_encoding.t
|
val encoding : t Data_encoding.t
|
||||||
|
|
||||||
val storage_cost : storage -> Tez_repr.tez
|
|
||||||
val code_cost : code -> Tez_repr.tez
|
|
||||||
|
|
||||||
val hash_expr : expr -> string
|
val hash_expr : expr -> string
|
||||||
|
@ -253,7 +253,7 @@ module Context = struct
|
|||||||
RPC.service
|
RPC.service
|
||||||
~description: "Access the code and data of the contract."
|
~description: "Access the code and data of the contract."
|
||||||
~input: empty
|
~input: empty
|
||||||
~output: (wrap_tzerror Script.encoding)
|
~output: (wrap_tzerror (option Script.encoding))
|
||||||
RPC.Path.(custom_root / "context" / "contracts" /: Contract.arg / "script")
|
RPC.Path.(custom_root / "context" / "contracts" /: Contract.arg / "script")
|
||||||
|
|
||||||
let assets custom_root =
|
let assets custom_root =
|
||||||
@ -268,7 +268,7 @@ module Context = struct
|
|||||||
balance: Tez.t ;
|
balance: Tez.t ;
|
||||||
spendable: bool ;
|
spendable: bool ;
|
||||||
delegate: bool * public_key_hash option ;
|
delegate: bool * public_key_hash option ;
|
||||||
script: Script.t ;
|
script: Script.t option ;
|
||||||
assets: Asset.Map.t ;
|
assets: Asset.Map.t ;
|
||||||
counter: int32 ;
|
counter: int32 ;
|
||||||
}
|
}
|
||||||
@ -291,7 +291,7 @@ module Context = struct
|
|||||||
(req "delegate" @@ obj2
|
(req "delegate" @@ obj2
|
||||||
(req "setable" bool)
|
(req "setable" bool)
|
||||||
(opt "value" Ed25519.Public_key_hash.encoding))
|
(opt "value" Ed25519.Public_key_hash.encoding))
|
||||||
(dft "script" Script.encoding No_script)
|
(opt "script" Script.encoding)
|
||||||
(req "assets" Asset.Map.encoding)
|
(req "assets" Asset.Map.encoding)
|
||||||
(req "counter" int32))
|
(req "counter" int32))
|
||||||
RPC.Path.(custom_root / "context" / "contracts" /: Contract.arg)
|
RPC.Path.(custom_root / "context" / "contracts" /: Contract.arg)
|
||||||
|
@ -117,6 +117,8 @@ module Key = struct
|
|||||||
let counter c = contract_store c ["counter"]
|
let counter c = contract_store c ["counter"]
|
||||||
let code c = contract_store c ["code"]
|
let code c = contract_store c ["code"]
|
||||||
let storage c = contract_store c ["storage"]
|
let storage c = contract_store c ["storage"]
|
||||||
|
let code_fees c = contract_store c ["code_fees"]
|
||||||
|
let storage_fees c = contract_store c ["storage_fees"]
|
||||||
end
|
end
|
||||||
|
|
||||||
module Vote = struct
|
module Vote = struct
|
||||||
@ -330,6 +332,24 @@ module Contract = struct
|
|||||||
let encoding = Script_repr.storage_encoding
|
let encoding = Script_repr.storage_encoding
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
module Code_fees =
|
||||||
|
Make_indexed_data_storage(struct
|
||||||
|
type key = Contract_repr.t
|
||||||
|
type value = Tez_repr.t
|
||||||
|
let name = "contract code fees"
|
||||||
|
let key = Key.Contract.code_fees
|
||||||
|
let encoding = Tez_repr.encoding
|
||||||
|
end)
|
||||||
|
|
||||||
|
module Storage_fees =
|
||||||
|
Make_indexed_data_storage(struct
|
||||||
|
type key = Contract_repr.t
|
||||||
|
type value = Tez_repr.t
|
||||||
|
let name = "contract storage fees"
|
||||||
|
let key = Key.Contract.storage_fees
|
||||||
|
let encoding = Tez_repr.encoding
|
||||||
|
end)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Votes **)
|
(** Votes **)
|
||||||
|
@ -174,6 +174,16 @@ module Contract : sig
|
|||||||
and type value = Script_repr.storage
|
and type value = Script_repr.storage
|
||||||
and type context := t
|
and type context := t
|
||||||
|
|
||||||
|
module Code_fees : Indexed_data_storage
|
||||||
|
with type key = Contract_repr.t
|
||||||
|
and type value = Tez_repr.t
|
||||||
|
and type context := t
|
||||||
|
|
||||||
|
module Storage_fees : Indexed_data_storage
|
||||||
|
with type key = Contract_repr.t
|
||||||
|
and type value = Tez_repr.t
|
||||||
|
and type context := t
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Votes *)
|
(** Votes *)
|
||||||
|
@ -126,11 +126,8 @@ module Script : sig
|
|||||||
}
|
}
|
||||||
|
|
||||||
type t =
|
type t =
|
||||||
| No_script
|
{ code : code ;
|
||||||
| Script of {
|
storage : storage }
|
||||||
code: code ;
|
|
||||||
storage: storage ;
|
|
||||||
}
|
|
||||||
|
|
||||||
val location_encoding: location Data_encoding.t
|
val location_encoding: location Data_encoding.t
|
||||||
val expr_encoding: expr Data_encoding.t
|
val expr_encoding: expr Data_encoding.t
|
||||||
@ -138,10 +135,7 @@ module Script : sig
|
|||||||
val code_encoding: code Data_encoding.t
|
val code_encoding: code Data_encoding.t
|
||||||
val encoding: t Data_encoding.t
|
val encoding: t Data_encoding.t
|
||||||
|
|
||||||
val storage_cost: storage -> Tez.t
|
val hash_expr : expr -> string
|
||||||
val code_cost: code -> Tez.t
|
|
||||||
|
|
||||||
val hash_expr: expr -> string
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -316,6 +310,8 @@ module Contract : sig
|
|||||||
val is_default: contract -> public_key_hash option
|
val is_default: contract -> public_key_hash option
|
||||||
|
|
||||||
val exists: context -> contract -> bool tzresult Lwt.t
|
val exists: context -> contract -> bool tzresult Lwt.t
|
||||||
|
val must_exist: context -> contract -> unit tzresult Lwt.t
|
||||||
|
|
||||||
val list: context -> contract list tzresult Lwt.t
|
val list: context -> contract list tzresult Lwt.t
|
||||||
|
|
||||||
type origination_nonce
|
type origination_nonce
|
||||||
@ -328,8 +324,6 @@ module Contract : sig
|
|||||||
|
|
||||||
val get_manager:
|
val get_manager:
|
||||||
context -> contract -> public_key_hash tzresult Lwt.t
|
context -> contract -> public_key_hash tzresult Lwt.t
|
||||||
val get_delegate:
|
|
||||||
context -> contract -> public_key_hash tzresult Lwt.t
|
|
||||||
val get_delegate_opt:
|
val get_delegate_opt:
|
||||||
context -> contract -> public_key_hash option tzresult Lwt.t
|
context -> contract -> public_key_hash option tzresult Lwt.t
|
||||||
val is_delegatable:
|
val is_delegatable:
|
||||||
@ -337,7 +331,7 @@ module Contract : sig
|
|||||||
val is_spendable:
|
val is_spendable:
|
||||||
context -> contract -> bool tzresult Lwt.t
|
context -> contract -> bool tzresult Lwt.t
|
||||||
val get_script:
|
val get_script:
|
||||||
context -> contract -> Script.t tzresult Lwt.t
|
context -> contract -> (Script.t option) tzresult Lwt.t
|
||||||
|
|
||||||
val get_counter: context -> contract -> int32 tzresult Lwt.t
|
val get_counter: context -> contract -> int32 tzresult Lwt.t
|
||||||
val get_balance:
|
val get_balance:
|
||||||
@ -348,14 +342,14 @@ module Contract : sig
|
|||||||
val set_delegate:
|
val set_delegate:
|
||||||
context -> contract -> public_key_hash option -> context tzresult Lwt.t
|
context -> contract -> public_key_hash option -> context tzresult Lwt.t
|
||||||
|
|
||||||
type error += Initial_amount_too_low of Tez.t * Tez.t
|
type error += Initial_amount_too_low of contract * Tez.t * Tez.t
|
||||||
|
|
||||||
val originate:
|
val originate:
|
||||||
context ->
|
context ->
|
||||||
origination_nonce ->
|
origination_nonce ->
|
||||||
balance: Tez.t ->
|
balance: Tez.t ->
|
||||||
manager: public_key_hash ->
|
manager: public_key_hash ->
|
||||||
script: Script.t ->
|
?script: (Script.t * (Tez.t * Tez.t)) ->
|
||||||
delegate: public_key_hash option ->
|
delegate: public_key_hash option ->
|
||||||
spendable: bool ->
|
spendable: bool ->
|
||||||
delegatable: bool -> (context * contract * origination_nonce) tzresult Lwt.t
|
delegatable: bool -> (context * contract * origination_nonce) tzresult Lwt.t
|
||||||
@ -364,7 +358,7 @@ module Contract : sig
|
|||||||
|
|
||||||
val spend:
|
val spend:
|
||||||
context -> contract -> Tez.t -> context tzresult Lwt.t
|
context -> contract -> Tez.t -> context tzresult Lwt.t
|
||||||
val unconditional_spend:
|
val spend_from_script:
|
||||||
context -> contract -> Tez.t -> context tzresult Lwt.t
|
context -> contract -> Tez.t -> context tzresult Lwt.t
|
||||||
|
|
||||||
val credit:
|
val credit:
|
||||||
@ -373,8 +367,8 @@ module Contract : sig
|
|||||||
context -> contract ->
|
context -> contract ->
|
||||||
Asset.t -> public_key_hash -> Tez.t -> context tzresult Lwt.t
|
Asset.t -> public_key_hash -> Tez.t -> context tzresult Lwt.t
|
||||||
|
|
||||||
val update_script_storage:
|
val update_script_storage_and_fees:
|
||||||
context -> contract -> Script.expr -> context tzresult Lwt.t
|
context -> contract -> Tez.t -> Script.expr -> context tzresult Lwt.t
|
||||||
|
|
||||||
val increment_counter:
|
val increment_counter:
|
||||||
context -> contract -> context tzresult Lwt.t
|
context -> contract -> context tzresult Lwt.t
|
||||||
@ -474,7 +468,7 @@ and manager_operation =
|
|||||||
| Origination of {
|
| Origination of {
|
||||||
manager: public_key_hash ;
|
manager: public_key_hash ;
|
||||||
delegate: public_key_hash option ;
|
delegate: public_key_hash option ;
|
||||||
script: Script.t ;
|
script: Script.t option ;
|
||||||
spendable: bool ;
|
spendable: bool ;
|
||||||
delegatable: bool ;
|
delegatable: bool ;
|
||||||
credit: Tez.t ;
|
credit: Tez.t ;
|
||||||
|
Loading…
Reference in New Issue
Block a user