diff --git a/src/kernel_sequencer/src/delayed_inbox.rs b/src/kernel_sequencer/src/delayed_inbox.rs index 29fc85b689db3259bf117631e3a2790f666905c5..2b7ce470dad2f1ac09984c06cf06b2550eaacf50 100644 --- a/src/kernel_sequencer/src/delayed_inbox.rs +++ b/src/kernel_sequencer/src/delayed_inbox.rs @@ -110,7 +110,10 @@ pub fn read_input( }, } } - None => return handle_pending_inbox(host, pending_inbox_queue), + None => { + let state = read_state(host)?; + return handle_pending_inbox(host, pending_inbox_queue, delayed_inbox_queue, state); + } } } } @@ -256,12 +259,33 @@ fn handle_message( fn handle_pending_inbox( host: &mut H, pending_inbox_queue: &mut Queue, + delayed_inbox_queue: &mut Queue, + state: State, ) -> Result, RuntimeError> { - let pending_message = pending_inbox_queue.pop(host)?; - let Some(PendingUserMessage {id, level, payload}) = pending_message else {return Ok(None)}; + match state { + State::Sequenced(_) => { + let pending_message = pending_inbox_queue.pop(host)?; + let Some(PendingUserMessage {id, level, payload}) = pending_message else {return Ok(None)}; - let msg = Message::new(level, id, payload); - Ok(Some(msg)) + let msg = Message::new(level, id, payload); + Ok(Some(msg)) + } + State::Fallback => { + // First we should remove remaining message from the pending inbox + match pending_inbox_queue.pop(host)? { + Some(PendingUserMessage { id, level, payload }) => { + let msg = Message::new(level, id, payload); + Ok(Some(msg)) + } + None => { + let delayed_message = delayed_inbox_queue.pop(host)?; + let Some(UserMessage { payload, .. }) = delayed_message else {return Ok(None)}; + let msg = Message::new(0, 0, payload); + Ok(Some(msg)) + } + } + } + } } #[cfg(test)] @@ -411,4 +435,21 @@ mod tests { assert_external_eq(Msg::new(0x01), msg1.as_ref()); assert!(msg2.is_none()); } + + #[test] + fn test_fallback() { + let (mut mock_host, _) = prepare(); + write_state(&mut mock_host, State::Fallback).unwrap(); + + mock_host.add_external(Msg::new(0x01)); + mock_host.add_external(Msg::new(0x02)); + mock_host.add_external(Msg::new(0x03)); + + let mut runtime = SequencerRuntime::new(mock_host, crate::FilterBehavior::AllowAll, 1); + let msg1 = runtime.read_input().unwrap().unwrap(); + let msg2 = runtime.read_input().unwrap().unwrap(); + + assert_external_eq(Msg::new(0x01), msg1.as_ref()); + assert_external_eq(Msg::new(0x02), msg2.as_ref()); + } } diff --git a/src/kernel_sequencer/src/sequencer_runtime.rs b/src/kernel_sequencer/src/sequencer_runtime.rs index d521f698838d9fd403b359d35e77014d854f1e83..91216d0d86d6bcbb3175e5901c071fe313b5ae3e 100644 --- a/src/kernel_sequencer/src/sequencer_runtime.rs +++ b/src/kernel_sequencer/src/sequencer_runtime.rs @@ -213,7 +213,9 @@ where mod tests { use super::SequencerRuntime; + use crate::storage::write_state; use tezos_data_encoding_derive::BinWriter; + use tezos_smart_rollup_encoding::public_key::PublicKey; use tezos_smart_rollup_host::{path::RefPath, runtime::Runtime}; use tezos_smart_rollup_mock::MockHost; @@ -231,6 +233,10 @@ mod tests { #[test] fn test_add_user_message() { let mut mock_host = MockHost::default(); + let public_key = + PublicKey::from_b58check("edpkuDMUm7Y53wp4gxeLBXuiAhXZrLn8XB1R83ksvvesH8Lp8bmCfK") + .unwrap(); + write_state(&mut mock_host, crate::state::State::Sequenced(public_key)).unwrap(); mock_host.add_external(UserMessage::new(1)); mock_host.add_external(UserMessage::new(2)); mock_host.add_external(UserMessage::new(3));