Skip to content

Commit 45611f2

Browse files
authored
reject transactions with size greater than max block size (#1852)
Closes #1777 This PR Rejects any transaction whose payload length is more than the max block size. The max block size parameter is found in the chain config, which can be updated through an upgrade. Therefore, we use the chain config from the validated state first, as the validated state is the mutable state of the node and the chain config, if present, will be the latest chain config. If the chain config is not present in the validated state, which may occur if the node has not seen an upgrade, we use the chain config from the node state. The node will automatically catch up and have an updated chain config in the validated state when building the header for the next block.
2 parents c35113d + c78bddd commit 45611f2

File tree

3 files changed

+36
-14
lines changed

3 files changed

+36
-14
lines changed

node-metrics/src/service/client_state/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1308,7 +1308,7 @@ pub mod tests {
13081308
let (internal_client_message_sender, internal_client_message_receiver) = mpsc::channel(1);
13091309
let (server_message_sender_1, mut server_message_receiver_1) = mpsc::channel(1);
13101310
let (server_message_sender_2, mut server_message_receiver_2) = mpsc::channel(1);
1311-
let _process_internal_client_message_handle = InternalClientMessageProcessingTask::new(
1311+
let process_internal_client_message_handle = InternalClientMessageProcessingTask::new(
13121312
internal_client_message_receiver,
13131313
data_state,
13141314
client_thread_state,
@@ -1359,6 +1359,8 @@ pub mod tests {
13591359
voters_1, voters_2
13601360
]))),
13611361
);
1362+
1363+
drop(process_internal_client_message_handle)
13621364
}
13631365

13641366
#[async_std::test]

sequencer/src/api.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,36 @@ impl<N: ConnectedNetwork<PubKey>, Ver: StaticVersionType + 'static, P: Sequencer
168168
SubmitDataSource<N, P> for ApiState<N, P, Ver>
169169
{
170170
async fn submit(&self, tx: Transaction) -> anyhow::Result<()> {
171-
self.consensus()
172-
.await
173-
.read()
171+
let handle = self.consensus().await;
172+
173+
let consensus_read_lock = handle.read().await;
174+
175+
// Fetch full chain config from the validated state, if present.
176+
// This is necessary because we support chain config upgrades,
177+
// so the updated chain config is found in the validated state.
178+
let cf = consensus_read_lock
179+
.decided_state()
174180
.await
175-
.submit_transaction(tx)
176-
.await?;
181+
.chain_config
182+
.resolve();
183+
184+
// Use the chain config from the validated state if available,
185+
// otherwise, use the node state's chain config
186+
// The node state's chain config is the node's base version chain config
187+
let cf = match cf {
188+
Some(cf) => cf,
189+
None => self.node_state().await.chain_config,
190+
};
191+
192+
let max_block_size: u64 = cf.max_block_size.into();
193+
let txn_size = tx.payload().len() as u64;
194+
195+
// reject transaction bigger than block size
196+
if txn_size > max_block_size {
197+
bail!("transaction size ({txn_size}) is greater than max_block_size ({max_block_size})")
198+
}
199+
200+
consensus_read_lock.submit_transaction(tx).await?;
177201
Ok(())
178202
}
179203
}

sequencer/src/bin/espresso-dev-node.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -672,20 +672,16 @@ mod tests {
672672
.await;
673673
}
674674

675-
// Now the `submit/submit` endpoint allows the extremely large transactions to be in the mempool.
676-
// And we need to check whether this extremely large transaction blocks the building process.
677-
// Currently the default value of `max_block_size` is 30720, and this transaction exceeds the limit.
678-
// TODO: https://github.com/EspressoSystems/espresso-sequencer/issues/1777
679675
{
676+
// transactions with size larger than max_block_size result in an error
680677
let extremely_large_tx = Transaction::new(100_u32.into(), vec![0; 50120]);
681-
let extremely_large_hash: Commitment<Transaction> = api_client
682-
.post("submit/submit")
678+
api_client
679+
.post::<Commitment<Transaction>>("submit/submit")
683680
.body_json(&extremely_large_tx)
684681
.unwrap()
685682
.send()
686683
.await
687-
.unwrap();
688-
assert_eq!(extremely_large_tx.commit(), extremely_large_hash);
684+
.unwrap_err();
689685

690686
// Now we send a small transaction to make sure this transaction can be included in a hotshot block.
691687
let tx = Transaction::new(100_u32.into(), vec![0; 3]);

0 commit comments

Comments
 (0)