@@ -110,7 +110,7 @@ use std::{
110110 collections:: HashMap ,
111111 path:: { Path , PathBuf } ,
112112 sync:: {
113- atomic:: { AtomicU64 , AtomicUsize , Ordering } ,
113+ atomic:: { AtomicUsize , Ordering } ,
114114 Arc ,
115115 } ,
116116} ;
@@ -126,7 +126,7 @@ use near_api_types::{
126126use borsh:: { BorshDeserialize , BorshSerialize } ;
127127use serde:: { Deserialize , Serialize } ;
128128use slipped10:: BIP32Path ;
129- use tracing:: { debug, info , instrument, trace , warn} ;
129+ use tracing:: { debug, instrument, warn} ;
130130
131131use crate :: {
132132 config:: NetworkConfig ,
@@ -394,7 +394,7 @@ pub trait SignerTrait {
394394/// It provides an access key pooling and a nonce caching mechanism to improve transaction throughput.
395395pub struct Signer {
396396 pool : tokio:: sync:: RwLock < HashMap < PublicKey , Box < dyn SignerTrait + Send + Sync + ' static > > > ,
397- nonce_cache : tokio :: sync :: RwLock < HashMap < ( AccountId , PublicKey ) , AtomicU64 > > ,
397+ nonce_cache : futures :: lock :: Mutex < HashMap < ( AccountId , PublicKey ) , u64 > > ,
398398 current_public_key : AtomicUsize ,
399399}
400400
@@ -410,7 +410,7 @@ impl Signer {
410410 public_key,
411411 Box :: new ( signer) as Box < dyn SignerTrait + Send + Sync + ' static > ,
412412 ) ] ) ) ,
413- nonce_cache : tokio :: sync :: RwLock :: new ( HashMap :: new ( ) ) ,
413+ nonce_cache : futures :: lock :: Mutex :: new ( HashMap :: new ( ) ) ,
414414 current_public_key : AtomicUsize :: new ( 0 ) ,
415415 } ) )
416416 }
@@ -545,36 +545,20 @@ impl Signer {
545545 network : & NetworkConfig ,
546546 ) -> Result < ( Nonce , CryptoHash , BlockHeight ) , SignerError > {
547547 debug ! ( target: SIGNER_TARGET , "Fetching transaction nonce" ) ;
548+
548549 let nonce_data = crate :: account:: Account ( account_id. clone ( ) )
549550 . access_key ( public_key)
550551 . fetch_from ( network)
551552 . await
552553 . map_err ( |e| SignerError :: FetchNonceError ( Box :: new ( e) ) ) ?;
553- let nonce_cache = self . nonce_cache . read ( ) . await ;
554-
555- if let Some ( nonce) = nonce_cache. get ( & ( account_id. clone ( ) , public_key) ) {
556- let nonce = nonce. fetch_add ( 1 , Ordering :: SeqCst ) ;
557- drop ( nonce_cache) ;
558- trace ! ( target: SIGNER_TARGET , "Nonce fetched from cache" ) ;
559- return Ok ( ( nonce + 1 , nonce_data. block_hash , nonce_data. block_height ) ) ;
560- } else {
561- drop ( nonce_cache) ;
562- }
563-
564- // It's initialization, so it's better to take write lock, so other will wait
565554
566- // case where multiple writers end up at the same lock acquisition point and tries
567- // to overwrite the cached value that a previous writer already wrote.
568- let nonce = self
569- . nonce_cache
570- . write ( )
571- . await
572- . entry ( ( account_id. clone ( ) , public_key) )
573- . or_insert_with ( || AtomicU64 :: new ( nonce_data. data . nonce . 0 + 1 ) )
574- . fetch_max ( nonce_data. data . nonce . 0 + 1 , Ordering :: SeqCst )
575- . max ( nonce_data. data . nonce . 0 + 1 ) ;
555+ let nonce = {
556+ let mut nonce_cache = self . nonce_cache . lock ( ) . await ;
557+ let nonce = nonce_cache. entry ( ( account_id, public_key) ) . or_default ( ) ;
558+ * nonce = ( * nonce) . max ( nonce_data. data . nonce . 0 ) + 1 ;
559+ * nonce
560+ } ;
576561
577- info ! ( target: SIGNER_TARGET , "Nonce fetched and cached" ) ;
578562 Ok ( ( nonce, nonce_data. block_hash , nonce_data. block_height ) )
579563 }
580564
0 commit comments