diff --git a/src/proto_alpha/lib_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index e4643ff77ea1f86cde3c4d5efffd4d649609404f..48aa9a2acecc6d3bc92df4145cc021a3982b4384 100644 --- a/src/proto_alpha/lib_plugin/RPC.ml +++ b/src/proto_alpha/lib_plugin/RPC.ml @@ -1862,6 +1862,17 @@ module Sc_rollup = struct path /: Sc_rollup.Address.rpc_arg / "last_cemented_commitment_hash_with_level") + let staked_on_commitment = + RPC_service.get_service + ~description: + "The hash of the commitment on which the operator has staked on for \ + a smart-contract rollup" + ~query:RPC_query.empty + ~output:(obj1 (req "hash" Sc_rollup.Commitment.Hash.encoding)) + RPC_path.( + path /: Sc_rollup.Address.rpc_arg / "staker" + /: Sc_rollup.Staker.rpc_arg / "staked_on_commitment") + let commitment = RPC_service.get_service ~description:"Commitment for a smart contract rollup from its hash" @@ -1931,6 +1942,15 @@ module Sc_rollup = struct in (last_cemented_commitment, level) + let register_staked_on_commitment () = + Registration.register2 ~chunked:false S.staked_on_commitment + @@ fun ctxt address staker () () -> + let open Lwt_tzresult_syntax in + let+ branch, _ctxt = + Alpha_context.Sc_rollup.Stake_storage.find_staker ctxt address staker + in + branch + let register_commitment () = Registration.register2 ~chunked:false S.commitment @@ fun ctxt address commitment_hash () () -> @@ -1958,6 +1978,7 @@ module Sc_rollup = struct register_initial_level () ; register_boot_sector () ; register_last_cemented_commitment_hash_with_level () ; + register_staked_on_commitment () ; register_commitment () ; register_dal_slot_subscriptions () ; register_root () diff --git a/src/proto_alpha/lib_protocol/alpha_context.ml b/src/proto_alpha/lib_protocol/alpha_context.ml index 6408a2c8deb158758b6dbc57ef570b5e8b3179d8..7be3af7d02c0105a52cdc03ab247208ed3ae2398 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.ml +++ b/src/proto_alpha/lib_protocol/alpha_context.ml @@ -74,7 +74,10 @@ module Sc_rollup = struct include Sc_rollup_commitment_storage end - module Stake_storage = Sc_rollup_stake_storage + module Stake_storage = struct + include Sc_rollup_stake_storage + end + module Refutation_storage = Sc_rollup_refutation_storage include Sc_rollup_storage include Sc_rollups diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index c5477750f8be2bd0ad0a74011ae38d7f56b38053..f4a740efb2fd0d01c921c1a42917a3a3f3908e61 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -3257,6 +3257,9 @@ module Sc_rollup : sig end module Stake_storage : sig + val find_staker : + context -> t -> Staker.t -> (Commitment.Hash.t * context) tzresult Lwt.t + val publish_commitment : context -> t -> diff --git a/src/proto_alpha/lib_protocol/sc_rollup_commitment_storage.mli b/src/proto_alpha/lib_protocol/sc_rollup_commitment_storage.mli index d8fc3d81bacfdbaa580cf5d94acd4e5484f5cde7..0934c5adf4958b2d970e3316897d2de4b4a5b28d 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_commitment_storage.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_commitment_storage.mli @@ -161,7 +161,7 @@ val get_commitment : (** [get_commitment_unsafe context rollup commitment_hash] returns the commitment with the given hash. This function *must* be called only after they have checked for the existence - of the rollup, and therefore it is not ncessary for it to check for the + of the rollup, and therefore it is not necessary for it to check for the existence of the rollup again. Otherwise, use the safe function {!get_commitment}. diff --git a/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.ml b/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.ml index 46ef8abf8d454e04b9f2dce30cb726c74db80f7e..669c5085809ef6172c0cf68ae0785daf31098f5e 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.ml @@ -30,13 +30,19 @@ module Commitment_storage = Sc_rollup_commitment_storage module Commitment = Sc_rollup_commitment_repr module Commitment_hash = Commitment.Hash -let find_staker ctxt rollup staker = +let find_staker_unsafe ctxt rollup staker = let open Lwt_tzresult_syntax in let* ctxt, res = Store.Stakers.find (ctxt, rollup) staker in match res with | None -> fail Sc_rollup_not_staked | Some branch -> return (branch, ctxt) +let find_staker ctxt rollup staker = + let open Lwt_tzresult_syntax in + let* ctxt, res = Store.Last_cemented_commitment.mem ctxt rollup in + if not res then fail (Sc_rollup_does_not_exist rollup) + else find_staker_unsafe ctxt rollup staker + let modify_staker_count ctxt rollup f = let open Lwt_tzresult_syntax in let* ctxt, maybe_count = Store.Staker_count.find ctxt rollup in @@ -243,7 +249,7 @@ let commitment_storage_size_in_bytes = 85 let refine_stake ctxt rollup staker commitment = let open Lwt_tzresult_syntax in let* lcc, ctxt = Commitment_storage.last_cemented_commitment ctxt rollup in - let* staked_on, ctxt = find_staker ctxt rollup staker in + let* staked_on, ctxt = find_staker_unsafe ctxt rollup staker in let* ctxt = assert_refine_conditions_met ctxt rollup lcc commitment in let new_hash = Commitment.hash commitment in (* TODO: https://gitlab.com/tezos/tezos/-/issues/2559 diff --git a/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.mli b/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.mli index 3f37fdeb968afb0317fc7aa1a973bdd924bf0f17..11a3f756fa3dce6f717a6ca3e60568b2199524ff 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_stake_storage.mli @@ -113,14 +113,26 @@ val cement_commitment : Sc_rollup_commitment_repr.Hash.t -> Raw_context.t tzresult Lwt.t -(** [find_staker ctxt rollup staker] returns the branch on which the stake +(** [find_staker_unsafe ctxt rollup staker] returns the branch on which the stake is deposited for the [rollup]'s [staker]. + This function *must* be called only after they have checked for the existence + of the rollup, and therefore it is not necessary for it to check for the + existence of the rollup again. Otherwise, use the safe function + {!find_staker}. May fail with [Sc_rollup_not_staked] if [staker] is not staked. *) +val find_staker_unsafe : + Raw_context.t -> + Sc_rollup_repr.t -> + Sc_rollup_repr.Staker.t -> + (Sc_rollup_commitment_repr.Hash.t * Raw_context.t) tzresult Lwt.t + +(** Same as {!find_staker_unsafe} but checks for the existence of the [rollup] + before. *) val find_staker : Raw_context.t -> Sc_rollup_repr.t -> - Signature.public_key_hash -> + Sc_rollup_repr.Staker.t -> (Sc_rollup_commitment_repr.Hash.t * Raw_context.t) tzresult Lwt.t (** The storage size requirement (in bytes) of a commitment *) diff --git a/tezt/lib_tezos/RPC.ml b/tezt/lib_tezos/RPC.ml index 203eeb17bce83de25ff80d7b3364a6142213f283..26b750275dfd832f6ae9cdd9e3acc9136cf2fefb 100644 --- a/tezt/lib_tezos/RPC.ml +++ b/tezt/lib_tezos/RPC.ml @@ -308,3 +308,39 @@ let get_fetch_protocol protocol_hash = let get_stats_gc = make GET ["stats"; "gc"] Fun.id let get_stats_memory = make GET ["stats"; "memory"] Fun.id + +module Sc_rollup = struct + let root_path ~chain ~block = + ["chains"; chain; "blocks"; block; "context"; "sc_rollup"] + + let list ?(chain = "main") ?(block = "head") () = + make GET (root_path ~chain ~block) Fun.id + + let path ~chain ~block sc_rollup_address = + root_path ~chain ~block @ [sc_rollup_address] + + let get_inbox ?(chain = "main") ?(block = "head") sc_rollup_address = + make GET (path ~chain ~block sc_rollup_address @ ["inbox"]) Fun.id + + let get_initial_level ?(chain = "main") ?(block = "head") sc_rollup_address = + make GET (path ~chain ~block sc_rollup_address @ ["initial_level"]) Fun.id + + let get_boot_sector ?(chain = "main") ?(block = "head") sc_rollup_address = + make GET (path ~chain ~block sc_rollup_address @ ["boot_sector"]) Fun.id + + let get_last_cemented_commitment_hash_with_level ?(chain = "main") + ?(block = "head") sc_rollup_address = + make + GET + (path ~chain ~block sc_rollup_address + @ ["last_cemented_commitment_hash_with_level"]) + Fun.id + + let get_staked_on_commitment ?(chain = "main") ?(block = "head") + ~sc_rollup_address staker = + make + GET + (path ~chain ~block sc_rollup_address + @ ["staker"; staker; "staked_on_commitment"]) + Fun.id +end diff --git a/tezt/lib_tezos/RPC.mli b/tezt/lib_tezos/RPC.mli index e403c78f87f43a0832f1b57a8378aee1fd68c701..9ec7e38bd4dbf1b53d0dd9a9d99b98b97247b49e 100644 --- a/tezt/lib_tezos/RPC.mli +++ b/tezt/lib_tezos/RPC.mli @@ -343,3 +343,30 @@ val get_stats_gc : JSON.t t (** RPC: [GET /stats/memory] *) val get_stats_memory : JSON.t t + +(** Smart contract rollup RPC module. *) +module Sc_rollup : sig + (** RPC: [GET chain/[chain]/blocks/[block]/context/sc_rollup] *) + val list : ?chain:string -> ?block:string -> unit -> JSON.t t + + (** RPC: [GET chain/[chain]/blocks/[block]/context/sc_rollup//inbox] *) + val get_inbox : ?chain:string -> ?block:string -> string -> JSON.t t + + (** RPC: [GET chain/[chain]/blocks/[block]/context/sc_rollup//initial_level] *) + val get_initial_level : ?chain:string -> ?block:string -> string -> JSON.t t + + (** RPC: [GET chain/[chain]/blocks/[block]/context/sc_rollup//boot_sector] *) + val get_boot_sector : ?chain:string -> ?block:string -> string -> JSON.t t + + (** RPC: [GET chain/[chain]/blocks/[block]/context/sc_rollup//get_last_cemented_commitment_hash_with_level] *) + val get_last_cemented_commitment_hash_with_level : + ?chain:string -> ?block:string -> string -> JSON.t t + + (** Call RPC /chain/[chain]/blocks/[block]/context/sc_rollup/[rollup_hash]/staker/[staker]/staked_on_commitment *) + val get_staked_on_commitment : + ?chain:string -> + ?block:string -> + sc_rollup_address:string -> + string -> + JSON.t t +end diff --git a/tezt/lib_tezos/RPC_legacy.ml b/tezt/lib_tezos/RPC_legacy.ml index 0431488f3abf5cf40c7410420f575031d2845cae..1adb473033d63cfdf7e5c0e9b45a9badc4683665 100644 --- a/tezt/lib_tezos/RPC_legacy.ml +++ b/tezt/lib_tezos/RPC_legacy.ml @@ -689,41 +689,6 @@ module Tx_rollup = struct end end -module Sc_rollup = struct - let root_path ~chain ~block = - ["chains"; chain; "blocks"; block; "context"; "sc_rollup"] - - let list ?endpoint ?hooks ?(chain = "main") ?(block = "head") client = - let path = root_path ~chain ~block in - Client.rpc ?endpoint ?hooks GET path client - - let path ~chain ~block ~sc_rollup_address = - root_path ~chain ~block @ [sc_rollup_address] - - let get_inbox ?endpoint ?hooks ?(chain = "main") ?(block = "head") - ~sc_rollup_address client = - let path = path ~chain ~block ~sc_rollup_address @ ["inbox"] in - Client.rpc ?endpoint ?hooks GET path client - - let get_initial_level ?endpoint ?hooks ?(chain = "main") ?(block = "head") - ~sc_rollup_address client = - let path = path ~chain ~block ~sc_rollup_address @ ["initial_level"] in - Client.rpc ?endpoint ?hooks GET path client - - let get_boot_sector ?endpoint ?hooks ?(chain = "main") ?(block = "head") - ~sc_rollup_address client = - let path = path ~chain ~block ~sc_rollup_address @ ["boot_sector"] in - Client.rpc ?endpoint ?hooks GET path client - - let get_last_cemented_commitment_hash_with_level ?endpoint ?hooks - ?(chain = "main") ?(block = "head") ~sc_rollup_address client = - let path = - path ~chain ~block ~sc_rollup_address - @ ["last_cemented_commitment_hash_with_level"] - in - Client.rpc ?endpoint ?hooks GET path client -end - let raw_bytes ?endpoint ?hooks ?(chain = "main") ?(block = "head") ?(path = []) client = let path = diff --git a/tezt/lib_tezos/RPC_legacy.mli b/tezt/lib_tezos/RPC_legacy.mli index e5eb15e6e3a564c0f2cea8164b6107ee0ac4635b..b67149b3894bc6336182d602a896070fdadb472b 100644 --- a/tezt/lib_tezos/RPC_legacy.mli +++ b/tezt/lib_tezos/RPC_legacy.mli @@ -919,57 +919,6 @@ module Tx_rollup : sig end end -module Sc_rollup : sig - (** Call RPC /chain/[chain]/blocks/[block]/context/sc_rollup *) - val list : - ?endpoint:Client.endpoint -> - ?hooks:Process.hooks -> - ?chain:string -> - ?block:string -> - Client.t -> - JSON.t Lwt.t - - (** Call RPC /chain/[chain]/blocks/[block]/context/sc_rollup/[rollup_hash]/state *) - val get_inbox : - ?endpoint:Client.endpoint -> - ?hooks:Process.hooks -> - ?chain:string -> - ?block:string -> - sc_rollup_address:string -> - Client.t -> - JSON.t Lwt.t - - (** Call RPC /chain/[chain]/blocks/[block]/context/sc_rollup/[rollup_hash]/initial_level *) - val get_initial_level : - ?endpoint:Client.endpoint -> - ?hooks:Process.hooks -> - ?chain:string -> - ?block:string -> - sc_rollup_address:string -> - Client.t -> - JSON.t Lwt.t - - (** Call RPC /chain/[chain]/blocks/[block]/context/sc_rollup/[rollup_hash]/boot_sector *) - val get_boot_sector : - ?endpoint:Client.endpoint -> - ?hooks:Process.hooks -> - ?chain:string -> - ?block:string -> - sc_rollup_address:string -> - Client.t -> - JSON.t Lwt.t - - (** Call RPC /chain/[chain]/blocks/[block]/context/sc_rollup/[rollup_hash]/lcc_hash_with_level *) - val get_last_cemented_commitment_hash_with_level : - ?endpoint:Client.endpoint -> - ?hooks:Process.hooks -> - ?chain:string -> - ?block:string -> - sc_rollup_address:string -> - Client.t -> - JSON.t Lwt.t -end - val raw_bytes : ?endpoint:Client.endpoint -> ?hooks:Process.hooks -> diff --git a/tezt/lib_tezos/constant.ml b/tezt/lib_tezos/constant.ml index 42c55d9d9700294821a86dc33aee4710b3233cc2..35a17d77a149137d7a2c463f7bb036b63b3e0d65 100644 --- a/tezt/lib_tezos/constant.ml +++ b/tezt/lib_tezos/constant.ml @@ -102,6 +102,10 @@ let tx_rollup_proof_initial_state = "after": { "node": "CoVu7Pqp1Gh3z33mink5T5Q2kAQKtnn3GHxVhyehdKZpQMBxFBGF" } , "state": [] }|} +(** A valid base58 encoded compressed state hash. *) +let sc_rollup_compressed_state = + "scs11VNjWyZw4Tgbvsom8epQbox86S2CKkE1UAZkXMM7Pj8MQMLzMf" + (** A valid base58 encoded layer-2 account to be used to test transaction and smart contract rollups. *) let tz4_account : Account.aggregate_key = diff --git a/tezt/tests/RPC_test.ml b/tezt/tests/RPC_test.ml index d8812d44cc61d49089e42f5ac90289509dc7214a..24cf1e464423cf1dc0dd968569a1f5ce97bcf528 100644 --- a/tezt/tests/RPC_test.ml +++ b/tezt/tests/RPC_test.ml @@ -986,7 +986,7 @@ let test_chain _test_mode_tag protocol ?endpoint client = if Protocol.number protocol >= 013 then let* _ = (* Calls [/chains/main/blocks/head/context/sc_rollup] *) - RPC.Sc_rollup.list ?endpoint client + RPC.Client.call ?endpoint client @@ RPC.Sc_rollup.list () in unit else unit diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index 91b6e70b94cfe96a982ea256fe05b94d0342a5b4..c560597c4a7ed1c57eac93884c35281d85c47769 100644 --- a/tezt/tests/dal.ml +++ b/tezt/tests/dal.ml @@ -335,7 +335,8 @@ let rollup_node_subscribes_to_dal_slots _protocol sc_rollup_node 6. Fetch the list of subscribed slots, determine that it contains slots 0 and 1 *) let* init_level = - RPC.Sc_rollup.get_initial_level ~hooks ~sc_rollup_address client + RPC.Client.call ~hooks client + @@ RPC.Sc_rollup.get_initial_level sc_rollup_address in let init_level = init_level |> JSON.as_int in let* () = Sc_rollup_node.run sc_rollup_node in diff --git a/tezt/tests/expected/sc_rollup.ml/Alpha- consecutive commitments.out b/tezt/tests/expected/sc_rollup.ml/Alpha- consecutive commitments.out new file mode 100644 index 0000000000000000000000000000000000000000..9e75a142abc72b3cd4be1c2fa64af12167bec062 --- /dev/null +++ b/tezt/tests/expected/sc_rollup.ml/Alpha- consecutive commitments.out @@ -0,0 +1,97 @@ + +./tezos-client --wait none originate sc rollup from '[PUBLIC_KEY_HASH]' of kind arith of type unit booting with --burn-cap 9999999 +Node is bootstrapped. +Estimated gas: 1800.800 units (will add 100 for safety) +Estimated storage: 6541 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000428 + Expected counter: 1 + Gas limit: 1901 + Storage limit: 6561 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000428 + payload fees(the block proposer) ....... +ꜩ0.000428 + Originate smart contract rollup of kind arith and type unit with boot sector '' + This smart contract rollup origination was successfully applied + Consumed gas: 1800.800 + Storage size: 6541 bytes + Address: [SC_ROLLUP_HASH] + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ1.63525 + storage fees ........................... +ꜩ1.63525 + + +./tezos-client --wait none publish commitment from '[PUBLIC_KEY_HASH]' for sc rollup '[SC_ROLLUP_HASH]' with compressed state scs11VNjWyZw4Tgbvsom8epQbox86S2CKkE1UAZkXMM7Pj8MQMLzMf at inbox level 32 and predecessor '[SC_ROLLUP_COMMITMENT_HASH]' and number of messages 0 and number of ticks 0 +Node is bootstrapped. +Estimated gas: 5330.828 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000885 + Expected counter: 2 + Gas limit: 5431 + Storage limit: 0 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000885 + payload fees(the block proposer) ....... +ꜩ0.000885 + Publish commitment SCORU Commitment: + compressed_state: scs11VNjWyZw4Tgbvsom8epQbox86S2CKkE1UAZkXMM7Pj8MQMLzMf + inbox_level: 32 + predecessor: [SC_ROLLUP_COMMITMENT_HASH] + number_of_messages: 0 + number_of_ticks: 0 in the smart contract rollup at address [SC_ROLLUP_HASH] + This smart contract rollup commitment publishing was successfully applied + Consumed gas: 5330.828 + Hash of commit: [SC_ROLLUP_COMMITMENT_HASH] + Commitment published at level: 3 + Balance updates: + [PUBLIC_KEY_HASH] ....................................................... -ꜩ32 + Frozen_bonds([PUBLIC_KEY_HASH],[SC_ROLLUP_HASH]) ... +ꜩ32 + + +./tezos-client --wait none publish commitment from '[PUBLIC_KEY_HASH]' for sc rollup '[SC_ROLLUP_HASH]' with compressed state scs11VNjWyZw4Tgbvsom8epQbox86S2CKkE1UAZkXMM7Pj8MQMLzMf at inbox level 62 and predecessor '[SC_ROLLUP_COMMITMENT_HASH]' and number of messages 0 and number of ticks 0 +Node is bootstrapped. +Estimated gas: 4019.750 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000753 + Expected counter: 3 + Gas limit: 4120 + Storage limit: 0 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000753 + payload fees(the block proposer) ....... +ꜩ0.000753 + Publish commitment SCORU Commitment: + compressed_state: scs11VNjWyZw4Tgbvsom8epQbox86S2CKkE1UAZkXMM7Pj8MQMLzMf + inbox_level: 62 + predecessor: [SC_ROLLUP_COMMITMENT_HASH] + number_of_messages: 0 + number_of_ticks: 0 in the smart contract rollup at address [SC_ROLLUP_HASH] + This smart contract rollup commitment publishing was successfully applied + Consumed gas: 4019.750 + Hash of commit: [SC_ROLLUP_COMMITMENT_HASH] + Commitment published at level: 4 + diff --git a/tezt/tests/sc_rollup.ml b/tezt/tests/sc_rollup.ml index f114915ebc94d259e8693de3ddc806d5c6a09e74..e871f605605fdf7b0463e0b8ed22a7e1de6e75ae 100644 --- a/tezt/tests/sc_rollup.ml +++ b/tezt/tests/sc_rollup.ml @@ -192,10 +192,23 @@ let number_of_ticks (_hash, (commitment : Sc_rollup_client.commitment), _level) = commitment.number_of_ticks -let last_cemented_commitment_hash_with_level json = +let last_cemented_commitment_hash_with_level ~sc_rollup_address client = + let* json = + RPC.Client.call client + @@ RPC.Sc_rollup.get_last_cemented_commitment_hash_with_level + sc_rollup_address + in let hash = JSON.(json |-> "hash" |> as_string) in let level = JSON.(json |-> "level" |> as_int) in - (hash, level) + return (hash, level) + +let get_staked_on_commitment ~sc_rollup_address ~staker client = + let* json = + RPC.Client.call client + @@ RPC.Sc_rollup.get_staked_on_commitment ~sc_rollup_address staker + in + let hash = JSON.(json |-> "hash" |> as_string) in + return hash let hash (hash, (_ : Sc_rollup_client.commitment), _level) = hash @@ -215,6 +228,29 @@ let cement_commitment client ~sc_rollup_address ~hash = in Client.bake_for_and_wait client +let publish_commitment ?(src = Constant.bootstrap1.public_key_hash) ~commitment + client sc_rollup = + let ({ + compressed_state; + inbox_level; + predecessor; + number_of_messages; + number_of_ticks; + } + : Sc_rollup_client.commitment) = + commitment + in + Client.Sc_rollup.publish_commitment + ~hooks + ~src + ~sc_rollup + ~compressed_state + ~inbox_level + ~predecessor + ~number_of_messages + ~number_of_ticks + client + (* Tests @@ -389,7 +425,8 @@ let test_rollup_get_initial_level = from the current level. *) let* _ = repeat 10 (fun () -> Client.bake_for_and_wait client) in let* initial_level = - RPC.Sc_rollup.get_initial_level ~sc_rollup_address client + RPC.Client.call client + @@ RPC.Sc_rollup.get_initial_level sc_rollup_address in (* 1 Block for activating alpha + 1 block for originating the rollup the rollup initial level should be 2 *) @@ -425,13 +462,8 @@ let test_rollup_get_last_cemented_commitment_hash_with_level = (* Bake 10 blocks to be sure that the origination_level of rollup is different from the level of the head node. *) let* () = repeat 10 (fun () -> Client.bake_for_and_wait client) in - let* lcc_info_json = - RPC.Sc_rollup.get_last_cemented_commitment_hash_with_level - ~sc_rollup_address - client - in - let hash, level = - last_cemented_commitment_hash_with_level lcc_info_json + let* hash, level = + last_cemented_commitment_hash_with_level ~sc_rollup_address client in (* The hardcoded value of `Sc_rollup.Commitment.zero` is "scc12XhSULdV8bAav21e99VYLTpqAjTd7NU8Mn4zFdKPSA8auMbggG". *) @@ -508,7 +540,9 @@ let parse_inbox json = (Printexc.to_string exn)) let get_inbox_from_tezos_node sc_rollup_address client = - let* inbox = RPC.Sc_rollup.get_inbox ~sc_rollup_address client in + let* inbox = + RPC.Client.call client @@ RPC.Sc_rollup.get_inbox sc_rollup_address + in parse_inbox inbox let get_inbox_from_sc_rollup_node sc_rollup_node = @@ -861,7 +895,7 @@ let sc_rollup_node_handles_chain_reorg protocol sc_rollup_node sc_rollup_address let test_rollup_list = let open Lwt.Syntax in let go node client bootstrap1 = - let* rollups = RPC.Sc_rollup.list client in + let* rollups = RPC.Client.call client @@ RPC.Sc_rollup.list () in let rollups = JSON.as_list rollups in let () = match rollups with @@ -874,7 +908,7 @@ let test_rollup_list = 10 (fun scoru_addresses -> let* () = Client.bake_for_and_wait client in - let+ rollups = RPC.Sc_rollup.list client in + let+ rollups = RPC.Client.call client @@ RPC.Sc_rollup.list () in let rollups = JSON.as_list rollups |> List.map JSON.as_string |> String_set.of_list in @@ -902,7 +936,8 @@ let test_rollup_list = let test_rollup_node_boots_into_initial_state = let go client sc_rollup_address sc_rollup_node = let* init_level = - RPC.Sc_rollup.get_initial_level ~hooks ~sc_rollup_address client + RPC.Client.call ~hooks client + @@ RPC.Sc_rollup.get_initial_level sc_rollup_address in let init_level = init_level |> JSON.as_int in @@ -948,7 +983,8 @@ let test_rollup_node_boots_into_initial_state = let test_rollup_node_advances_pvm_state = let go client sc_rollup_address sc_rollup_node = let* init_level = - RPC.Sc_rollup.get_initial_level ~hooks ~sc_rollup_address client + RPC.Client.call ~hooks client + @@ RPC.Sc_rollup.get_initial_level sc_rollup_address in let init_level = init_level |> JSON.as_int in @@ -1108,7 +1144,8 @@ let commitment_stored _protocol sc_rollup_node sc_rollup_address _node client = levels_to_finalise`. *) let* init_level = - RPC.Sc_rollup.get_initial_level ~hooks ~sc_rollup_address client + RPC.Client.call ~hooks client + @@ RPC.Sc_rollup.get_initial_level sc_rollup_address in let init_level = init_level |> JSON.as_int in @@ -1183,7 +1220,8 @@ let commitment_not_stored_if_non_final _protocol sc_rollup_node neither stored nor published. *) let* init_level = - RPC.Sc_rollup.get_initial_level ~hooks ~sc_rollup_address client + RPC.Client.call ~hooks client + @@ RPC.Sc_rollup.get_initial_level sc_rollup_address in let init_level = init_level |> JSON.as_int in @@ -1241,7 +1279,8 @@ let commitments_messages_reset _protocol sc_rollup_node sc_rollup_address _node commitments are stored and published by the rollup node. *) let* init_level = - RPC.Sc_rollup.get_initial_level ~hooks ~sc_rollup_address client + RPC.Client.call ~hooks client + @@ RPC.Sc_rollup.get_initial_level sc_rollup_address in let init_level = init_level |> JSON.as_int in @@ -1316,7 +1355,8 @@ let commitments_reorgs protocol sc_rollup_node sc_rollup_address node client = no messages and no ticks. *) let* init_level = - RPC.Sc_rollup.get_initial_level ~hooks ~sc_rollup_address client + RPC.Client.call ~hooks client + @@ RPC.Sc_rollup.get_initial_level sc_rollup_address in let init_level = init_level |> JSON.as_int in @@ -1488,7 +1528,8 @@ let commitment_before_lcc_not_published _protocol sc_rollup_node let challenge_window = constants.challenge_window_in_blocks in (* Rollup node 1 processes messages, produces and publishes two commitments. *) let* init_level = - RPC.Sc_rollup.get_initial_level ~hooks ~sc_rollup_address client + RPC.Client.call ~hooks client + @@ RPC.Sc_rollup.get_initial_level sc_rollup_address in let init_level = init_level |> JSON.as_int in @@ -1652,7 +1693,8 @@ let first_published_level_is_global _protocol sc_rollup_node sc_rollup_address node client = (* Rollup node 1 processes messages, produces and publishes two commitments. *) let* init_level = - RPC.Sc_rollup.get_initial_level ~hooks ~sc_rollup_address client + RPC.Client.call ~hooks client + @@ RPC.Sc_rollup.get_initial_level sc_rollup_address in let* commitment_period = get_sc_rollup_commitment_period_in_blocks client in let init_level = init_level |> JSON.as_int in @@ -1744,7 +1786,8 @@ let test_rollup_origination_boot_sector = let go client sc_rollup_address = let* client_boot_sector = - RPC.Sc_rollup.get_boot_sector ~hooks ~sc_rollup_address client + RPC.Client.call ~hooks client + @@ RPC.Sc_rollup.get_boot_sector sc_rollup_address in let client_boot_sector = JSON.as_string client_boot_sector in Check.(boot_sector = client_boot_sector) @@ -1775,7 +1818,8 @@ let test_rollup_origination_boot_sector = let test_rollup_node_uses_boot_sector = let go_boot client sc_rollup_address sc_rollup_node = let* init_level = - RPC.Sc_rollup.get_initial_level ~hooks ~sc_rollup_address client + RPC.Client.call ~hooks client + @@ RPC.Sc_rollup.get_initial_level sc_rollup_address in let init_level = init_level |> JSON.as_int in @@ -1915,6 +1959,80 @@ let test_rollup_client_list_keys = pp maybe_keys) +let publish_dummy_commitment ~inbox_level ~predecessor ~sc_rollup ~src client = + let commitment : Sc_rollup_client.commitment = + { + compressed_state = Constant.sc_rollup_compressed_state; + inbox_level; + predecessor; + number_of_messages = 0; + number_of_ticks = 0; + } + in + + let*! () = publish_commitment ~src ~commitment client sc_rollup in + Client.bake_for_and_wait client + +let test_consecutive_commitments = + regression_test + ~__FILE__ + ~tags:["l1"; "commitment"] + "consecutive commitments" + (fun protocol -> + setup ~protocol @@ fun _node client bootstrap1_key -> + let* sc_rollup = + Client.Sc_rollup.originate + ~hooks + ~burn_cap:Tez.(of_int 9999999) + ~src:bootstrap1_key + ~kind:"arith" + ~parameters_ty:"unit" + ~boot_sector:"" + client + in + let operator = Constant.bootstrap1.public_key_hash in + let* inbox_level = Client.level client in + let* {commitment_period_in_blocks; _} = get_sc_rollup_constants client in + let* () = Client.bake_for_and_wait client in + (* As we did no publish any commitment yet, this is supposed to fail. *) + let*? process = + RPC.Client.spawn client + @@ RPC.Sc_rollup.get_staked_on_commitment + ~sc_rollup_address:sc_rollup + operator + in + let* () = Process.check_error ~msg:(rex "Unknown staker") process in + let* predecessor, _ = + last_cemented_commitment_hash_with_level + ~sc_rollup_address:sc_rollup + client + in + let* () = + publish_dummy_commitment + ~inbox_level:(inbox_level + commitment_period_in_blocks + 1) + ~predecessor + ~sc_rollup + ~src:operator + client + in + (* We get the predecessor's hash by getting the commitment on which + the operator just staked on. *) + let* predecessor = + get_staked_on_commitment + ~sc_rollup_address:sc_rollup + ~staker:operator + client + in + let* () = + publish_dummy_commitment + ~inbox_level:(inbox_level + (2 * commitment_period_in_blocks) + 1) + ~predecessor + ~sc_rollup + ~src:operator + client + in + unit) + let register ~protocols = test_origination protocols ; test_rollup_node_configuration protocols ; @@ -1958,6 +2076,7 @@ let register ~protocols = "first_published_at_level_global" first_published_level_is_global protocols ; + test_consecutive_commitments protocols ; test_rollup_origination_boot_sector protocols ; test_rollup_node_uses_boot_sector protocols ; test_rollup_client_show_address protocols ;