tempo_alloy/fillers/
nonce.rs1use crate::rpc::TempoTransactionRequest;
2use alloy_network::{Network, TransactionBuilder};
3use alloy_primitives::U256;
4use alloy_provider::{
5 SendableTx,
6 fillers::{FillerControlFlow, TxFiller},
7};
8use alloy_transport::TransportResult;
9use tempo_primitives::subblock::has_sub_block_nonce_key_prefix;
10
11#[derive(Clone, Copy, Debug, Default)]
15pub struct Random2DNonceFiller;
16
17impl Random2DNonceFiller {
18 fn is_filled(tx: &TempoTransactionRequest) -> bool {
20 tx.nonce().is_some() || tx.nonce_key.is_some()
21 }
22}
23
24impl<N: Network<TransactionRequest = TempoTransactionRequest>> TxFiller<N> for Random2DNonceFiller {
25 type Fillable = ();
26
27 fn status(&self, tx: &N::TransactionRequest) -> FillerControlFlow {
28 if Self::is_filled(tx) {
29 return FillerControlFlow::Finished;
30 }
31 FillerControlFlow::Ready
32 }
33
34 fn fill_sync(&self, tx: &mut SendableTx<N>) {
35 if let Some(builder) = tx.as_mut_builder()
36 && !Self::is_filled(builder)
37 {
38 let nonce_key = loop {
39 let key = U256::random();
40 if !has_sub_block_nonce_key_prefix(&key) {
42 break key;
43 }
44 };
45 builder.set_nonce_key(nonce_key);
46 builder.set_nonce(0);
47 }
48 }
49
50 async fn prepare<P>(
51 &self,
52 _provider: &P,
53 _tx: &N::TransactionRequest,
54 ) -> TransportResult<Self::Fillable>
55 where
56 P: alloy_provider::Provider<N>,
57 {
58 Ok(())
59 }
60
61 async fn fill(
62 &self,
63 _fillable: Self::Fillable,
64 tx: SendableTx<N>,
65 ) -> TransportResult<SendableTx<N>> {
66 Ok(tx)
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use crate::{TempoNetwork, fillers::Random2DNonceFiller, rpc::TempoTransactionRequest};
73 use alloy_network::TransactionBuilder;
74 use alloy_primitives::ruint::aliases::U256;
75 use alloy_provider::{ProviderBuilder, mock::Asserter};
76 use eyre;
77
78 #[tokio::test]
79 async fn test_random_2d_nonce_filler() -> eyre::Result<()> {
80 let provider = ProviderBuilder::<_, _, TempoNetwork>::default()
81 .filler(Random2DNonceFiller)
82 .connect_mocked_client(Asserter::default());
83
84 let filled_request = provider
86 .fill(TempoTransactionRequest::default())
87 .await?
88 .try_into_request()?;
89 assert!(filled_request.nonce_key.is_some());
90 assert_eq!(filled_request.nonce(), Some(0));
91
92 let filled_request = provider
94 .fill(TempoTransactionRequest::default().with_nonce(1))
95 .await?
96 .try_into_request()?;
97 assert!(filled_request.nonce_key.is_none());
98 assert_eq!(filled_request.nonce(), Some(1));
99
100 let filled_request = provider
102 .fill(TempoTransactionRequest::default().with_nonce_key(U256::ONE))
103 .await?
104 .try_into_request()?;
105 assert_eq!(filled_request.nonce_key, Some(U256::ONE));
106 assert!(filled_request.nonce().is_none());
107
108 Ok(())
109 }
110}