Skip to content

Commit 2cfa935

Browse files
committed
Handle everything with the state locked
1 parent 4afe0f0 commit 2cfa935

File tree

1 file changed

+18
-88
lines changed

1 file changed

+18
-88
lines changed

crates/batcher/src/lib.rs

Lines changed: 18 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ impl Batcher {
806806
};
807807

808808
// We acquire the lock on the user state, now everything will be processed sequentially
809-
let _user_state_guard = user_state_ref.lock().await;
809+
let mut user_state_guard = user_state_ref.lock().await;
810810

811811
// If the user state was not present, we need to get the nonce from the Ethereum contract and update the dummy user state
812812
if !is_user_in_state {
@@ -825,10 +825,8 @@ impl Batcher {
825825
return Ok(());
826826
}
827827
};
828-
let user_state = UserState::new(ethereum_user_nonce);
829-
self.user_states
830-
.entry(addr)
831-
.or_insert(Arc::new(Mutex::new(user_state)));
828+
// Update the dummy user state with the correct nonce
829+
user_state_guard.nonce = ethereum_user_nonce;
832830
}
833831

834832
// * ---------------------------------------------------*
@@ -847,46 +845,9 @@ impl Batcher {
847845
};
848846

849847
let msg_max_fee = nonced_verification_data.max_fee;
850-
let user_last_max_fee_limit = {
851-
let user_state = self.user_states.get(&addr);
852-
match user_state {
853-
Some(user_state) => {
854-
let user_state_guard = user_state.lock().await;
855-
Some(user_state_guard.last_max_fee_limit)
856-
}
857-
None => None,
858-
}
859-
};
848+
let user_last_max_fee_limit = user_state_guard.last_max_fee_limit;
860849

861-
let Some(user_last_max_fee_limit) = user_last_max_fee_limit else {
862-
send_message(
863-
ws_conn_sink.clone(),
864-
SubmitProofResponseMessage::AddToBatchError,
865-
)
866-
.await;
867-
self.metrics.user_error(&["batcher_state_error", ""]);
868-
return Ok(());
869-
};
870-
871-
let user_accumulated_fee = {
872-
let user_state = self.user_states.get(&addr);
873-
match user_state {
874-
Some(user_state) => {
875-
let user_state_guard = user_state.lock().await;
876-
Some(user_state_guard.total_fees_in_queue)
877-
}
878-
None => None,
879-
}
880-
};
881-
let Some(user_accumulated_fee) = user_accumulated_fee else {
882-
send_message(
883-
ws_conn_sink.clone(),
884-
SubmitProofResponseMessage::AddToBatchError,
885-
)
886-
.await;
887-
self.metrics.user_error(&["batcher_state_error", ""]);
888-
return Ok(());
889-
};
850+
let user_accumulated_fee = user_state_guard.total_fees_in_queue;
890851

891852
if !self.verify_user_has_enough_balance(user_balance, user_accumulated_fee, msg_max_fee) {
892853
send_message(
@@ -898,27 +859,7 @@ impl Batcher {
898859
return Ok(());
899860
}
900861

901-
let cached_user_nonce = {
902-
let user_state = self.user_states.get(&addr);
903-
match user_state {
904-
Some(user_state) => {
905-
let user_state_guard = user_state.lock().await;
906-
Some(user_state_guard.nonce)
907-
}
908-
None => None,
909-
}
910-
};
911-
912-
let Some(expected_nonce) = cached_user_nonce else {
913-
error!("Failed to get cached user nonce: User not found in user states, but it should have been already inserted");
914-
send_message(
915-
ws_conn_sink.clone(),
916-
SubmitProofResponseMessage::AddToBatchError,
917-
)
918-
.await;
919-
self.metrics.user_error(&["batcher_state_error", ""]);
920-
return Ok(());
921-
};
862+
let expected_nonce = user_state_guard.nonce;
922863

923864
if expected_nonce < msg_nonce {
924865
warn!("Invalid nonce for address {addr}, expected nonce: {expected_nonce:?}, received nonce: {msg_nonce:?}");
@@ -1032,7 +973,7 @@ impl Batcher {
1032973
if let Err(e) = self
1033974
.add_to_batch(
1034975
batch_state_lock,
1035-
nonced_verification_data,
976+
&nonced_verification_data,
1036977
ws_conn_sink.clone(),
1037978
signature,
1038979
addr,
@@ -1045,6 +986,14 @@ impl Batcher {
1045986
return Ok(());
1046987
};
1047988

989+
// Update user state now that entry has been successfully added to batch
990+
let max_fee = nonced_verification_data.max_fee;
991+
let nonce = nonced_verification_data.nonce;
992+
user_state_guard.nonce = nonce + U256::one();
993+
user_state_guard.last_max_fee_limit = max_fee;
994+
user_state_guard.proofs_in_batch += 1;
995+
user_state_guard.total_fees_in_queue += max_fee;
996+
1048997
info!("Verification data message handled");
1049998
Ok(())
1050999
}
@@ -1247,7 +1196,7 @@ impl Batcher {
12471196
async fn add_to_batch(
12481197
&self,
12491198
mut batch_state_lock: MutexGuard<'_, BatchState>,
1250-
verification_data: NoncedVerificationData,
1199+
verification_data: &NoncedVerificationData,
12511200
ws_conn_sink: WsMessageSink,
12521201
proof_submitter_sig: Signature,
12531202
proof_submitter_addr: Address,
@@ -1260,7 +1209,7 @@ impl Batcher {
12601209
let nonce = verification_data.nonce;
12611210
batch_state_lock.batch_queue.push(
12621211
BatchQueueEntry::new(
1263-
verification_data,
1212+
verification_data.clone(),
12641213
verification_data_comm,
12651214
ws_conn_sink,
12661215
proof_submitter_sig,
@@ -1277,26 +1226,7 @@ impl Batcher {
12771226

12781227
info!("Current batch queue length: {}", queue_len);
12791228

1280-
// User state is updated
1281-
{
1282-
let user_state = self.user_states.get(&proof_submitter_addr);
1283-
match user_state {
1284-
Some(user_state) => {
1285-
let mut user_state_guard = user_state.lock().await;
1286-
user_state_guard.nonce = nonce + U256::one();
1287-
user_state_guard.last_max_fee_limit = max_fee;
1288-
user_state_guard.proofs_in_batch += 1;
1289-
user_state_guard.total_fees_in_queue += max_fee;
1290-
}
1291-
None => {
1292-
error!("User state of address {proof_submitter_addr} was not found when trying to update user state. This user state should have been present");
1293-
std::mem::drop(batch_state_lock);
1294-
return Err(BatcherError::AddressNotFoundInUserStates(
1295-
proof_submitter_addr,
1296-
));
1297-
}
1298-
}
1299-
}
1229+
// User state will be updated by the caller who already has the lock
13001230

13011231
Ok(())
13021232
}

0 commit comments

Comments
 (0)