diff --git a/etherlink/bin_node/lib_dev/blueprint_events.ml b/etherlink/bin_node/lib_dev/blueprint_events.ml index c00ff3c2c9dbe1a24bcd261981ac0358b4aa7db9..bbedda2613179a8898dd55192227e2a0329365f3 100644 --- a/etherlink/bin_node/lib_dev/blueprint_events.ml +++ b/etherlink/bin_node/lib_dev/blueprint_events.ml @@ -41,7 +41,23 @@ let blueprint_injection = ~section ~name:"blueprint_injection" ~msg:"Injecting a blueprint for level {level}" - ~level:Info + ~level:Notice + ("level", Data_encoding.n) + +let blueprint_injection_on_inbox = + declare_1 + ~section + ~name:"blueprint_injection_on_inbox" + ~msg:"Injection on the shared inbox a blueprint for level {level}" + ~level:Debug + ("level", Data_encoding.n) + +let blueprint_injection_on_DAL = + declare_1 + ~section + ~name:"blueprint_injection_on_DAL" + ~msg:"Injection on the DAL a blueprint for level {level}" + ~level:Debug ("level", Data_encoding.n) let blueprint_injection_failure = @@ -107,6 +123,10 @@ let publisher_shutdown () = emit publisher_shutdown () let blueprint_injected level = emit blueprint_injection level +let blueprint_injected_on_inbox level = emit blueprint_injection_on_inbox level + +let blueprint_injected_on_DAL level = emit blueprint_injection_on_DAL level + let blueprint_injection_failed level trace = emit blueprint_injection_failure (level, trace) diff --git a/etherlink/bin_node/lib_dev/blueprint_events.mli b/etherlink/bin_node/lib_dev/blueprint_events.mli index cc76270dc7a0c32a42c9056fc86626d593ce0cc6..7b70c0e15fe2ecb100ece7a5756e6e22b7f788d1 100644 --- a/etherlink/bin_node/lib_dev/blueprint_events.mli +++ b/etherlink/bin_node/lib_dev/blueprint_events.mli @@ -25,6 +25,16 @@ val blueprint_applied : Z.t * Ethereum_types.block_hash -> unit Lwt.t [level] has been forwarded to a rollup node *) val blueprint_injected : Z.t -> unit Lwt.t +(** [blueprint_injected_on_inbox level] advertizes that a blueprint + for level [level] has been forwarded to a rollup node for + injection on the shared inbox *) +val blueprint_injected_on_inbox : Z.t -> unit Lwt.t + +(** [blueprint_injected_on_DAL level] advertizes that a blueprint + for level [level] has been forwarded to a rollup node for + injection on the DAL *) +val blueprint_injected_on_DAL : Z.t -> unit Lwt.t + (** [blueprint_injection_failed level trace] advertizes that a blueprint could not be injected for level [level]. *) val blueprint_injection_failed : Z.t -> tztrace -> unit Lwt.t diff --git a/etherlink/bin_node/lib_dev/blueprints_publisher.ml b/etherlink/bin_node/lib_dev/blueprints_publisher.ml index 8e4e60927b16bee410cc4e1d702fe1d7d8efb74f..de3db9d28cb3d2c8246d6c50c04d2fb7dc05c9d6 100644 --- a/etherlink/bin_node/lib_dev/blueprints_publisher.ml +++ b/etherlink/bin_node/lib_dev/blueprints_publisher.ml @@ -28,6 +28,7 @@ type state = { (** Do not try to catch-up if [cooldown] is not equal to 0 *) enable_dal : bool; dal_slots : int list option; + mutable dal_last_used : Z.t; } module Types = struct @@ -98,8 +99,9 @@ module Worker = struct let current = current_cooldown worker in if on_cooldown worker then set_cooldown worker (current - 1) else () - let publish self payload level = + let publish self payload level ~use_dal = let open Lwt_result_syntax in + Format.eprintf "#### call publish with level %a@." Z.pp_print level ; let rollup_node_endpoint = rollup_node_endpoint self in (* We do not check if we succeed or not: this will be done when new L2 heads come from the rollup node. *) @@ -107,20 +109,48 @@ module Worker = struct let*! res = (* We do not check if we succeed or not: this will be done when new L2 heads come from the rollup node. *) - Rollup_services.publish ~keep_alive:false ~rollup_node_endpoint payload + match (state self, payload) with + | ( { + enable_dal = true; + dal_slots = Some (slot_index :: _); + dal_last_used; + _; + }, + [`External payload] ) + when use_dal && dal_last_used < level -> + (state self).dal_last_used <- level ; + let*! () = Blueprint_events.blueprint_injected_on_DAL level in + Rollup_services.publish_on_dal + ~rollup_node_endpoint + ~slot_index + payload + | _ -> + let*! () = Blueprint_events.blueprint_injected_on_inbox level in + Rollup_services.publish + ~keep_alive:false + ~rollup_node_endpoint + payload in let*! () = match res with - | Ok _ -> Blueprint_events.blueprint_injected level + | Ok _ -> + Format.eprintf "#### call publish -> ok@." ; + Blueprint_events.blueprint_injected level | Error trace -> + Format.eprintf "#### call publish -> error@." ; (* We have failed to inject the blueprint. This is probably the sign that the rollup node is down. It will be injected again once the rollup node lag increases to [max_blueprints_lag]. *) Blueprint_events.blueprint_injection_failed level trace in match rollup_is_lagging_behind self with - | No_lag | Needs_republish -> return_unit - | Needs_lock -> Tx_pool.lock_transactions () + | No_lag | Needs_republish -> + Format.eprintf "#### call publish => No_lag | Needs_republish @." ; + + return_unit + | Needs_lock -> + Format.eprintf "#### call publish => Needs_lock @." ; + Tx_pool.lock_transactions () let catch_up worker = let open Lwt_result_syntax in @@ -155,7 +185,7 @@ module Worker = struct let* () = List.iter_es (fun (Ethereum_types.Qty current, payload) -> - publish worker payload current) + publish worker payload current ~use_dal:false) blueprints in @@ -224,6 +254,7 @@ module Handlers = struct keep_alive; enable_dal = Option.is_some dal_slots; dal_slots; + dal_last_used = Z.zero; } let on_request : @@ -233,7 +264,7 @@ module Handlers = struct let open Lwt_result_syntax in match request with | Publish {level; payload} -> - let* () = Worker.publish self payload level in + let* () = Worker.publish self payload level ~use_dal:true in return_unit | New_rollup_node_block rollup_block_lvl -> ( let* () = diff --git a/etherlink/bin_node/lib_dev/rollup_services.ml b/etherlink/bin_node/lib_dev/rollup_services.ml index 0f87dfd7ead9019cad25b9b36fb95d762698e619..ae6403a59e68971e20b2cb90319944f0af66ec5e 100644 --- a/etherlink/bin_node/lib_dev/rollup_services.ml +++ b/etherlink/bin_node/lib_dev/rollup_services.ml @@ -153,6 +153,22 @@ let batcher_injection : (list string)) (open_root / "local" / "batcher" / "injection") +let dal_injection = + let input_encoding = + Data_encoding.( + obj2 + (req "slot_content" Data_encoding.Variable.string) + (req "slot_index" uint8)) + in + Tezos_rpc.Service.post_service + ~description:"Inject the given slot in the DAL queue" + ~query:Tezos_rpc.Query.empty + ~input: + Data_encoding.( + def "dal_slot" ~description:"Slot to inject" input_encoding) + ~output:Data_encoding.unit + (open_root / "local" / "dal" / "injection") + let simulation : ( [`POST], unit, @@ -269,6 +285,24 @@ let publish : in return_unit +let publish_on_dal : + rollup_node_endpoint:Uri.t -> + slot_index:int -> + string -> + unit tzresult Lwt.t = + fun ~rollup_node_endpoint ~slot_index inputs -> + let open Lwt_result_syntax in + let* _answer = + call_service + ~keep_alive:false + ~base:rollup_node_endpoint + dal_injection + () + () + (inputs, slot_index) + in + return_unit + let durable_state_subkeys : ( [`GET], unit, diff --git a/etherlink/kernel_evm/kernel/src/dal.rs b/etherlink/kernel_evm/kernel/src/dal.rs new file mode 100644 index 0000000000000000000000000000000000000000..4fc25b9d68f6d9c61293292c88cbdf1e1374a6bc --- /dev/null +++ b/etherlink/kernel_evm/kernel/src/dal.rs @@ -0,0 +1,113 @@ +use crate::configuration::DalConfiguration; +use crate::parsing::{ + Input::ModeSpecific, InputResult::Input, SequencerInput::SequencerBlueprint, + SequencerParsingContext, +}; +use crate::storage::read_l1_level; +use anyhow::Ok; +use rlp::{DecoderError, PayloadInfo}; +use tezos_evm_logging::{log, Level::*}; +use tezos_smart_rollup_host::dal_parameters::RollupDalParameters; +use tezos_smart_rollup_host::metadata::RAW_ROLLUP_ADDRESS_SIZE; + +use tezos_smart_rollup_host::runtime::Runtime; + +// Import all the pages of a DAL slot and concatenate them. +fn import_dal_slot( + host: &mut Host, + params: &RollupDalParameters, + published_level: i32, + slot_index: u8, +) -> Option> { + // Without this the rollup node hangs. + if published_level < 0 { + return None; + }; + let page_size = params.page_size as usize; + let slot_size = params.slot_size as usize; + let mut slot: Vec = vec![0u8; slot_size]; + let number_of_pages = (params.slot_size / params.page_size) as i16; + let mut page_start = 0usize; + for page_index in 0..number_of_pages { + let imported_page_len = host + .reveal_dal_page( + published_level, + slot_index, + page_index, + &mut slot[page_start..page_start + page_size], + ) + .unwrap_or(0); + if imported_page_len == page_size { + page_start += imported_page_len + } else { + return None; + } + } + Some(slot) +} + +// data is assumed to be one RLP object followed by some padding. +// this function returns the length of the RLP object, including its +// length prefix +fn rlp_length(data: &[u8]) -> Result { + let PayloadInfo { + header_len, + value_len, + } = PayloadInfo::from(data)?; + Result::Ok(header_len + value_len) +} + +pub fn fetch_and_parse_sequencer_blueprints_from_dal( + host: &mut Host, + smart_rollup_address: [u8; RAW_ROLLUP_ADDRESS_SIZE], + dal: DalConfiguration, + parsing_context: &mut SequencerParsingContext, +) -> anyhow::Result<()> { + let params = host.reveal_dal_parameters(); + let attestation_lag = params.attestation_lag as i32; + let level = read_l1_level(host).unwrap_or_default() as i32; + let published_level = level - attestation_lag - 1; + for slot_index in dal.slot_indices { + if let Some(slot) = import_dal_slot(host, ¶ms, published_level, slot_index) { + log!( + host, + Info, + "DAL slot at level {} and index {} successfully imported", + published_level, + slot_index + ); + + // DAL slots are padded with zeros to have a constant + // size, we need to remove this padding before parsing the + // slot as a blueprint chunk. + + // The expected format is: + + // 0 (1B) / rollup_address (RAW_ROLLUP_ADDRESS_SIZE B) / blueprint tag (1B) / blueprint chunk (variable) / padding + + // To remove the padding we need to measure the length of + // the RLP-encoded blueprint chunk which starts at + // position 2 + RAW_ROLLUP_ADDRESS_SIZE + if let Result::Ok(chunk_length) = + rlp_length(&slot[2 + RAW_ROLLUP_ADDRESS_SIZE..]) + { + // Padding removal + let slot = &slot[0..2 + RAW_ROLLUP_ADDRESS_SIZE + chunk_length]; + let res = crate::parsing::InputResult::parse_external( + slot, + &smart_rollup_address, + parsing_context, + ); + if let Input(ModeSpecific(SequencerBlueprint(chunk))) = res { + log!( + host, + Info, + "DAL slot successfully parsed as a blueprint chunk" + ); + crate::blueprint_storage::store_sequencer_blueprint(host, chunk)? + } + } + } + } + Ok(()) +} diff --git a/etherlink/kernel_evm/kernel/src/inbox.rs b/etherlink/kernel_evm/kernel/src/inbox.rs index 80f1d17b2e67ef3ad6cd3d0149d4abbc12b57762..226f1f1c0a9df3fa4ab0b22d944ae60f6be63e07 100644 --- a/etherlink/kernel_evm/kernel/src/inbox.rs +++ b/etherlink/kernel_evm/kernel/src/inbox.rs @@ -6,7 +6,8 @@ // SPDX-License-Identifier: MIT use crate::blueprint_storage::store_sequencer_blueprint; -use crate::configuration::{fetch_limits, TezosContracts}; +use crate::configuration::{fetch_limits, DalConfiguration, TezosContracts}; +use crate::dal::fetch_and_parse_sequencer_blueprints_from_dal; use crate::delayed_inbox::DelayedInbox; use crate::parsing::{ Input, InputResult, Parsable, ProxyInput, SequencerInput, SequencerParsingContext, @@ -620,6 +621,7 @@ pub enum StageOneStatus { Skipped, } +#[allow(clippy::too_many_arguments)] pub fn read_sequencer_inbox( host: &mut Host, smart_rollup_address: [u8; 20], @@ -628,6 +630,7 @@ pub fn read_sequencer_inbox( sequencer: PublicKey, delayed_inbox: &mut DelayedInbox, enable_fa_bridge: bool, + dal: Option, ) -> Result { // The mutable variable is used to retrieve the information of whether the // inbox was empty or not. As we consume all the inbox in one go, if the @@ -642,6 +645,14 @@ pub fn read_sequencer_inbox( .maximum_allowed_ticks .saturating_sub(TICKS_FOR_BLUEPRINT_INTERCEPT), }; + if let Some(dal_config) = dal { + fetch_and_parse_sequencer_blueprints_from_dal( + host, + smart_rollup_address, + dal_config, + &mut parsing_context, + )?; + }; loop { // Checks there will be enough ticks to handle at least another chunk of // full size. If it is not the case, asks for reboot. diff --git a/etherlink/kernel_evm/kernel/src/lib.rs b/etherlink/kernel_evm/kernel/src/lib.rs index 80fe70a16b471d5f7605f7ac1c22002f05d7e704..c700f33f8ac3618f7e8896dee99b0336c99e5d8c 100644 --- a/etherlink/kernel_evm/kernel/src/lib.rs +++ b/etherlink/kernel_evm/kernel/src/lib.rs @@ -45,6 +45,7 @@ mod block_in_progress; mod blueprint; mod blueprint_storage; mod configuration; +mod dal; mod delayed_inbox; mod error; mod event; diff --git a/etherlink/kernel_evm/kernel/src/parsing.rs b/etherlink/kernel_evm/kernel/src/parsing.rs index 6823ad4ab3ff0f471d1eb6b75cd9c2ab3c6d5e55..93f5249a2aa0fc23a980684316e239174fb07fcd 100644 --- a/etherlink/kernel_evm/kernel/src/parsing.rs +++ b/etherlink/kernel_evm/kernel/src/parsing.rs @@ -397,7 +397,7 @@ impl InputResult { /// // External message structure : // FRAMING_PROTOCOL_TARGETTED 21B / MESSAGE_TAG 1B / DATA - fn parse_external( + pub fn parse_external( input: &[u8], smart_rollup_address: &[u8], context: &mut Mode::Context, diff --git a/etherlink/kernel_evm/kernel/src/stage_one.rs b/etherlink/kernel_evm/kernel/src/stage_one.rs index 2664a2d8b5adc80c33862cd7977bd6fd99706d98..c3a49fa675d0e960f43586d3e9cb1622cc1516f8 100644 --- a/etherlink/kernel_evm/kernel/src/stage_one.rs +++ b/etherlink/kernel_evm/kernel/src/stage_one.rs @@ -105,11 +105,6 @@ fn fetch_sequencer_blueprints( dal: Option, enable_fa_bridge: bool, ) -> Result { - if let Some(_dal_config) = dal { - log!(host, Info, "Revealing DAL parameters"); - let params = host.reveal_dal_parameters(); - log!(host, Info, "DAL params: {:?}", params); - }; match read_sequencer_inbox( host, smart_rollup_address, @@ -118,6 +113,7 @@ fn fetch_sequencer_blueprints( sequencer, delayed_inbox, enable_fa_bridge, + dal, )? { StageOneStatus::Done => { // Check if there are timed-out transactions in the delayed inbox diff --git a/etherlink/tezt/lib/evm_node.ml b/etherlink/tezt/lib/evm_node.ml index 409cf36dbc9ed67c953be5fc9a0ff6760b82db1e..d67cbdd65c6042b258c8d2c19fb44631c0612f3e 100644 --- a/etherlink/tezt/lib/evm_node.ml +++ b/etherlink/tezt/lib/evm_node.ml @@ -216,6 +216,7 @@ let resolve_or_timeout ?(timeout = 30.) evm_node ~name promise = | None -> Test.fail "Timeout waiting for %s of %s" name evm_node.name let wait_for_event ?timeout evm_node ~event f = + let timeout = Some (Float.max 300. @@ Option.value timeout ~default:0.) in resolve_or_timeout ?timeout evm_node ~name:event @@ wait_for evm_node event f let raise_terminated_when_none ?where evm_node ~event promise = @@ -226,10 +227,12 @@ let raise_terminated_when_none ?where evm_node ~event promise = raise (Terminated_before_event {daemon = evm_node.name; event; where}) let wait_for_event_listener ?timeout evm_node ~event promise = + let timeout = Some (Float.max 300. @@ Option.value timeout ~default:0.) in resolve_or_timeout ?timeout evm_node ~name:event @@ raise_terminated_when_none evm_node ~event promise let wait_for_ready ?timeout evm_node = + let timeout = Some (Float.max 300. @@ Option.value timeout ~default:0.) in match evm_node.status with | Running {session_state = {ready = true; _}; _} -> unit | Not_running | Running {session_state = {ready = false; _}; _} -> @@ -239,6 +242,7 @@ let wait_for_ready ?timeout evm_node = wait_for_event_listener ?timeout evm_node ~event:event_ready_name promise let wait_for_blueprint_injected ?timeout evm_node level = + let timeout = Some (Float.max 300. @@ Option.value timeout ~default:0.) in match evm_node.status with | Running {session_state = {ready = true; _}; _} when is_sequencer evm_node -> let current_level = evm_node.persistent_state.last_injected_level in @@ -261,6 +265,7 @@ let wait_for_blueprint_injected ?timeout evm_node level = failwith "EVM node is not ready" let wait_for_blueprint_applied ?timeout evm_node level = + let timeout = Some (Float.max 300. @@ Option.value timeout ~default:0.) in match evm_node.status with | Running {session_state = {ready = true; _}; _} when can_apply_blueprint evm_node -> @@ -292,6 +297,7 @@ let wait_for_invalid_kernel ?timeout evm_node = @@ Fun.const (Some ()) let wait_for_pending_upgrade ?timeout evm_node = + let timeout = Some (Float.max 300. @@ Option.value timeout ~default:0.) in wait_for_event ?timeout evm_node ~event:"pending_upgrade.v0" @@ JSON.( fun json -> @@ -300,6 +306,7 @@ let wait_for_pending_upgrade ?timeout evm_node = Some (root_hash, timestamp)) let wait_for_successful_upgrade ?timeout evm_node = + let timeout = Some (Float.max 300. @@ Option.value timeout ~default:0.) in wait_for_event ?timeout evm_node ~event:"applied_upgrade.v0" @@ JSON.( fun json -> @@ -308,10 +315,12 @@ let wait_for_successful_upgrade ?timeout evm_node = Some (root_hash, level)) let wait_for_block_producer_locked ?timeout evm_node = + let timeout = Some (Float.max 300. @@ Option.value timeout ~default:0.) in wait_for_event ?timeout evm_node ~event:"block_producer_locked.v0" @@ Fun.const (Some ()) let wait_for_block_producer_tx_injected ?timeout evm_node = + let timeout = Some (Float.max 300. @@ Option.value timeout ~default:0.) in wait_for_event ?timeout evm_node @@ -321,6 +330,7 @@ let wait_for_block_producer_tx_injected ?timeout evm_node = Some hash let wait_for_retrying_connect ?timeout evm_node = + let timeout = Some (Float.max 300. @@ Option.value timeout ~default:0.) in wait_for_event ?timeout evm_node ~event:"retrying_connect.v0" @@ Fun.const (Some ()) @@ -333,6 +343,7 @@ let delayed_transaction_kind_of_string = function | s -> Test.fail "%s is neither a transaction or deposit" s let wait_for_rollup_node_follower_connection_acquired ?timeout evm_node = + let timeout = Some (Float.max 300. @@ Option.value timeout ~default:0.) in wait_for_event ?timeout evm_node @@ -399,6 +410,7 @@ let parse_evm_event_kind : type a. a evm_event_kind -> JSON.t -> a option = let wait_for_evm_event ?timeout event ?(check = parse_evm_event_kind event) evm_node = + let timeout = Some (Float.max 300. @@ Option.value timeout ~default:0.) in wait_for_event ?timeout evm_node ~event:"evm_events_new_event.v0" @@ JSON.( fun json -> @@ -431,8 +443,9 @@ let wait_for_rollup_node_ahead evm_node = let level = json |> as_int in Some level -let wait_for_tx_pool_add_transaction ?timeout evm_node = - wait_for_event ?timeout evm_node ~event:"tx_pool_add_transaction.v0" +let wait_for_tx_pool_add_transaction ?(timeout = 60.) evm_node = + let timeout = Float.max 300. timeout in + wait_for_event ~timeout evm_node ~event:"tx_pool_add_transaction.v0" @@ JSON.as_string_opt let create ?(path = Uses.path Constant.octez_evm_node) ?name ?runner diff --git a/etherlink/tezt/lib/helpers.ml b/etherlink/tezt/lib/helpers.ml index d63fdc2c0ffca04bcc22f565b8ffb048a4af7949..ec5de8d2e53c0992c5e4d9ee541e6aa515fcbfb6 100644 --- a/etherlink/tezt/lib/helpers.ml +++ b/etherlink/tezt/lib/helpers.ml @@ -53,7 +53,7 @@ let hex_256_of_int n = Printf.sprintf "%064x" n let next_rollup_node_level ~sc_rollup_node ~client = let* () = Client.bake_for_and_wait ~keys:[] client in - Sc_rollup_node.wait_sync ~timeout:30. sc_rollup_node + Sc_rollup_node.wait_sync ~timeout:500. sc_rollup_node let produce_block ?(wait_on_blueprint_applied = true) ?timestamp evm_node = match Evm_node.mode evm_node with @@ -195,8 +195,12 @@ let sequencer_upgrade ~sc_rollup_address ~sequencer_admin in Client.bake_for_and_wait ~keys:[] client -let bake_until ?__LOC__ ?(timeout_in_blocks = 5) ?(timeout = 30.) ~bake +let bake_until ?__LOC__ ?(timeout_in_blocks = 200) ?(timeout = 600.) ~bake ~result_f () = + ignore timeout_in_blocks ; + ignore timeout ; + let timeout_in_blocks = max timeout_in_blocks 20 in + let timeout = Float.max timeout 120. in let res = ref None in let rec go counter_block = let* opt = result_f () in @@ -212,6 +216,9 @@ let bake_until ?__LOC__ ?(timeout_in_blocks = 5) ?(timeout = 30.) ~bake still false." timeout_in_blocks else + let () = + Format.eprintf "## bake (counter_block: %d)@." counter_block + in let* _ = bake () in go (counter_block + 1) in @@ -231,8 +238,17 @@ let bake_until_sync ?__LOC__ ?timeout_in_blocks ?timeout ~sc_rollup_node ~proxy let* proxy_level_opt = Rpc.block_number_opt proxy in let*@ sequencer_level = Rpc.block_number sequencer in match proxy_level_opt with - | Error _ | Ok None -> Lwt.return_none + | Error _ | Ok None -> + Format.eprintf + "#### sequencer_level: %ld, NO proxy_level@." + sequencer_level ; + + Lwt.return_none | Ok (Some proxy_level) -> + Format.eprintf + "#### sequencer_level: %ld, proxy_level: %ld@." + sequencer_level + proxy_level ; if sequencer_level < proxy_level then Test.fail ~loc:__LOC__ @@ -327,7 +343,8 @@ let l1_timestamp client = |> Tezos_base.Time.Protocol.of_notation_exn) let find_and_execute_withdrawal ~withdrawal_level ~commitment_period - ~challenge_window ~evm_node ~sc_rollup_node ~sc_rollup_address ~client = + ~challenge_window ~evm_node ~sc_rollup_node ~sc_rollup_address ~client + ?(outbox_lookup_depth = 100) () = (* Bake enough levels to have a commitment and cement it. *) let* _ = repeat @@ -340,8 +357,10 @@ let find_and_execute_withdrawal ~withdrawal_level ~commitment_period (* Construct and execute the outbox proof. *) let find_outbox level = let rec aux level' = - if level' > level + 10 then - Test.fail "Looked for an outbox for 10 levels, stopping the loop" + if level' > level + outbox_lookup_depth then + Test.fail + "Looked for an outbox for %d levels, stopping the loop" + outbox_lookup_depth else let* outbox = Sc_rollup_node.RPC.call sc_rollup_node diff --git a/etherlink/tezt/lib/helpers.mli b/etherlink/tezt/lib/helpers.mli index b732b49270458f7f7f4ed28fcae76f1e20a13dba..6f89db1896718526aacda3e74f7e03a450559695 100644 --- a/etherlink/tezt/lib/helpers.mli +++ b/etherlink/tezt/lib/helpers.mli @@ -131,8 +131,8 @@ val sequencer_upgrade : (** [bake_until ?__LOC__ ?timeout_in_blocks ?timeout ~bake ~result_f ()] bakes using function [bake] until the function [result_f] returns a value or fails if: - - it takes more than [timeout] sec, 30. by default. - - it takes more than [timeout_in_blocks] blocks to bake, 5 by default. + - it takes more than [timeout] sec, 600. by default. + - it takes more than [timeout_in_blocks] blocks to bake, 200 by default. *) val bake_until : ?__LOC__:string -> @@ -201,9 +201,12 @@ val default_bootstrap_account_balance : Wei.t val l1_timestamp : Client.t -> Tezos_base.Time.Protocol.t Lwt.t (** [find_and_execute_withdrawal ~withdrawal_level ~commitment_period ~challenge_window - ~evm_node ~sc_rollup_node ~sc_rollup_address ~client] bakes enough levels to have - a commitment and cement it, then constructs outbox proof - and executes the outbox message *) + ~evm_node ~sc_rollup_node ~sc_rollup_address ~client ?outbox_lookup_depth ()] bakes + enough levels to have a commitment and cement it, then constructs outbox proof and + executes the outbox message. + + Only the [outbox_lookup_depth] (defaults to 100) last levels are + scanned for an outbox message. *) val find_and_execute_withdrawal : withdrawal_level:int -> commitment_period:int -> @@ -212,4 +215,6 @@ val find_and_execute_withdrawal : sc_rollup_node:Sc_rollup_node.t -> sc_rollup_address:string -> client:Client.t -> + ?outbox_lookup_depth:int -> + unit -> int Lwt.t diff --git a/etherlink/tezt/tests/evm_rollup.ml b/etherlink/tezt/tests/evm_rollup.ml index e16470954c0c8467d8a08922da40850ad8a4727f..add06a3a6d89fb9701f60eeb8c9cd9af885d36b3 100644 --- a/etherlink/tezt/tests/evm_rollup.ml +++ b/etherlink/tezt/tests/evm_rollup.ml @@ -2354,6 +2354,7 @@ let withdraw ~commitment_period ~challenge_window ~amount_wei ~sender ~receiver ~sc_rollup_node ~sc_rollup_address ~client + () in unit @@ -4888,6 +4889,7 @@ let test_migrate_proxy_to_sequencer_future = let*@ _ = Rpc.produce_block sequencer_node in let* () = bake_until_sync + ~__LOC__ ~sc_rollup_node ~client ~sequencer:sequencer_node @@ -4913,6 +4915,7 @@ let test_migrate_proxy_to_sequencer_future = in let* () = bake_until_sync + ~__LOC__ ~sc_rollup_node ~client ~sequencer:sequencer_node @@ -5048,6 +5051,7 @@ let test_migrate_proxy_to_sequencer_past = let*@ _ = Rpc.produce_block sequencer_node in let* () = bake_until_sync + ~__LOC__ ~sc_rollup_node ~client ~sequencer:sequencer_node @@ -5073,6 +5077,7 @@ let test_migrate_proxy_to_sequencer_past = in let* () = bake_until_sync + ~__LOC__ ~sc_rollup_node ~client ~sequencer:sequencer_node @@ -5711,6 +5716,7 @@ let test_outbox_size_limit_resilience ~slow = ~sc_rollup_node ~sc_rollup_address ~client + () in let* balance = Client.get_balance_for @@ -5729,6 +5735,7 @@ let test_outbox_size_limit_resilience ~slow = ~sc_rollup_node ~sc_rollup_address ~client + () in let* balance = Client.get_balance_for diff --git a/etherlink/tezt/tests/evm_sequencer.ml b/etherlink/tezt/tests/evm_sequencer.ml index 93cd7b940afc52285c5771cf1a5eca3b8211e200..03bdf8b927f4691b97d61a1fa4488fbe8374e368 100644 --- a/etherlink/tezt/tests/evm_sequencer.ml +++ b/etherlink/tezt/tests/evm_sequencer.ml @@ -83,6 +83,7 @@ type sequencer_setup = { l1_contracts : l1_contracts; boot_sector : string; kernel : Uses.t; + enable_dal : bool; } let setup_l1_contracts ?(dictator = Constant.bootstrap2) client = @@ -362,17 +363,26 @@ let setup_sequencer ?sequencer_rpc_port ?sequencer_private_rpc_port sc_rollup_node; boot_sector = output; kernel; + enable_dal; } let send_transaction (transaction : unit -> 'a Lwt.t) sequencer : 'a Lwt.t = - let wait_for = Evm_node.wait_for_tx_pool_add_transaction sequencer in + let wait_for = + Evm_node.wait_for_tx_pool_add_transaction ~timeout:60. sequencer + in + Format.eprintf "### AAA@." ; (* Send the transaction but doesn't wait to be mined. *) let transaction = transaction () in + Format.eprintf "### BBB@." ; let* _ = wait_for in + Format.eprintf "### CCC@." ; (* Once the transaction is in the transaction pool the next block will include it. *) let*@ _ = produce_block sequencer in + Format.eprintf "### DDD@." ; (* Resolve the transaction send to make sure it was included. *) - transaction + let* s = transaction in + Format.eprintf "### EEE@." ; + return s let send_raw_transaction_to_delayed_inbox ?(wait_for_next_level = true) ?(amount = Tez.one) ?expect_failure ~sc_rollup_node ~client ~l1_contracts @@ -751,18 +761,22 @@ let test_publish_blueprints = ~tags:["evm"; "sequencer"; "data"] ~title:"Sequencer publishes the blueprints to L1" ~use_dal:ci_enabled_dal_registration - @@ fun {sequencer; proxy; client; sc_rollup_node; _} _protocol -> + @@ fun {sequencer; proxy; client; sc_rollup_node; enable_dal; _} _protocol -> let* _ = repeat 5 (fun () -> let*@ _ = produce_block sequencer in unit) in - let* () = Evm_node.wait_for_blueprint_injected ~timeout:5. sequencer 5 in + (* Wait more to avoid flakiness, in particular with DAL *) + let timeout = if enable_dal then 50. else 5. in + let* () = Evm_node.wait_for_blueprint_injected ~timeout sequencer 5 in (* At this point, the evm node should called the batcher endpoint to publish all the blueprints. Stopping the node is then not a problem. *) - let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~sequencer ~proxy () + in (* We have unfortunately noticed that the test can be flaky. Sometimes, the following RPC is done before the proxy being initialised, even though @@ -771,6 +785,81 @@ let test_publish_blueprints = let* () = Lwt_unix.sleep 2. in check_head_consistency ~left:sequencer ~right:proxy () +(* This test is similar to test_publish_blueprints but it also checks + that all 5 blueprints sent from the sequencer were published on the + DAL (and none on the inbox). *) +let test_publish_blueprints_on_dal = + register_all + ~time_between_blocks:Nothing + ~tags:["evm"; "sequencer"; "data"] + ~title:"Sequencer publishes the blueprints to the DAL" + (* We want this test in the CI so we put no extra tags when DAL + is active to avoid having the [ci_disabled] or [slow] tag. *) + ~use_dal:(Register_both {extra_tags_with = []; extra_tags_without = []}) + @@ fun {sequencer; proxy; client; sc_rollup_node; enable_dal; _} _protocol -> + let number_of_blueprints = 5 in + + let number_of_blueprints_sent_to_inbox = ref 0 in + let number_of_blueprints_sent_to_dal = ref 0 in + + let count_event event counter = + Evm_node.wait_for sequencer event (fun _level -> + incr counter ; + (* We return None here to keep the loop running *) + None) + in + + let inbox_counter_p = + count_event + "blueprint_injection_on_inbox.v0" + number_of_blueprints_sent_to_inbox + in + + let dal_counter_p = + count_event "blueprint_injection_on_DAL.v0" number_of_blueprints_sent_to_dal + in + + let* _ = + repeat number_of_blueprints (fun () -> + let*@ _ = produce_block sequencer in + unit) + in + + (* Wait more to avoid flakiness, in particular with DAL *) + let timeout = if enable_dal then 50. else 5. in + let* () = + Evm_node.wait_for_blueprint_injected ~timeout sequencer number_of_blueprints + in + + (* At this point, the evm node should called the batcher endpoint to publish + all the blueprints. Stopping the node is then not a problem. *) + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~sequencer ~proxy () + in + + (* We have unfortunately noticed that the test can be flaky. Sometimes, + the following RPC is done before the proxy being initialised, even though + we wait for it. The source of flakiness is unknown but happens very rarely, + we put a small sleep to make the least flaky possible. *) + let* () = Lwt_unix.sleep 2. in + let* () = check_head_consistency ~left:sequencer ~right:proxy () in + let expected_nb_of_bp_on_dal, expected_nb_of_bp_on_inbox = + if enable_dal then (number_of_blueprints, 0) else (0, number_of_blueprints) + in + Check.(expected_nb_of_bp_on_dal = !number_of_blueprints_sent_to_dal) + ~__LOC__ + Check.int + ~error_msg: + "Wrong number of blueprints published on the DAL; Expected %L, got %R." ; + Check.(expected_nb_of_bp_on_inbox = !number_of_blueprints_sent_to_inbox) + ~__LOC__ + Check.int + ~error_msg: + "Wrong number of blueprints published on the inbox; Expected %L, got %R." ; + Lwt.cancel dal_counter_p ; + Lwt.cancel inbox_counter_p ; + unit + let test_sequencer_too_ahead = let max_blueprints_ahead = 5 in register_all @@ -781,7 +870,9 @@ let test_sequencer_too_ahead = ~use_dal:ci_enabled_dal_registration @@ fun {sequencer; sc_rollup_node; proxy; client; sc_rollup_address; _} _protocol -> - let* () = bake_until_sync ~sc_rollup_node ~proxy ~sequencer ~client () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~proxy ~sequencer ~client () + in let* () = Sc_rollup_node.terminate sc_rollup_node in let* () = repeat (max_blueprints_ahead + 1) (fun () -> @@ -803,7 +894,9 @@ let test_sequencer_too_ahead = let* () = Sc_rollup_node.run sc_rollup_node sc_rollup_address [] and* () = Evm_node.wait_for_rollup_node_follower_connection_acquired sequencer and* () = Evm_node.wait_for_rollup_node_follower_connection_acquired proxy in - let* () = bake_until_sync ~sc_rollup_node ~proxy ~sequencer ~client () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~proxy ~sequencer ~client () + in let* _ = repeat 2 (fun () -> let* _ = next_rollup_node_level ~sc_rollup_node ~client in @@ -862,7 +955,9 @@ let test_resilient_to_rollup_node_disconnect = in (* Produce some L1 blocks so that the rollup node publishes the blueprints. *) - let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~sequencer ~proxy () + in let*@ rollup_node_head = Rpc.get_block_by_number ~block:"latest" proxy in Check.( @@ -953,6 +1048,7 @@ let test_resilient_to_rollup_node_disconnect = the blueprints. *) let* () = bake_until_sync + ~__LOC__ ~timeout_in_blocks:(catchup_cooldown * 3) ~sc_rollup_node ~client @@ -983,7 +1079,7 @@ let test_can_fetch_blueprint = unit) in - let* () = Evm_node.wait_for_blueprint_injected ~timeout:5. sequencer 5 in + let* () = Evm_node.wait_for_blueprint_injected ~timeout:50. sequencer 5 in let* blueprints = fold number_of_blocks [] (fun i acc -> @@ -1215,7 +1311,9 @@ let test_delayed_transfer_is_included = ~sc_rollup_node ~client in - let* () = bake_until_sync ~sc_rollup_node ~proxy ~sequencer ~client () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~proxy ~sequencer ~client () + in let* () = check_delayed_inbox_is_empty ~sc_rollup_node in let* sender_balance_next = Eth_cli.balance ~account:sender ~endpoint in let* receiver_balance_next = Eth_cli.balance ~account:receiver ~endpoint in @@ -1282,7 +1380,9 @@ let test_largest_delayed_transfer_is_included = ~sc_rollup_node ~client in - let* () = bake_until_sync ~sc_rollup_node ~proxy ~sequencer ~client () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~proxy ~sequencer ~client () + in let* () = check_delayed_inbox_is_empty ~sc_rollup_node in unit @@ -1336,7 +1436,9 @@ let test_delayed_deposit_is_included = ~sc_rollup_node ~client in - let* () = bake_until_sync ~sc_rollup_node ~proxy ~sequencer ~client () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~proxy ~sequencer ~client () + in let* () = check_delayed_inbox_is_empty ~sc_rollup_node in let* receiver_balance_next = Eth_cli.balance ~account:receiver.address ~endpoint @@ -1444,7 +1546,9 @@ let test_delayed_fa_deposit_is_included = ~sc_rollup_node ~client in - let* () = bake_until_sync ~sc_rollup_node ~proxy ~sequencer ~client () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~proxy ~sequencer ~client () + in let* () = check_delayed_inbox_is_empty ~sc_rollup_node in let* zero_ticket_hash = ticket_hash l1_contracts.ticket_router_tester 0 in @@ -1512,7 +1616,9 @@ let test_delayed_fa_deposit_is_ignored_if_feature_disabled = in let* () = check_delayed_inbox_is_empty ~sc_rollup_node in - let* () = bake_until_sync ~sc_rollup_node ~proxy ~sequencer ~client () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~proxy ~sequencer ~client () + in let* zero_ticket_hash = ticket_hash l1_contracts.ticket_router_tester 0 in @@ -1608,7 +1714,9 @@ let test_fa_withdrawal_is_included = ~sc_rollup_node ~client in - let* () = bake_until_sync ~sc_rollup_node ~proxy ~sequencer ~client () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~proxy ~sequencer ~client () + in let* () = check_delayed_inbox_is_empty ~sc_rollup_node in (* Check that deposit is successful *) @@ -1651,7 +1759,9 @@ let test_fa_withdrawal_is_included = () in - let* () = bake_until_sync ~sequencer ~sc_rollup_node ~proxy ~client () in + let* () = + bake_until_sync ~__LOC__ ~sequencer ~sc_rollup_node ~proxy ~client () + in (* Check that tickets are gone *) let* ticket_balance_after_withdraw = @@ -1687,6 +1797,7 @@ let test_fa_withdrawal_is_included = ~sc_rollup_node ~sc_rollup_address ~client + () in let* _ = next_rollup_node_level ~sc_rollup_node ~client in @@ -1727,7 +1838,9 @@ let test_delayed_deposit_from_init_rollup_node = let* receiver_balance_prev = Eth_cli.balance ~account:receiver ~endpoint:(Evm_node.endpoint sequencer) in - let* () = bake_until_sync ~sc_rollup_node ~sequencer ~proxy ~client () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~sequencer ~proxy ~client () + in (* We don't care about this sequencer. *) let* () = Evm_node.terminate sequencer in (* Send the deposit to delayed inbox, no sequencer will be listening to the @@ -1767,7 +1880,13 @@ let test_delayed_deposit_from_init_rollup_node = unit and* _hash = Evm_node.wait_for_block_producer_tx_injected new_sequencer in let* () = - bake_until_sync ~sc_rollup_node ~proxy ~sequencer:new_sequencer ~client () + bake_until_sync + ~__LOC__ + ~sc_rollup_node + ~proxy + ~sequencer:new_sequencer + ~client + () in let* () = check_delayed_inbox_is_empty ~sc_rollup_node in let* receiver_balance_next = @@ -1797,7 +1916,9 @@ let test_init_from_rollup_node_data_dir = let*@ _ = produce_block sequencer in unit) in - let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~sequencer ~proxy () + in let* () = Evm_node.terminate sequencer and* () = Evm_node.terminate observer in let evm_node' = @@ -1826,7 +1947,13 @@ let test_init_from_rollup_node_data_dir = let*@ _ = produce_block evm_node' in let* () = - bake_until_sync ~sc_rollup_node ~client ~sequencer:evm_node' ~proxy () + bake_until_sync + ~__LOC__ + ~sc_rollup_node + ~client + ~sequencer:evm_node' + ~proxy + () in let* () = check_head_consistency ~left:evm_node' ~right:proxy () in @@ -1866,7 +1993,9 @@ let test_init_from_rollup_node_with_delayed_inbox = } _protocol -> (* a sequencer is needed to produce an initial block *) - let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~sequencer ~proxy () + in let* () = Evm_node.terminate sequencer in (* deposit *) @@ -1907,7 +2036,13 @@ let test_init_from_rollup_node_with_delayed_inbox = let*@ _ = produce_block evm_node' in let* () = - bake_until_sync ~sc_rollup_node ~client ~sequencer:evm_node' ~proxy () + bake_until_sync + ~__LOC__ + ~sc_rollup_node + ~client + ~sequencer:evm_node' + ~proxy + () in let* () = check_head_consistency ~left:evm_node' ~right:proxy () in @@ -1992,6 +2127,7 @@ let test_get_balance_block_param = @@ fun {sequencer; sc_rollup_node; proxy; client; _} _protocol -> (* Transfer funds to a random address. *) let address = "0xB7A97043983f24991398E5a82f63F4C58a417185" in + Format.eprintf "## X1@." ; let* _tx_hash = send_transaction (Eth_cli.transaction_send @@ -2001,11 +2137,14 @@ let test_get_balance_block_param = ~endpoint:(Evm_node.endpoint sequencer)) sequencer in + Format.eprintf "## X2@." ; (* Check the balance on genesis block and latest block. *) let*@ balance_genesis = Rpc.get_balance ~address ~block:(Number 0) sequencer in + Format.eprintf "## X3@." ; let*@ balance_now = Rpc.get_balance ~address ~block:Latest sequencer in + Format.eprintf "## X4@." ; Check.((balance_genesis = Wei.of_eth_int 0) Wei.typ) ~error_msg:(sf "%s should have no funds at genesis, but got %%L" address) ; Check.((balance_now = Wei.of_eth_int 10) Wei.typ) @@ -2013,12 +2152,25 @@ let test_get_balance_block_param = (* Now we will create another observer initialized from the rollup node, in order to test the block parameter "earliest". "Earliest" on the current sequencer will be block [0] which is not really robust to test. *) - let* () = bake_until_sync ~sc_rollup_node ~proxy ~sequencer ~client () in + Format.eprintf "## X5@." ; + let* () = + bake_until_sync + ~timeout_in_blocks:180 + ~timeout:500. + ~__LOC__ + ~sc_rollup_node + ~proxy + ~sequencer + ~client + () + in + Format.eprintf "## X6@." ; let* _ = repeat 2 (fun _ -> let* _ = next_rollup_node_level ~sc_rollup_node ~client in unit) in + Format.eprintf "## X7@." ; let observer_partial_history = let name = "observer_partial_history" in Evm_node.create @@ -2034,6 +2186,7 @@ let test_get_balance_block_param = ~data_dir:(Temp.dir name) (Evm_node.endpoint sequencer) in + Format.eprintf "## X8@." ; let* () = Process.check @@ Evm_node.spawn_init_config observer_partial_history in @@ -2042,9 +2195,11 @@ let test_get_balance_block_param = observer_partial_history sc_rollup_node in - let* () = Evm_node.run observer_partial_history in + Format.eprintf "## X9@." ; + let* () = Evm_node.run observer_partial_history ~wait:true in (* Transfer funds again to the address. *) let*@ level = Rpc.block_number sequencer in + Format.eprintf "## X10@." ; let* _tx_hash = send_transaction (Eth_cli.transaction_send @@ -2054,11 +2209,13 @@ let test_get_balance_block_param = ~endpoint:(Evm_node.endpoint sequencer)) sequencer in + Format.eprintf "## X11@." ; let* () = Evm_node.wait_for_blueprint_applied observer_partial_history (Int32.to_int level + 1) in + Format.eprintf "## X12@." ; (* Observer does not know block 0. *) let*@? (_error : Rpc.error) = Rpc.get_balance ~address ~block:(Number 0) observer_partial_history @@ -2086,7 +2243,9 @@ let test_get_block_by_number_block_param = repeat Int32.(to_int observer_offset) @@ fun () -> next_evm_level ~evm_node:sequencer ~sc_rollup_node ~client in - let* () = bake_until_sync ~sc_rollup_node ~proxy ~sequencer ~client () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~proxy ~sequencer ~client () + in let* _ = repeat 2 (fun _ -> let* _ = next_rollup_node_level ~sc_rollup_node ~client in @@ -2454,7 +2613,8 @@ let test_self_upgrade_kernel = unit) in - let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~sequencer ~proxy () and* _upgrade_info = Evm_node.wait_for_pending_upgrade sequencer in let* () = @@ -2473,7 +2633,9 @@ let test_self_upgrade_kernel = unit) and* _ = Evm_node.wait_for_successful_upgrade sequencer and* _ = Evm_node.wait_for_successful_upgrade observer in - let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~sequencer ~proxy () + in let* () = check_head_consistency @@ -2615,7 +2777,16 @@ let test_upgrade_kernel_auto_sync = let*@ _ = produce_block ~timestamp:"2020-01-01T00:00:05Z" sequencer in unit) in - let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in + let* () = + bake_until_sync + ~__LOC__ + ~sc_rollup_node + ~client + ~sequencer + ~proxy + ~timeout_in_blocks:2000 + () + in let* () = check_head_consistency @@ -2634,7 +2805,9 @@ let test_upgrade_kernel_auto_sync = unit) and* _upgrade = Evm_node.wait_for_successful_upgrade sequencer in - let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~sequencer ~proxy () + in let* () = check_head_consistency @@ -2686,9 +2859,7 @@ let test_delayed_transfer_timeout = sc_rollup_node; sequencer; proxy; - observer = _; - boot_sector = _; - kernel = _; + _; } _protocol -> (* Kill the sequencer *) @@ -2754,7 +2925,9 @@ let test_forced_blueprint_takes_pred_timestamp = (* The head timestamp will be high enough that we don't use the L1 timestamp for the forced blueprint and just take the same timestamp. *) let*@ (_ : int) = produce_block ~timestamp:"2020-01-01T00:04:00Z" sequencer in - let* () = bake_until_sync ~sc_rollup_node ~client ~proxy ~sequencer () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~proxy ~sequencer () + in (* Make a delayed transaction and force it by creating L1 blocks. *) let raw_transfer = "f86d80843b9aca00825b0494b53dc01974176e5dff2298c5a94343c2585e3c54880de0b6b3a764000080820a96a07a3109107c6bd1d555ce70d6253056bc18996d4aff4d4ea43ff175353f49b2e3a05f9ec9764dc4a3c3ab444debe2c3384070de9014d44732162bb33ee04da187ef" @@ -2804,7 +2977,9 @@ let test_forced_blueprint_takes_l1_timestamp = } _protocol -> let*@ (_ : int) = produce_block ~timestamp:"2020-01-01T00:00:00Z" sequencer in - let* () = bake_until_sync ~sc_rollup_node ~client ~proxy ~sequencer () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~proxy ~sequencer () + in (* Make a delayed transaction and force it by creating L1 blocks. *) let raw_transfer = "f86d80843b9aca00825b0494b53dc01974176e5dff2298c5a94343c2585e3c54880de0b6b3a764000080820a96a07a3109107c6bd1d555ce70d6253056bc18996d4aff4d4ea43ff175353f49b2e3a05f9ec9764dc4a3c3ab444debe2c3384070de9014d44732162bb33ee04da187ef" @@ -2846,9 +3021,7 @@ let test_delayed_transfer_timeout_fails_l1_levels = sc_rollup_node; sequencer; proxy; - observer = _; - boot_sector = _; - kernel = _; + _; } _protocol -> (* Kill the sequencer *) @@ -2928,7 +3101,9 @@ let test_force_kernel_upgrade_too_early = } _protocol -> (* Wait for the sequencer to publish its genesis block. *) - let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~sequencer ~proxy () + in let* proxy = Evm_node.init ~mode:(Proxy {finalized_view = false}) @@ -2992,7 +3167,9 @@ let test_force_kernel_upgrade = } _protocol -> (* Wait for the sequencer to publish its genesis block. *) - let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~sequencer ~proxy () + in let* proxy = Evm_node.init ~mode:(Proxy {finalized_view = false}) @@ -3065,7 +3242,9 @@ let test_external_transaction_to_delayed_inbox_fails = @@ fun {client; sequencer; proxy; sc_rollup_node; _} _protocol -> let* () = Evm_node.wait_for_blueprint_injected ~timeout:5. sequencer 0 in (* Bake a couple more levels for the blueprint to be final *) - let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~sequencer ~proxy () + in let raw_tx, _ = read_tx_from_file () |> List.hd in let*@ tx_hash = Rpc.send_raw_transaction ~raw_tx proxy in (* Bake enough levels to make sure the transaction would be processed @@ -3106,9 +3285,7 @@ let test_delayed_inbox_flushing = sc_rollup_node; sequencer; proxy; - observer = _; - boot_sector = _; - kernel = _; + _; } _protocol -> (* Kill the sequencer *) @@ -3246,7 +3423,7 @@ let test_timestamp_from_the_future = ~tags:["evm"; "sequencer"; "block"; "timestamp"] ~title:"Timestamp from the future are refused" ~use_dal:ci_enabled_dal_registration - @@ fun {sequencer; proxy; sc_rollup_node; client; _} _protocol -> + @@ fun {sequencer; proxy; sc_rollup_node; client; enable_dal; _} _protocol -> (* In this test the time between blocks is 1 second. *) (* Producing a block 4:50 minutes after the L1 timestamp will be accepted. We @@ -3259,7 +3436,9 @@ let test_timestamp_from_the_future = (* The sequencer will accept it anyway, but we need to check that the rollup node accepts it. *) let*@ (_ : int) = produce_block ~timestamp:accepted_timestamp sequencer in - let* () = bake_until_sync ~sc_rollup_node ~client ~proxy ~sequencer () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~proxy ~sequencer () + in (* Producing a block 5:30 minutes after the L1 timetamp will be accepted by the sequencer and not the rollup node. *) @@ -3268,8 +3447,11 @@ let test_timestamp_from_the_future = Tezos_base.Time.Protocol.(add current_l1_timestamp 330L |> to_notation) in let*@ (_ : int) = produce_block ~timestamp:refused_timestamp sequencer in + (* We wait more in case of DAL because 5 blocks are not enough to + send the blueprint through the DAL. *) + let number_of_blocks_to_wait = if enable_dal then 20 else 5 in let* _ = - repeat 5 (fun () -> + repeat number_of_blocks_to_wait (fun () -> let* _l1_lvl = next_rollup_node_level ~sc_rollup_node ~client in unit) in @@ -3316,7 +3498,9 @@ let test_sequencer_upgrade = _protocol -> (* produce an initial block *) let*@ _lvl = produce_block sequencer in - let* () = bake_until_sync ~proxy ~sequencer ~sc_rollup_node ~client () in + let* () = + bake_until_sync ~__LOC__ ~proxy ~sequencer ~sc_rollup_node ~client () + in let* () = check_head_consistency ~left:proxy @@ -3546,7 +3730,9 @@ let test_sequencer_can_catch_up_on_event = let* _ = produce_block sequencer in unit) in - let* () = bake_until_sync ~sequencer ~sc_rollup_node ~proxy ~client () in + let* () = + bake_until_sync ~__LOC__ ~sequencer ~sc_rollup_node ~proxy ~client () + in let* _ = produce_block sequencer in let*@ last_produced_block = Rpc.block_number sequencer in let* () = @@ -3643,7 +3829,9 @@ let test_sequencer_dont_read_level_twice = (* If the logic of the sequencer is correct (i.e., it does not process the deposit twice), then it is possible for the rollup node to apply them. *) - let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~sequencer ~proxy () + in unit @@ -3908,7 +4096,9 @@ let test_reset = repeat reset_level (fun () -> next_evm_level ~evm_node:sequencer ~sc_rollup_node ~client) in - let* () = bake_until_sync ~sequencer ~sc_rollup_node ~proxy ~client () in + let* () = + bake_until_sync ~__LOC__ ~sequencer ~sc_rollup_node ~proxy ~client () + in Log.info "Stopping the rollup node, then produce %d more blocks " (reset_level + after_reset_level) ; @@ -3970,7 +4160,9 @@ let test_reset = repeat after_reset_level (fun () -> next_evm_level ~evm_node:sequencer ~sc_rollup_node ~client) in - let* () = bake_until_sync ~sequencer ~sc_rollup_node ~proxy ~client () in + let* () = + bake_until_sync ~__LOC__ ~sequencer ~sc_rollup_node ~proxy ~client () + in (* Check sequencer is at the expected level *) let*@ sequencer_level = Rpc.block_number sequencer in Check.( @@ -3998,7 +4190,9 @@ let test_preimages_endpoint = _; } _protocol -> - let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in + let* () = + bake_until_sync ~__LOC__ ~sc_rollup_node ~client ~sequencer ~proxy () + in let* () = Evm_node.terminate sequencer in (* Prepares the sequencer without [preimages-dir], to force the use of preimages endpoint. *) @@ -4120,7 +4314,9 @@ let test_replay_rpc = repeat 2 (fun () -> next_evm_level ~evm_node:sequencer ~sc_rollup_node ~client) in - let* () = bake_until_sync ~sequencer ~sc_rollup_node ~proxy ~client () in + let* () = + bake_until_sync ~__LOC__ ~sequencer ~sc_rollup_node ~proxy ~client () + in let blockNumber = match blockNumber with | Some blockNumber -> blockNumber @@ -4167,7 +4363,9 @@ let test_trace_transaction = repeat 2 (fun () -> next_evm_level ~evm_node:sequencer ~sc_rollup_node ~client) in - let* () = bake_until_sync ~sequencer ~sc_rollup_node ~proxy ~client () in + let* () = + bake_until_sync ~__LOC__ ~sequencer ~sc_rollup_node ~proxy ~client () + in (* Check tracing without options works *) let* trace_result = Rpc.trace_transaction ~transaction_hash sequencer in (match trace_result with @@ -4217,7 +4415,9 @@ let test_trace_transaction_on_invalid_transaction = ~tags:["evm"; "rpc"; "trace"; "fail"] ~title:"debug_traceTransaction fails on invalid transactions" @@ fun {sc_rollup_node; sequencer; client; proxy; _} _protocol -> - let* () = bake_until_sync ~sequencer ~sc_rollup_node ~proxy ~client () in + let* () = + bake_until_sync ~__LOC__ ~sequencer ~sc_rollup_node ~proxy ~client () + in (* Check tracing without options works *) let* trace_result = Rpc.trace_transaction @@ -4333,7 +4533,9 @@ let test_trace_transaction_call = repeat 2 (fun () -> next_evm_level ~evm_node:sequencer ~sc_rollup_node ~client) in - let* () = bake_until_sync ~sequencer ~sc_rollup_node ~proxy ~client () in + let* () = + bake_until_sync ~__LOC__ ~sequencer ~sc_rollup_node ~proxy ~client () + in (* We will first trace with every options enabled, and check that we have the logs as complete as possible. We call the function `set` from the contract, @@ -4353,7 +4555,9 @@ let test_trace_transaction_call = repeat 2 (fun () -> next_evm_level ~evm_node:sequencer ~sc_rollup_node ~client) in - let* () = bake_until_sync ~sequencer ~sc_rollup_node ~proxy ~client () in + let* () = + bake_until_sync ~__LOC__ ~sequencer ~sc_rollup_node ~proxy ~client () + in (* We will use the receipt to check that the results from the trace are consistent with the result from the transaction once applied in the block. *) @@ -4391,7 +4595,9 @@ let test_trace_transaction_call = repeat 2 (fun () -> next_evm_level ~evm_node:sequencer ~sc_rollup_node ~client) in - let* () = bake_until_sync ~sequencer ~sc_rollup_node ~proxy ~client () in + let* () = + bake_until_sync ~__LOC__ ~sequencer ~sc_rollup_node ~proxy ~client () + in let*@ transaction_receipt = Rpc.get_transaction_receipt ~tx_hash:transaction_hash sequencer in @@ -4826,6 +5032,7 @@ let () = test_remove_sequencer protocols ; test_persistent_state protocols ; test_publish_blueprints protocols ; + test_publish_blueprints_on_dal protocols ; test_sequencer_too_ahead protocols ; test_resilient_to_rollup_node_disconnect protocols ; test_can_fetch_smart_rollup_address protocols ; diff --git a/run.sh b/run.sh new file mode 100755 index 0000000000000000000000000000000000000000..f6bc9bd348f745e5bbb542ef5da2138496316519 --- /dev/null +++ b/run.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +rm -rf /tmp/tezt-* + +cpt=2 + +function run { + name=$1 + cpt=$((cpt + 1)) + + time timeout 300 dune exec etherlink/tezt/tests/main.exe -- alpha latest /ci_disabled /flaky dal --only 1 --keep-temp --match "$name" --verbose &> log + + echo "=========================" + if [ "$(grep -c '\[SUCCESS\]' log)" -eq "1" ]; then + echo "$cpt: $name : SUCCESS" + tail -n 4 log + else + echo "$cpt: $name : FAILURE" + grep -i error log + grep "Temporary files can be found in" log + tmp=$(grep "Temporary files can be found in" log | cut -d ":" -f 4) + grep -i panic "$tmp/sc-rollup-node*/kernel.log" + echo + echo "logs:" + head log + echo "..." + tail log + fi + echo "=========================" +} + +run "Remove sequencer via sequencer admin contract" +run "Sequencer state is persistent across runs" +run "Sequencer publishes the blueprints to L1" +run "Sequencer can return the smart rollup address on demand" +run "Sequencer can provide blueprints on demand" +run "Send a transaction to the delayed inbox" +run "Send a deposit to the delayed inbox" +run "RPC method produceBlock" +run "RPC method getBalance uses block parameter" +run "RPC method getBlockByNumber uses block parameter" +run "Supports extended block parameter" +run "Delayed transaction is included" +run "Delayed deposit is included" +run "Largest possible delayed transaction is included" +run "Delayed inbox is populated at init from rollup node" +run "Sequencer is reimbursed for DA fees" +run "Rollup-node kernel upgrade is applied to the sequencer state." +run "EVM Kernel can upgrade to itself" +run "Force kernel upgrade" +run "Force kernel upgrade fail too early" +run "Sending an external transaction to the delayed inbox fails" +run "Delayed transaction timeout" +run "Delayed transaction timeout considers l1 level" +run "Delayed inbox flushing" +run "No automatic block production" +run "Non increasing timestamp are forbidden" +run "Evm node don\'t read the same level twice" +run "Checks the stage one reboots when reading too much chunks in a single L1 level" +run "Checks the sequencer doesn\'t produce blueprint bigger than the given maximum number of chunks and count delayed transactions size in the blueprint" +run "try to reset sequencer and observer state using the command." +run "Sequencer use remote server to get preimages" +run "Sequencer checks the smart rollup address" +run "Evm node can catchup event from the rollup node" +run "Runs two sequencers, one diverge and stop" + +run "Init evm node sequencer data dir from a rollup node data dir" +run "Evm node can catchup event from the rollup node" +run "Rollup-node kernel upgrade is applied to the sequencer state." +run "Runs two sequencers, one diverge and stop" diff --git a/tezt/lib_tezos/sc_rollup_node.ml b/tezt/lib_tezos/sc_rollup_node.ml index ac81240c13231bbd60e91f798211daa87283edda..426266c37b3797228d3091bba6ee93fc35606ac0 100644 --- a/tezt/lib_tezos/sc_rollup_node.ml +++ b/tezt/lib_tezos/sc_rollup_node.ml @@ -504,7 +504,10 @@ let unsafe_wait_sync ?timeout sc_node = in wait_for_level ?timeout sc_node node_level -let wait_sync sc_node ~timeout = unsafe_wait_sync sc_node ~timeout +let wait_sync sc_node ~timeout = + ignore timeout ; + let timeout = Float.max timeout 180. in + unsafe_wait_sync sc_node ~timeout let handle_event sc_node {name; value; timestamp = _} = match name with