@@ -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