From 85ac82386f2877316ffd82b9ff4674da05e53baa Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Thu, 28 Jul 2022 10:01:11 +0200 Subject: [PATCH 1/8] Proto,SCORU: Expose equality between inbox in Alpha_context Signed-off-by: Yann Regis-Gianas --- src/proto_alpha/lib_protocol/alpha_context.mli | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index e7bbcbd0f8d9..03557875bcac 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2826,6 +2826,8 @@ module Sc_rollup : sig val encoding : t Data_encoding.t + val equal : t -> t -> bool + val inbox_level : t -> Raw_level.t type history_proof -- GitLab From b680f4b11eab71b0ed9c9a563743a2fa683a8ed6 Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Thu, 28 Jul 2022 10:01:37 +0200 Subject: [PATCH 2/8] Proto,Plugin: Expose inbox RPC helper Signed-off-by: Yann Regis-Gianas --- src/proto_alpha/lib_plugin/RPC.ml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/proto_alpha/lib_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index af3bce22d0d7..2eb1d9003d74 100644 --- a/src/proto_alpha/lib_plugin/RPC.ml +++ b/src/proto_alpha/lib_plugin/RPC.ml @@ -2161,6 +2161,9 @@ module Sc_rollup = struct let list ctxt block = RPC_context.make_call0 S.root ctxt block () () + let inbox ctxt block sc_rollup_address = + RPC_context.make_call1 S.inbox ctxt block sc_rollup_address () () + let genesis_info ctxt block sc_rollup_address = RPC_context.make_call1 S.genesis_info ctxt block sc_rollup_address () () -- GitLab From 95d9087a9afcf852b7e71ab0d0562a2ef1617544 Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Thu, 28 Jul 2022 10:01:59 +0200 Subject: [PATCH 3/8] SCORU,Node: Add an error to report inbox inconsistency Signed-off-by: Yann Regis-Gianas --- .../sc_rollup_node_errors.ml | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/proto_alpha/bin_sc_rollup_node/sc_rollup_node_errors.ml b/src/proto_alpha/bin_sc_rollup_node/sc_rollup_node_errors.ml index 845b2e39b312..b5c9a4b4c65c 100644 --- a/src/proto_alpha/bin_sc_rollup_node/sc_rollup_node_errors.ml +++ b/src/proto_alpha/bin_sc_rollup_node/sc_rollup_node_errors.ml @@ -25,18 +25,17 @@ open Protocol.Alpha_context -type error += Bad_minimal_fees of string - -type error += Commitment_predecessor_should_be_LCC of Sc_rollup.Commitment.t - -type error += Unreliable_tezos_node_returning_inconsistent_game - type error += | Cannot_produce_proof of Sc_rollup.Inbox.t * Sc_rollup.Inbox.history * Raw_level.t - -type error += | Missing_mode_operators of {mode : string; missing_operators : string list} + | Bad_minimal_fees of string + | Commitment_predecessor_should_be_LCC of Sc_rollup.Commitment.t + | Unreliable_tezos_node_returning_inconsistent_game + | Inconsistent_inbox of { + layer1_inbox : Sc_rollup.Inbox.t; + inbox : Sc_rollup.Inbox.t; + } let () = register_error_kind @@ -134,4 +133,27 @@ let () = Some (mode, missing_operators) | _ -> None) (fun (mode, missing_operators) -> - Missing_mode_operators {mode; missing_operators}) + Missing_mode_operators {mode; missing_operators}) ; + + register_error_kind + ~id:"internal.inconsistent_inbox" + ~title:"Internal error: Rollup node has an inconsistent inbox" + ~description: + "The rollup node inbox should be the same as the layer 1 inbox." + ~pp:(fun ppf (layer1_inbox, inbox) -> + Format.fprintf + ppf + "@[Rollup inbox:@;%a@]@;should be equal to @[Layer1 inbox:@;%a@]" + Sc_rollup.Inbox.pp + inbox + Sc_rollup.Inbox.pp + layer1_inbox) + `Permanent + Data_encoding.( + obj2 + (req "layer1_inbox" Sc_rollup.Inbox.encoding) + (req "inbox" Sc_rollup.Inbox.encoding)) + (function + | Inconsistent_inbox {layer1_inbox; inbox} -> Some (layer1_inbox, inbox) + | _ -> None) + (fun (layer1_inbox, inbox) -> Inconsistent_inbox {layer1_inbox; inbox}) -- GitLab From 5d31529320a949c5bcf7342be29d81bcd6af9d0c Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Thu, 28 Jul 2022 10:03:28 +0200 Subject: [PATCH 4/8] SCORU,Node: Check consistency with layer 1 inbox The rollup node maintains its own inbox because this inbox contains all the history required to produce inclusion proofs for refutation games. It is critical that the inbox descriptor of the rollup node stays consistent with the one computed by the layer 1 or else the refutation game will be lost by the rollup node. This invariant is unfortunately invalid: adding this check in the rollup node makes the integration tests fail, witnessing a bug in the rollup node. Signed-off-by: Yann Regis-Gianas --- src/proto_alpha/bin_sc_rollup_node/inbox.ml | 60 +++++++---- tezt/tests/sc_rollup.ml | 109 +++++++++++++++----- 2 files changed, 124 insertions(+), 45 deletions(-) diff --git a/src/proto_alpha/bin_sc_rollup_node/inbox.ml b/src/proto_alpha/bin_sc_rollup_node/inbox.ml index e5b69d06b86c..7cf61122ba4c 100644 --- a/src/proto_alpha/bin_sc_rollup_node/inbox.ml +++ b/src/proto_alpha/bin_sc_rollup_node/inbox.ml @@ -154,6 +154,17 @@ let get_messages Node_context.{l1_ctxt; rollup_address; _} head = in return (List.rev messages) +let same_inbox_as_layer_1 node_ctxt head_hash inbox = + let open Lwt_result_syntax in + let head_block = `Hash (head_hash, 0) in + let Node_context.{cctxt; rollup_address; _} = node_ctxt in + let* layer1_inbox = + Plugin.RPC.Sc_rollup.inbox cctxt (cctxt#chain, head_block) rollup_address + in + fail_unless + (Sc_rollup.Inbox.equal layer1_inbox inbox) + (Sc_rollup_node_errors.Inconsistent_inbox {layer1_inbox; inbox}) + let process_head node_ctxt store Layer1.(Head {level; hash = head_hash} as head) = let open Lwt_result_syntax in @@ -175,28 +186,33 @@ let process_head node_ctxt store Layer1.(Head {level; hash = head_hash} as head) let*! predecessor = Layer1.predecessor store head in let* inbox = State.inbox_of_hash node_ctxt store predecessor in let* history = State.history_of_hash node_ctxt store predecessor in - lift - @@ let*! messages_tree = State.find_message_tree store predecessor in - let*? level = Raw_level.of_int32 level in - let*? messages = List.map_e Store.Inbox.Message.serialize messages in - let* history, inbox = - if messages = [] then return (history, inbox) - else - let* messages_tree, history, inbox = - Store.Inbox.add_messages - store - history - inbox - level - messages - messages_tree - in - let*! () = State.set_message_tree store head_hash messages_tree in - return (history, inbox) - in - let*! () = State.add_inbox store head_hash inbox in - let*! () = State.add_history store head_hash history in - return_unit + let* inbox = + lift + @@ let*! messages_tree = State.find_message_tree store predecessor in + let*? level = Raw_level.of_int32 level in + let*? messages = List.map_e Store.Inbox.Message.serialize messages in + let* history, inbox = + if messages = [] then return (history, inbox) + else + let* messages_tree, history, inbox = + Store.Inbox.add_messages + store + history + inbox + level + messages + messages_tree + in + let*! () = + State.set_message_tree store head_hash messages_tree + in + return (history, inbox) + in + let*! () = State.add_inbox store head_hash inbox in + let*! () = State.add_history store head_hash history in + return inbox + in + same_inbox_as_layer_1 node_ctxt head_hash inbox let inbox_of_hash = State.inbox_of_hash diff --git a/tezt/tests/sc_rollup.ml b/tezt/tests/sc_rollup.ml index 636872adb3ad..7c59ce3c7abc 100644 --- a/tezt/tests/sc_rollup.ml +++ b/tezt/tests/sc_rollup.ml @@ -777,7 +777,9 @@ let basic_scenario _protocol sc_rollup_node sc_rollup _node client = let* () = send_messages num_messages sc_rollup client in let* level = Client.level client in Log.info "level: %d\n" level ; - let* _ = Sc_rollup_node.wait_for_level sc_rollup_node expected_level in + let* _ = + Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node expected_level + in return () let sc_rollup_node_stops_scenario _protocol sc_rollup_node sc_rollup _node @@ -793,7 +795,9 @@ let sc_rollup_node_stops_scenario _protocol sc_rollup_node sc_rollup _node let* () = Sc_rollup_node.terminate sc_rollup_node in let* () = send_messages num_messages sc_rollup client in let* () = Sc_rollup_node.run sc_rollup_node in - let* _ = Sc_rollup_node.wait_for_level sc_rollup_node expected_level in + let* _ = + Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node expected_level + in return () let sc_rollup_node_disconnects_scenario _protocol sc_rollup_node sc_rollup node @@ -834,7 +838,7 @@ let sc_rollup_node_handles_chain_reorg protocol sc_rollup_node sc_rollup node observe level 3. *) let* _ = Node.wait_for_level node 3 in let* _ = Node.wait_for_level node' 3 in - let* _ = Sc_rollup_node.wait_for_level sc_rollup_node 3 in + let* _ = Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node 3 in Log.info "Nodes are synchronized." ; let divergence () = @@ -863,7 +867,7 @@ let sc_rollup_node_handles_chain_reorg protocol sc_rollup_node sc_rollup node let* () = trigger_reorg () in (* After bringing [node'] back, our SCORU node should see that there is a more attractive head at level 5. *) - let* _ = Sc_rollup_node.wait_for_level sc_rollup_node 5 in + let* _ = Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node 5 in return () (* One can retrieve the list of originated SCORUs. @@ -939,7 +943,9 @@ let test_rollup_node_boots_into_initial_state ~kind = let* () = Sc_rollup_node.run sc_rollup_node in let sc_rollup_client = Sc_rollup_client.create sc_rollup_node in - let* level = Sc_rollup_node.wait_for_level sc_rollup_node init_level in + let* level = + Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node init_level + in Check.(level = init_level) Check.int ~error_msg:"Current level has moved past origination level (%L = %R)" ; @@ -993,7 +999,9 @@ let test_rollup_node_advances_pvm_state protocols ~kind = let* () = Sc_rollup_node.run sc_rollup_node in let sc_rollup_client = Sc_rollup_client.create sc_rollup_node in - let* level = Sc_rollup_node.wait_for_level sc_rollup_node init_level in + let* level = + Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node init_level + in Check.(level = init_level) Check.int ~error_msg:"Current level has moved past origination level (%L = %R)" ; @@ -1040,7 +1048,9 @@ let test_rollup_node_advances_pvm_state protocols ~kind = in Client.bake_for_and_wait client in - let* _ = Sc_rollup_node.wait_for_level sc_rollup_node (level + i) in + let* _ = + Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node (level + i) + in (* specific per kind PVM checks *) let* () = @@ -1235,7 +1245,9 @@ let commitment_stored _protocol sc_rollup_node sc_rollup _node client = in let* () = Sc_rollup_node.run sc_rollup_node in let sc_rollup_client = Sc_rollup_client.create sc_rollup_node in - let* level = Sc_rollup_node.wait_for_level sc_rollup_node init_level in + let* level = + Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node init_level + in Check.(level = init_level) Check.int ~error_msg:"Current level has moved past origination level (%L = %R)" ; @@ -1248,6 +1260,7 @@ let commitment_stored _protocol sc_rollup_node sc_rollup _node client = in let* _ = Sc_rollup_node.wait_for_level + ~timeout:3. sc_rollup_node (init_level + levels_to_commitment) in @@ -1256,7 +1269,10 @@ let commitment_stored _protocol sc_rollup_node sc_rollup _node client = processed by the rollup node as finalized. *) let* () = bake_levels block_finality_time client in let* _ = - Sc_rollup_node.wait_for_level sc_rollup_node store_commitment_level + Sc_rollup_node.wait_for_level + ~timeout:3. + sc_rollup_node + store_commitment_level in let* stored_commitment = Sc_rollup_client.last_stored_commitment ~hooks sc_rollup_client @@ -1367,17 +1383,23 @@ let commitment_not_stored_if_non_final _protocol sc_rollup_node sc_rollup _node let store_commitment_level = init_level + levels_to_commitment in let* () = Sc_rollup_node.run sc_rollup_node in let sc_rollup_client = Sc_rollup_client.create sc_rollup_node in - let* level = Sc_rollup_node.wait_for_level sc_rollup_node init_level in + let* level = + Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node init_level + in Check.(level = init_level) Check.int ~error_msg:"Current level has moved past origination level (%L = %R)" ; let* () = send_messages levels_to_commitment sc_rollup client in let* _ = - Sc_rollup_node.wait_for_level sc_rollup_node store_commitment_level + Sc_rollup_node.wait_for_level + ~timeout:3. + sc_rollup_node + store_commitment_level in let* () = bake_levels levels_to_finalize client in let* _ = Sc_rollup_node.wait_for_level + ~timeout:3. sc_rollup_node (store_commitment_level + levels_to_finalize) in @@ -1423,7 +1445,9 @@ let commitments_messages_reset _protocol sc_rollup_node sc_rollup _node client = in let* () = Sc_rollup_node.run sc_rollup_node in let sc_rollup_client = Sc_rollup_client.create sc_rollup_node in - let* level = Sc_rollup_node.wait_for_level sc_rollup_node init_level in + let* level = + Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node init_level + in Check.(level = init_level) Check.int ~error_msg:"Current level has moved past origination level (%L = %R)" ; @@ -1444,6 +1468,7 @@ let commitments_messages_reset _protocol sc_rollup_node sc_rollup _node client = let* () = bake_levels (levels_to_commitment + block_finality_time) client in let* _ = Sc_rollup_node.wait_for_level + ~timeout:3. sc_rollup_node (init_level + (2 * levels_to_commitment) + block_finality_time) in @@ -1498,7 +1523,9 @@ let commitment_stored_robust_to_failures _protocol sc_rollup_node sc_rollup node let sc_rollup_client' = Sc_rollup_client.create sc_rollup_node' in let* () = Sc_rollup_node.run sc_rollup_node in let* () = Sc_rollup_node.run sc_rollup_node' in - let* level = Sc_rollup_node.wait_for_level sc_rollup_node init_level in + let* level = + Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node init_level + in Check.(level = init_level) Check.int ~error_msg:"Current level has moved past origination level (%L = %R)" ; @@ -1514,11 +1541,13 @@ let commitment_stored_robust_to_failures _protocol sc_rollup_node sc_rollup node let* () = bake_levels (block_finality_time - 1) client in let* level_before_storing_commitment = Sc_rollup_node.wait_for_level + ~timeout:3. sc_rollup_node (init_level + levels_to_commitment + block_finality_time - 1) in let* _ = Sc_rollup_node.wait_for_level + ~timeout:3. sc_rollup_node' level_before_storing_commitment in @@ -1530,11 +1559,15 @@ let commitment_stored_robust_to_failures _protocol sc_rollup_node sc_rollup node let* () = Sc_rollup_node.run sc_rollup_node' in let* level_commitment_is_stored = Sc_rollup_node.wait_for_level + ~timeout:3. sc_rollup_node (level_before_storing_commitment + 1) in let* _ = - Sc_rollup_node.wait_for_level sc_rollup_node' level_commitment_is_stored + Sc_rollup_node.wait_for_level + ~timeout:3. + sc_rollup_node' + level_commitment_is_stored in let* stored_commitment = Sc_rollup_client.last_stored_commitment ~hooks sc_rollup_client @@ -1585,6 +1618,7 @@ let commitments_reorgs protocol sc_rollup_node sc_rollup node client = let* _ = Node.wait_for_level node' (init_level + levels_to_commitment - 1) in let* _ = Sc_rollup_node.wait_for_level + ~timeout:3. sc_rollup_node (init_level + levels_to_commitment - 1) in @@ -1631,6 +1665,7 @@ let commitments_reorgs protocol sc_rollup_node sc_rollup node client = *) let* _ = Sc_rollup_node.wait_for_level + ~timeout:3. sc_rollup_node (init_level + levels_to_commitment - 1 + num_empty_blocks) in @@ -1638,6 +1673,7 @@ let commitments_reorgs protocol sc_rollup_node sc_rollup node client = let* () = bake_levels (block_finality_time - num_empty_blocks + 1) client in let* _ = Sc_rollup_node.wait_for_level + ~timeout:3. sc_rollup_node (init_level + levels_to_commitment + block_finality_time) in @@ -1731,13 +1767,18 @@ let commitment_before_lcc_not_published _protocol sc_rollup_node sc_rollup node let* () = Sc_rollup_node.run sc_rollup_node in let sc_rollup_client = Sc_rollup_client.create sc_rollup_node in - let* level = Sc_rollup_node.wait_for_level sc_rollup_node init_level in + let* level = + Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node init_level + in Check.(level = init_level) Check.int ~error_msg:"Current level has moved past origination level (%L = %R)" ; let* () = bake_levels commitment_period client in let* commitment_inbox_level = - Sc_rollup_node.wait_for_level sc_rollup_node (init_level + commitment_period) + Sc_rollup_node.wait_for_level + ~timeout:3. + sc_rollup_node + (init_level + commitment_period) in (* Bake `block_finality_time` additional level to ensure that block number `init_level + sc_rollup_commitment_period_in_blocks` is processed by @@ -1745,6 +1786,7 @@ let commitment_before_lcc_not_published _protocol sc_rollup_node sc_rollup node let* () = bake_levels block_finality_time client in let* commitment_finalized_level = Sc_rollup_node.wait_for_level + ~timeout:3. sc_rollup_node (commitment_inbox_level + block_finality_time) in @@ -1777,6 +1819,7 @@ let commitment_before_lcc_not_published _protocol sc_rollup_node sc_rollup node let* () = bake_levels levels_to_cementation client in let* cemented_commitment_level = Sc_rollup_node.wait_for_level + ~timeout:3. sc_rollup_node (commitment_finalized_level + levels_to_cementation) in @@ -1795,7 +1838,10 @@ let commitment_before_lcc_not_published _protocol sc_rollup_node sc_rollup node cement_commitment client ~sc_rollup ~hash:cemented_commitment_hash in let* level_after_cementation = - Sc_rollup_node.wait_for_level sc_rollup_node (cemented_commitment_level + 1) + Sc_rollup_node.wait_for_level + ~timeout:3. + sc_rollup_node + (cemented_commitment_level + 1) in (* Withdraw stake after cementing should succeed *) @@ -1815,7 +1861,10 @@ let commitment_before_lcc_not_published _protocol sc_rollup_node sc_rollup node let* () = Sc_rollup_node.run sc_rollup_node' in let* rollup_node2_catchup_level = - Sc_rollup_node.wait_for_level sc_rollup_node' level_after_cementation + Sc_rollup_node.wait_for_level + ~timeout:3. + sc_rollup_node' + level_after_cementation in Check.(rollup_node2_catchup_level = level_after_cementation) Check.int @@ -1854,6 +1903,7 @@ let commitment_before_lcc_not_published _protocol sc_rollup_node sc_rollup node let commitment_inbox_level = commitment_inbox_level + commitment_period in let* _ = Sc_rollup_node.wait_for_level + ~timeout:3. sc_rollup_node' (level_after_cementation + commitment_period) in @@ -1896,13 +1946,18 @@ let first_published_level_is_global _protocol sc_rollup_node sc_rollup node let* commitment_period = get_sc_rollup_commitment_period_in_blocks client in let* () = Sc_rollup_node.run sc_rollup_node in let sc_rollup_client = Sc_rollup_client.create sc_rollup_node in - let* level = Sc_rollup_node.wait_for_level sc_rollup_node init_level in + let* level = + Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node init_level + in Check.(level = init_level) Check.int ~error_msg:"Current level has moved past origination level (%L = %R)" ; let* () = bake_levels commitment_period client in let* commitment_inbox_level = - Sc_rollup_node.wait_for_level sc_rollup_node (init_level + commitment_period) + Sc_rollup_node.wait_for_level + ~timeout:3. + sc_rollup_node + (init_level + commitment_period) in (* Bake `block_finality_time` additional level to ensure that block number `init_level + sc_rollup_commitment_period_in_blocks` is processed by @@ -1910,6 +1965,7 @@ let first_published_level_is_global _protocol sc_rollup_node sc_rollup node let* () = bake_levels block_finality_time client in let* commitment_finalized_level = Sc_rollup_node.wait_for_level + ~timeout:3. sc_rollup_node (commitment_inbox_level + block_finality_time) in @@ -1952,7 +2008,10 @@ let first_published_level_is_global _protocol sc_rollup_node sc_rollup node let* () = Sc_rollup_node.run sc_rollup_node' in let* rollup_node2_catchup_level = - Sc_rollup_node.wait_for_level sc_rollup_node' commitment_finalized_level + Sc_rollup_node.wait_for_level + ~timeout:3. + sc_rollup_node' + commitment_finalized_level in Check.(rollup_node2_catchup_level = commitment_finalized_level) Check.int @@ -2027,10 +2086,14 @@ let test_rollup_node_uses_arith_boot_sector = let* () = Sc_rollup_node.run sc_rollup_node in let sc_rollup_client = Sc_rollup_client.create sc_rollup_node in - let* level = Sc_rollup_node.wait_for_level sc_rollup_node init_level in + let* level = + Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node init_level + in let* () = send_text_messages client sc_rollup ["10 +"] in - let* _ = Sc_rollup_node.wait_for_level sc_rollup_node (level + 1) in + let* _ = + Sc_rollup_node.wait_for_level ~timeout:3. sc_rollup_node (level + 1) + in Sc_rollup_client.state_hash ~hooks sc_rollup_client in -- GitLab From ac101661cb7955dde32e081e6709547169f86ad3 Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Thu, 28 Jul 2022 10:12:08 +0200 Subject: [PATCH 5/8] SCORU,Node: Fix invalid level in empty inbox Signed-off-by: Yann Regis-Gianas --- src/proto_alpha/bin_sc_rollup_node/inbox.ml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/proto_alpha/bin_sc_rollup_node/inbox.ml b/src/proto_alpha/bin_sc_rollup_node/inbox.ml index 7cf61122ba4c..85079c31d0da 100644 --- a/src/proto_alpha/bin_sc_rollup_node/inbox.ml +++ b/src/proto_alpha/bin_sc_rollup_node/inbox.ml @@ -65,7 +65,10 @@ module State = struct let block_level = Raw_level.of_int32_exn block_level in if Raw_level.(block_level <= node_ctxt.genesis_info.level) then let*! inbox = - Store.Inbox.empty store node_ctxt.rollup_address Raw_level.root + Store.Inbox.empty + store + node_ctxt.rollup_address + node_ctxt.genesis_info.level in return inbox else -- GitLab From 5cf8f9c7eff61c74abb5739afba4847aa377b832 Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Thu, 28 Jul 2022 19:53:15 +0200 Subject: [PATCH 6/8] Proto,SCORU: Expose refresh_commitment_period for inbox We need to reset a message counter for commitment period when we enter a new level. This operation will be needed by the rollup node to fix a bug of inconsistency between the layer-1 inbox and the rollup node. Signed-off-by: Yann Regis-Gianas --- .../lib_protocol/alpha_context.mli | 3 +++ .../lib_protocol/sc_rollup_inbox_repr.ml | 17 +++++++++++++++ .../lib_protocol/sc_rollup_inbox_repr.mli | 13 ++++++------ .../lib_protocol/sc_rollup_inbox_storage.ml | 21 ++++--------------- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 03557875bcac..cf70be6a5047 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2830,6 +2830,9 @@ module Sc_rollup : sig val inbox_level : t -> Raw_level.t + val refresh_commitment_period : + commitment_period:int32 -> level:Raw_level.t -> t -> t + type history_proof type history diff --git a/src/proto_alpha/lib_protocol/sc_rollup_inbox_repr.ml b/src/proto_alpha/lib_protocol/sc_rollup_inbox_repr.ml index 36ce1e827efc..fd87602c7fa3 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_inbox_repr.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_inbox_repr.ml @@ -348,6 +348,23 @@ module V1 = struct let starting_level_of_current_commitment_period inbox = inbox.starting_level_of_current_commitment_period + + let refresh_commitment_period ~commitment_period ~level inbox = + let start = starting_level_of_current_commitment_period inbox in + let freshness = Raw_level_repr.diff level start in + let open Int32 in + let open Compare.Int32 in + if freshness >= commitment_period then ( + let nb_periods = + to_int ((mul (div freshness commitment_period)) commitment_period) + in + let new_starting_level = Raw_level_repr.(add start nb_periods) in + assert (Raw_level_repr.(new_starting_level <= level)) ; + assert ( + rem (Raw_level_repr.diff new_starting_level start) commitment_period + = 0l) ; + start_new_commitment_period inbox new_starting_level) + else inbox end type versioned = V1 of V1.t diff --git a/src/proto_alpha/lib_protocol/sc_rollup_inbox_repr.mli b/src/proto_alpha/lib_protocol/sc_rollup_inbox_repr.mli index 79399710e1a9..2fee2212587b 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_inbox_repr.mli +++ b/src/proto_alpha/lib_protocol/sc_rollup_inbox_repr.mli @@ -196,13 +196,12 @@ module V1 : sig the current commitment period. *) val number_of_messages_during_commitment_period : t -> int64 - (** [start_new_commitment_period inbox level] marks the beginning of a - new commitment period at some [level]. *) - val start_new_commitment_period : t -> Raw_level_repr.t -> t - - (** [starting_level_of_current_commitment_period inbox] returns the - level at the beginning of a current commitment period. *) - val starting_level_of_current_commitment_period : t -> Raw_level_repr.t + (** [refresh_commitment_period ~commitment_period ~level inbox] updates + [inbox] to take into account the commitment_period: this resets a + counter for the number of messages in a given commitment period + (which is limited). *) + val refresh_commitment_period : + commitment_period:int32 -> level:Raw_level_repr.t -> t -> t end (** Versioning, see {!Sc_rollup_data_version_sig.S} for more information. *) diff --git a/src/proto_alpha/lib_protocol/sc_rollup_inbox_storage.ml b/src/proto_alpha/lib_protocol/sc_rollup_inbox_storage.ml index 915b3ccaab55..bcee20228e61 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_inbox_storage.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_inbox_storage.ml @@ -81,24 +81,11 @@ let add_messages ctxt rollup messages = (0, 0, ctxt) messages in - let start = - Sc_rollup_inbox_repr.starting_level_of_current_commitment_period inbox - in - let freshness = Raw_level_repr.diff level start in let inbox = - let open Int32 in - let open Compare.Int32 in - if freshness >= commitment_period then ( - let nb_periods = - to_int ((mul (div freshness commitment_period)) commitment_period) - in - let new_starting_level = Raw_level_repr.(add start nb_periods) in - assert (Raw_level_repr.(new_starting_level <= level)) ; - assert ( - rem (Raw_level_repr.diff new_starting_level start) commitment_period - = 0l) ; - Sc_rollup_inbox_repr.start_new_commitment_period inbox new_starting_level) - else inbox + Sc_rollup_inbox_repr.refresh_commitment_period + ~commitment_period + ~level + inbox in let* () = assert_inbox_nb_messages_in_commitment_period ctxt inbox num_messages -- GitLab From 875f58cee74b28188f86035521e01fa2dbc45f9a Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Thu, 28 Jul 2022 19:54:35 +0200 Subject: [PATCH 7/8] SCORU,Node: Fix a bug of inbox inconsistency The rollup node was not resetting the counter of messages per commitment period. Signed-off-by: Yann Regis-Gianas --- src/proto_alpha/bin_sc_rollup_node/inbox.ml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/proto_alpha/bin_sc_rollup_node/inbox.ml b/src/proto_alpha/bin_sc_rollup_node/inbox.ml index 85079c31d0da..9e19fcb076e8 100644 --- a/src/proto_alpha/bin_sc_rollup_node/inbox.ml +++ b/src/proto_alpha/bin_sc_rollup_node/inbox.ml @@ -191,12 +191,22 @@ let process_head node_ctxt store Layer1.(Head {level; hash = head_hash} as head) let* history = State.history_of_hash node_ctxt store predecessor in let* inbox = lift - @@ let*! messages_tree = State.find_message_tree store predecessor in - let*? level = Raw_level.of_int32 level in + @@ let*? level = Raw_level.of_int32 level in + let*! messages_tree = State.find_message_tree store predecessor in let*? messages = List.map_e Store.Inbox.Message.serialize messages in let* history, inbox = if messages = [] then return (history, inbox) else + let commitment_period = + node_ctxt.protocol_constants.parametric.sc_rollup + .commitment_period_in_blocks |> Int32.of_int + in + let inbox = + Store.Inbox.refresh_commitment_period + ~commitment_period + ~level + inbox + in let* messages_tree, history, inbox = Store.Inbox.add_messages store -- GitLab From 6867124fa28b9bec3a52ae7c84752454b806be6b Mon Sep 17 00:00:00 2001 From: Yann Regis-Gianas Date: Thu, 28 Jul 2022 20:08:55 +0200 Subject: [PATCH 8/8] SCORU,Node: Check inbox consistency before storing inbox Signed-off-by: Yann Regis-Gianas --- src/proto_alpha/bin_sc_rollup_node/inbox.ml | 62 ++++++++++----------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/src/proto_alpha/bin_sc_rollup_node/inbox.ml b/src/proto_alpha/bin_sc_rollup_node/inbox.ml index 9e19fcb076e8..dc20343f575e 100644 --- a/src/proto_alpha/bin_sc_rollup_node/inbox.ml +++ b/src/proto_alpha/bin_sc_rollup_node/inbox.ml @@ -189,43 +189,41 @@ let process_head node_ctxt store Layer1.(Head {level; hash = head_hash} as head) let*! predecessor = Layer1.predecessor store head in let* inbox = State.inbox_of_hash node_ctxt store predecessor in let* history = State.history_of_hash node_ctxt store predecessor in - let* inbox = + let* history, inbox, messages_tree = lift @@ let*? level = Raw_level.of_int32 level in let*! messages_tree = State.find_message_tree store predecessor in let*? messages = List.map_e Store.Inbox.Message.serialize messages in - let* history, inbox = - if messages = [] then return (history, inbox) - else - let commitment_period = - node_ctxt.protocol_constants.parametric.sc_rollup - .commitment_period_in_blocks |> Int32.of_int - in - let inbox = - Store.Inbox.refresh_commitment_period - ~commitment_period - ~level - inbox - in - let* messages_tree, history, inbox = - Store.Inbox.add_messages - store - history - inbox - level - messages - messages_tree - in - let*! () = - State.set_message_tree store head_hash messages_tree - in - return (history, inbox) - in - let*! () = State.add_inbox store head_hash inbox in - let*! () = State.add_history store head_hash history in - return inbox + if messages = [] then return (history, inbox, messages_tree) + else + let commitment_period = + node_ctxt.protocol_constants.parametric.sc_rollup + .commitment_period_in_blocks |> Int32.of_int + in + let inbox = + Store.Inbox.refresh_commitment_period + ~commitment_period + ~level + inbox + in + let* messages_tree, history, inbox = + Store.Inbox.add_messages + store + history + inbox + level + messages + messages_tree + in + return (history, inbox, Some messages_tree) in - same_inbox_as_layer_1 node_ctxt head_hash inbox + let* () = same_inbox_as_layer_1 node_ctxt head_hash inbox in + let*! () = + Option.iter_s (State.set_message_tree store head_hash) messages_tree + in + let*! () = State.add_inbox store head_hash inbox in + let*! () = State.add_history store head_hash history in + return () let inbox_of_hash = State.inbox_of_hash -- GitLab