Skip to content

Commit b804457

Browse files
committed
feat: retrieve last max fee in sdk
1 parent 6bb2431 commit b804457

File tree

2 files changed

+98
-3
lines changed

2 files changed

+98
-3
lines changed

crates/sdk/src/common/errors.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,16 @@ pub enum GetNonceError {
259259
GenericError(String),
260260
}
261261

262+
#[derive(Debug, Serialize, Deserialize, Clone)]
263+
pub enum GetLastMaxFeeError {
264+
ConnectionFailed(String),
265+
SerializationError(String),
266+
UnexpectedResponse(String),
267+
InvalidRequest(String),
268+
ProtocolMismatch { current: u16, expected: u16 },
269+
GenericError(String),
270+
}
271+
262272
#[derive(Debug)]
263273
pub enum ChainIdError {
264274
EthereumProviderError(String),

crates/sdk/src/verification_layer/mod.rs

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ use crate::{
55
DEFAULT_MAX_FEE_BATCH_SIZE, GAS_PRICE_PERCENTAGE_MULTIPLIER,
66
INSTANT_MAX_FEE_BATCH_SIZE, PERCENTAGE_DIVIDER,
77
},
8-
errors::{self, GetNonceError},
8+
errors::{self, GetLastMaxFeeError, GetNonceError},
99
types::{
10-
AlignedVerificationData, ClientMessage, FeeEstimationType, GetNonceResponseMessage,
11-
Network, ProvingSystemId, VerificationData,
10+
AlignedVerificationData, ClientMessage, FeeEstimationType,
11+
GetLastMaxFeeResponseMessage, GetNonceResponseMessage, Network, ProvingSystemId,
12+
VerificationData,
1213
},
1314
},
1415
communication::{
@@ -646,6 +647,90 @@ pub async fn get_nonce_from_ethereum(
646647
}
647648
}
648649

650+
/// Retrieves the `max_fee` of the proof with the highest nonce in the batcher queue for a given address.
651+
///
652+
/// This value represents the maximum fee limit that can be used when submitting the next proof.
653+
/// To increase the fee limit for a new proof, you must first bump the fee of the previous proof,
654+
/// and continue doing so recursively until you reach the proof with the highest nonce (this one).
655+
///
656+
/// Read more here: https://docs.alignedlayer.com/architecture/1_proof_verification_layer/1_batcher#max-fee-priority-queue
657+
///
658+
/// # Arguments
659+
/// * `network` - The network from which to retrieve the last `max_fee`.
660+
/// * `address` - The user address whose last `max_fee` will be retrieved.
661+
///
662+
/// # Returns
663+
/// * `Ok(U256)` - The `max_fee` of the proof with the highest nonce for the given user.
664+
/// * `Ok(U256::MAX)` - If the user has no proofs in the queue.
665+
///
666+
/// # Notes
667+
/// * Returns `U256::MAX` (2^256 - 1) when no proofs are present in the queue.
668+
pub async fn get_last_max_fee(
669+
network: Network,
670+
address: Address,
671+
) -> Result<U256, GetLastMaxFeeError> {
672+
let (ws_stream, _) = connect_async(network.get_batcher_url())
673+
.await
674+
.map_err(|_| {
675+
GetLastMaxFeeError::ConnectionFailed("Ws connection to batcher failed".to_string())
676+
})?;
677+
678+
debug!("WebSocket handshake has been successfully completed");
679+
let (mut ws_write, mut ws_read) = ws_stream.split();
680+
check_protocol_version(&mut ws_read)
681+
.map_err(|e| match e {
682+
errors::SubmitError::ProtocolVersionMismatch { current, expected } => {
683+
GetLastMaxFeeError::ProtocolMismatch { current, expected }
684+
}
685+
_ => GetLastMaxFeeError::UnexpectedResponse(
686+
"Unexpected response, expected protocol version".to_string(),
687+
),
688+
})
689+
.await?;
690+
691+
let msg = ClientMessage::GetLastMaxFee(address);
692+
693+
let msg_bin = cbor_serialize(&msg).map_err(|_| {
694+
GetLastMaxFeeError::SerializationError("Failed to serialize msg".to_string())
695+
})?;
696+
ws_write
697+
.send(Message::Binary(msg_bin.clone()))
698+
.await
699+
.map_err(|_| {
700+
GetLastMaxFeeError::ConnectionFailed(
701+
"Ws connection failed to send message to batcher".to_string(),
702+
)
703+
})?;
704+
705+
let mut response_stream: ResponseStream =
706+
ws_read.try_filter(|msg| futures_util::future::ready(msg.is_binary()));
707+
708+
let msg = match response_stream.next().await {
709+
Some(Ok(msg)) => msg,
710+
_ => {
711+
return Err(GetLastMaxFeeError::ConnectionFailed(
712+
"Connection was closed without close message before receiving all messages"
713+
.to_string(),
714+
));
715+
}
716+
};
717+
718+
let _ = ws_write.close().await;
719+
720+
match cbor_deserialize(msg.into_data().as_slice()) {
721+
Ok(GetLastMaxFeeResponseMessage::LastMaxFee(last_max_fee)) => Ok(last_max_fee),
722+
Ok(GetLastMaxFeeResponseMessage::InvalidRequest(e)) => {
723+
Err(GetLastMaxFeeError::InvalidRequest(e))
724+
}
725+
Ok(GetLastMaxFeeResponseMessage::ServerBusy) => Err(GetLastMaxFeeError::GenericError(
726+
"Server is busy processing requests, please retry".to_string(),
727+
)),
728+
Err(_) => Err(GetLastMaxFeeError::SerializationError(
729+
"Failed to deserialize batcher message".to_string(),
730+
)),
731+
}
732+
}
733+
649734
/// Returns the chain ID of the Ethereum network.
650735
///
651736
/// # Arguments

0 commit comments

Comments
 (0)