From a0eb396289624ce4a048bc83549387b7aac7a2b4 Mon Sep 17 00:00:00 2001 From: Gus Gutoski Date: Wed, 26 Jun 2024 10:25:54 -0400 Subject: [PATCH] empty namespace table implies empty block payload, with tests --- sequencer/src/block/full_payload/ns_table.rs | 12 ++++++---- .../src/block/full_payload/ns_table/test.rs | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/sequencer/src/block/full_payload/ns_table.rs b/sequencer/src/block/full_payload/ns_table.rs index 779d12c09..50ce3489e 100644 --- a/sequencer/src/block/full_payload/ns_table.rs +++ b/sequencer/src/block/full_payload/ns_table.rs @@ -221,10 +221,11 @@ impl NsTable { /// 1. Byte length must hold a whole number of entries. /// 2. All namespace IDs and offsets must increase monotonically. Offsets /// must be nonzero. - /// 3. Header consistent with byte length (obsolete after - /// ) - /// 4. Final offset must equal `payload_byte_len` (obsolete after - /// ) + /// 3. Header consistent with byte length. (Obsolete after + /// .) + /// 4. Final offset must equal `payload_byte_len`. (Obsolete after + /// .) + /// If the namespace table is empty then `payload_byte_len` must be 0. pub fn validate( &self, payload_byte_len: &PayloadByteLen, @@ -242,6 +243,8 @@ impl NsTable { if final_offset != payload_byte_len.as_usize() { return Err(InvalidFinalOffset); } + } else if payload_byte_len.as_usize() != 0 { + return Err(ExpectNonemptyNsTable); } Ok(()) @@ -372,6 +375,7 @@ pub enum NsTableValidationError { NonIncreasingEntries, InvalidHeader, // TODO this variant obsolete after https://github.com/EspressoSystems/espresso-sequencer/issues/1604 InvalidFinalOffset, // TODO this variant obsolete after https://github.com/EspressoSystems/espresso-sequencer/issues/1604 + ExpectNonemptyNsTable, } pub struct NsTableBuilder { diff --git a/sequencer/src/block/full_payload/ns_table/test.rs b/sequencer/src/block/full_payload/ns_table/test.rs index 47a22b53c..df92d25e1 100644 --- a/sequencer/src/block/full_payload/ns_table/test.rs +++ b/sequencer/src/block/full_payload/ns_table/test.rs @@ -101,6 +101,28 @@ async fn payload_byte_len() { // final offset less than payload byte len modify_final_offset(-1); + + // zero-length payload + let empty_block = Payload::from_transactions([], &Default::default(), &Default::default()) + .await + .unwrap() + .0; + assert_eq!(empty_block.ns_table().len().0, 0); + assert_eq!( + empty_block.ns_table().bytes, + usize_to_bytes::(0) + ); + empty_block + .ns_table() + .validate(&empty_block.byte_len()) + .unwrap(); + + // empty namespace table with nonempty payload + *block.ns_table_mut() = empty_block.ns_table().clone(); + assert_eq!( + block.ns_table().validate(&payload_byte_len).unwrap_err(), + ExpectNonemptyNsTable + ); } #[test]