Skip to content

Commit b63a928

Browse files
authored
Checks functions refactor (#1860)
1 parent b36b0a6 commit b63a928

File tree

1 file changed

+152
-53
lines changed
  • batcher/aligned-batcher/src

1 file changed

+152
-53
lines changed

batcher/aligned-batcher/src/lib.rs

Lines changed: 152 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -563,60 +563,33 @@ impl Batcher {
563563
// * Perform validations over the message *
564564
// * ---------------------------------------------------*
565565

566-
// This check does not save against "Holesky" and "HoleskyStage", since both are chain_id 17000
567-
let msg_chain_id = client_msg.verification_data.chain_id;
568-
if msg_chain_id != self.chain_id {
569-
warn!("Received message with incorrect chain id: {msg_chain_id}");
570-
send_message(
571-
ws_conn_sink.clone(),
572-
SubmitProofResponseMessage::InvalidChainId,
573-
)
574-
.await;
575-
self.metrics.user_error(&["invalid_chain_id", ""]);
566+
// All check functions sends the error to the metrics server and logs it
567+
// if they return false
568+
569+
if !self.msg_chain_id_is_valid(&client_msg, &ws_conn_sink).await {
576570
return Ok(());
577571
}
578572

579-
// This checks saves against "Holesky" and "HoleskyStage", since each one has a different payment service address
580-
let msg_payment_service_addr = client_msg.verification_data.payment_service_addr;
581-
if msg_payment_service_addr != self.payment_service.address() {
582-
warn!("Received message with incorrect payment service address: {msg_payment_service_addr}");
583-
send_message(
584-
ws_conn_sink.clone(),
585-
SubmitProofResponseMessage::InvalidPaymentServiceAddress(
586-
msg_payment_service_addr,
587-
self.payment_service.address(),
588-
),
589-
)
590-
.await;
591-
self.metrics
592-
.user_error(&["invalid_payment_service_address", ""]);
573+
if !self
574+
.msg_batcher_payment_addr_is_valid(&client_msg, &ws_conn_sink)
575+
.await
576+
{
593577
return Ok(());
594578
}
595579

596-
info!("Verifying message signature...");
597-
let Ok(addr) = client_msg.verify_signature() else {
598-
error!("Signature verification error");
599-
send_message(
600-
ws_conn_sink.clone(),
601-
SubmitProofResponseMessage::InvalidSignature,
602-
)
603-
.await;
604-
self.metrics.user_error(&["invalid_signature", ""]);
580+
if !self
581+
.msg_proof_size_is_valid(&client_msg, &ws_conn_sink)
582+
.await
583+
{
605584
return Ok(());
606-
};
607-
info!("Message signature verified");
585+
}
608586

609-
let proof_size = client_msg.verification_data.verification_data.proof.len();
610-
if proof_size > self.max_proof_size {
611-
error!("Proof size exceeds the maximum allowed size.");
612-
send_message(
613-
ws_conn_sink.clone(),
614-
SubmitProofResponseMessage::ProofTooLarge,
615-
)
616-
.await;
617-
self.metrics.user_error(&["proof_too_large", ""]);
587+
let Some(addr) = self
588+
.msg_signature_is_valid(&client_msg, &ws_conn_sink)
589+
.await
590+
else {
618591
return Ok(());
619-
}
592+
};
620593

621594
let nonced_verification_data = client_msg.verification_data.clone();
622595

@@ -661,6 +634,7 @@ impl Batcher {
661634
}
662635

663636
if self.is_nonpaying(&addr) {
637+
// TODO: Non paying msg and paying should share some logic
664638
return self
665639
.handle_nonpaying_msg(ws_conn_sink.clone(), &client_msg)
666640
.await;
@@ -671,17 +645,11 @@ impl Batcher {
671645
// We don't need a batch state lock here, since if the user locks its funds
672646
// after the check, some blocks should pass until he can withdraw.
673647
// It is safe to do just do this here.
674-
if self.user_balance_is_unlocked(&addr).await {
675-
send_message(
676-
ws_conn_sink.clone(),
677-
SubmitProofResponseMessage::InsufficientBalance(addr),
678-
)
679-
.await;
680-
self.metrics.user_error(&["insufficient_balance", ""]);
648+
if !self.msg_user_balance_is_locked(&addr, &ws_conn_sink).await {
681649
return Ok(());
682650
}
683651

684-
// We aquire the lock first only to query if the user is already present and the lock is dropped.
652+
// We acquire the lock first only to query if the user is already present and the lock is dropped.
685653
// If it was not present, then the user nonce is queried to the Aligned contract.
686654
// Lastly, we get a lock of the batch state again and insert the user state if it was still missing.
687655

@@ -1894,4 +1862,135 @@ impl Batcher {
18941862
(self.aggregator_fee_percentage_multiplier * self.aggregator_gas_cost) / PERCENTAGE_DIVIDER
18951863
+ BATCHER_SUBMISSION_BASE_GAS_COST
18961864
}
1865+
1866+
/// Checks if the message signature is valid
1867+
/// and returns the address if its.
1868+
/// If not, returns false, logs the error,
1869+
/// and sends it to the metrics server
1870+
async fn msg_signature_is_valid(
1871+
&self,
1872+
client_msg: &SubmitProofMessage,
1873+
ws_conn_sink: &WsMessageSink,
1874+
) -> Option<Address> {
1875+
let Ok(addr) = client_msg.verify_signature() else {
1876+
error!("Signature verification error");
1877+
send_message(
1878+
ws_conn_sink.clone(),
1879+
SubmitProofResponseMessage::InvalidSignature,
1880+
)
1881+
.await;
1882+
self.metrics.user_error(&["invalid_signature", ""]);
1883+
return None;
1884+
};
1885+
1886+
Some(addr)
1887+
}
1888+
1889+
/// Checks if the proof size + pub inputs is valid (not exceeding max_proof_size)
1890+
/// Returns false, logs the error,
1891+
/// and sends it to the metrics server if the size is too large
1892+
async fn msg_proof_size_is_valid(
1893+
&self,
1894+
client_msg: &SubmitProofMessage,
1895+
ws_conn_sink: &WsMessageSink,
1896+
) -> bool {
1897+
let verification_data = match cbor_serialize(&client_msg.verification_data) {
1898+
Ok(data) => data,
1899+
// This should never happened, the user sent all his data serialized
1900+
Err(_) => {
1901+
error!("Proof serialization error");
1902+
send_message(
1903+
ws_conn_sink.clone(),
1904+
SubmitProofResponseMessage::Error("Proof serialization error".to_string()),
1905+
)
1906+
.await;
1907+
self.metrics.user_error(&["proof_serialization_error", ""]);
1908+
return false;
1909+
}
1910+
};
1911+
1912+
if verification_data.len() > self.max_proof_size {
1913+
error!("Proof size exceeds the maximum allowed size.");
1914+
send_message(
1915+
ws_conn_sink.clone(),
1916+
SubmitProofResponseMessage::ProofTooLarge,
1917+
)
1918+
.await;
1919+
self.metrics.user_error(&["proof_too_large", ""]);
1920+
return false;
1921+
}
1922+
1923+
true
1924+
}
1925+
1926+
/// Checks if the chain id matches the one in the config
1927+
/// Returns false, logs the error,
1928+
/// and sends it to the metrics server if it doesn't matches
1929+
async fn msg_chain_id_is_valid(
1930+
&self,
1931+
client_msg: &SubmitProofMessage,
1932+
ws_conn_sink: &WsMessageSink,
1933+
) -> bool {
1934+
let msg_chain_id = client_msg.verification_data.chain_id;
1935+
if msg_chain_id != self.chain_id {
1936+
warn!("Received message with incorrect chain id: {msg_chain_id}");
1937+
send_message(
1938+
ws_conn_sink.clone(),
1939+
SubmitProofResponseMessage::InvalidChainId,
1940+
)
1941+
.await;
1942+
self.metrics.user_error(&["invalid_chain_id", ""]);
1943+
return false;
1944+
}
1945+
1946+
true
1947+
}
1948+
1949+
/// Checks if the message has a valid payment service address
1950+
/// Returns false, logs the error,
1951+
/// and sends it to the metrics server if it doesn't match
1952+
async fn msg_batcher_payment_addr_is_valid(
1953+
&self,
1954+
client_msg: &SubmitProofMessage,
1955+
ws_conn_sink: &WsMessageSink,
1956+
) -> bool {
1957+
let msg_payment_service_addr = client_msg.verification_data.payment_service_addr;
1958+
if msg_payment_service_addr != self.payment_service.address() {
1959+
warn!("Received message with incorrect payment service address: {msg_payment_service_addr}");
1960+
send_message(
1961+
ws_conn_sink.clone(),
1962+
SubmitProofResponseMessage::InvalidPaymentServiceAddress(
1963+
msg_payment_service_addr,
1964+
self.payment_service.address(),
1965+
),
1966+
)
1967+
.await;
1968+
self.metrics
1969+
.user_error(&["invalid_payment_service_address", ""]);
1970+
return false;
1971+
}
1972+
1973+
true
1974+
}
1975+
1976+
/// Checks if the user's balance is unlocked
1977+
/// Returns false if balance is unlocked, logs the error,
1978+
/// and sends it to the metrics server
1979+
async fn msg_user_balance_is_locked(
1980+
&self,
1981+
addr: &Address,
1982+
ws_conn_sink: &WsMessageSink,
1983+
) -> bool {
1984+
if self.user_balance_is_unlocked(addr).await {
1985+
send_message(
1986+
ws_conn_sink.clone(),
1987+
SubmitProofResponseMessage::InsufficientBalance(*addr),
1988+
)
1989+
.await;
1990+
self.metrics.user_error(&["insufficient_balance", ""]);
1991+
return false;
1992+
}
1993+
1994+
true
1995+
}
18971996
}

0 commit comments

Comments
 (0)