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