Skip to content

Commit 05443b3

Browse files
committed
feat(sdk): get_first_nonce_in_queue
1 parent 0203f50 commit 05443b3

File tree

2 files changed

+86
-3
lines changed

2 files changed

+86
-3
lines changed

batcher/aligned-sdk/src/core/errors.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,16 @@ pub enum GetNonceError {
248248
ProtocolMismatch { current: u16, expected: u16 },
249249
}
250250

251+
#[derive(Debug, Serialize, Deserialize, Clone)]
252+
pub enum GetFirstNonceFromQueueError {
253+
ConnectionFailed(String),
254+
SerializationError(String),
255+
UnexpectedResponse(String),
256+
InvalidRequest(String),
257+
ProtocolMismatch { current: u16, expected: u16 },
258+
NoProofsInQueue,
259+
}
260+
251261
#[derive(Debug)]
252262
pub enum ChainIdError {
253263
EthereumProviderError(String),

batcher/aligned-sdk/src/sdk.rs

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ use crate::{
1010
ADDITIONAL_SUBMISSION_GAS_COST_PER_PROOF, CONSTANT_GAS_COST,
1111
MAX_FEE_BATCH_PROOF_NUMBER, MAX_FEE_DEFAULT_PROOF_NUMBER,
1212
},
13-
errors::{self, GetNonceError},
13+
errors::{self, GetFirstNonceFromQueueError, GetNonceError},
1414
types::{
15-
AlignedVerificationData, ClientMessage, GetNonceResponseMessage, Network,
16-
PriceEstimate, ProvingSystemId, VerificationData,
15+
AlignedVerificationData, ClientMessage, GetFirstNonceInQueueResponseMessage,
16+
GetNonceResponseMessage, Network, PriceEstimate, ProvingSystemId, VerificationData,
1717
},
1818
},
1919
eth::{
@@ -653,6 +653,79 @@ pub async fn get_nonce_from_ethereum(
653653
}
654654
}
655655

656+
/// Returns the nonce of the proof with the lowest nonce inside the batcher queue for a given address.
657+
/// This might be useful when you proofs are stuck in the batcher due to a low fee and you need to bump them
658+
/// # Arguments
659+
/// * `batcher_url` - The batcher websocket url.
660+
/// * `address` - The user address for which the nonce will be retrieved.
661+
/// # Returns
662+
/// * The nonce of the oldest proof inside the batcher queue.
663+
/// # Errors
664+
/// * `NoProofsInQueue` if the address did not have proofs in the batcher queue.
665+
pub async fn get_first_nonce_in_queue_from_batcher(
666+
batcher_ws_url: &str,
667+
address: Address,
668+
) -> Result<U256, GetFirstNonceFromQueueError> {
669+
let (ws_stream, _) = connect_async(batcher_ws_url).await.map_err(|_| {
670+
GetFirstNonceFromQueueError::ConnectionFailed("Ws connection to batcher failed".to_string())
671+
})?;
672+
673+
debug!("WebSocket handshake has been successfully completed");
674+
let (mut ws_write, mut ws_read) = ws_stream.split();
675+
check_protocol_version(&mut ws_read)
676+
.map_err(|e| match e {
677+
errors::SubmitError::ProtocolVersionMismatch { current, expected } => {
678+
GetFirstNonceFromQueueError::ProtocolMismatch { current, expected }
679+
}
680+
_ => GetFirstNonceFromQueueError::UnexpectedResponse(
681+
"Unexpected response, expected protocol version".to_string(),
682+
),
683+
})
684+
.await?;
685+
686+
let msg = ClientMessage::GetNonceForAddress(address);
687+
688+
let msg_bin = cbor_serialize(&msg).map_err(|_| {
689+
GetFirstNonceFromQueueError::SerializationError("Failed to serialize msg".to_string())
690+
})?;
691+
ws_write
692+
.send(Message::Binary(msg_bin.clone()))
693+
.await
694+
.map_err(|_| {
695+
GetFirstNonceFromQueueError::ConnectionFailed(
696+
"Ws connection failed to send message to batcher".to_string(),
697+
)
698+
})?;
699+
700+
let mut response_stream: ResponseStream =
701+
ws_read.try_filter(|msg| futures_util::future::ready(msg.is_binary()));
702+
703+
let msg = match response_stream.next().await {
704+
Some(Ok(msg)) => msg,
705+
_ => {
706+
return Err(GetFirstNonceFromQueueError::ConnectionFailed(
707+
"Connection was closed without close message before receiving all messages"
708+
.to_string(),
709+
));
710+
}
711+
};
712+
713+
let _ = ws_write.close().await;
714+
715+
match cbor_deserialize(msg.into_data().as_slice()) {
716+
Ok(GetFirstNonceInQueueResponseMessage::Nonce(nonce)) => Ok(nonce),
717+
Ok(GetFirstNonceInQueueResponseMessage::InvalidRequest(e)) => {
718+
Err(GetFirstNonceFromQueueError::InvalidRequest(e))
719+
}
720+
Ok(GetFirstNonceInQueueResponseMessage::NoProofsInQueue) => {
721+
Err(GetFirstNonceFromQueueError::NoProofsInQueue)
722+
}
723+
Err(_) => Err(GetFirstNonceFromQueueError::SerializationError(
724+
"Failed to deserialize batcher message".to_string(),
725+
)),
726+
}
727+
}
728+
656729
/// Returns the chain ID of the Ethereum network.
657730
/// # Arguments
658731
/// * `eth_rpc_url` - The URL of the Ethereum RPC node.

0 commit comments

Comments
 (0)