@@ -68,8 +68,6 @@ const FEE_CAP: u64 = 20000;
6868const PLAYERS_REG_HEAD_LEN : usize = 152 ;
6969const PLAYERS_REG_INIT_LEN : usize = PLAYERS_REG_HEAD_LEN + 4 ;
7070
71- const MAX_RETRIES_FOR_GET_PLAYERS_REG : usize = 5 ;
72-
7371fn read_keypair ( path : PathBuf ) -> TransportResult < Keypair > {
7472 let keypair = solana_sdk:: signature:: read_keypair_file ( path)
7573 . map_err ( |e| TransportError :: InvalidKeyfile ( e. to_string ( ) ) ) ?;
@@ -646,14 +644,15 @@ impl TransportT for SolanaTransport {
646644 let ( payer, payer_pubkey) = self . payer ( ) ?;
647645 let game_account_pubkey = Self :: parse_pubkey ( & addr) ?;
648646 let game_state = self . internal_get_game_state ( & game_account_pubkey) . await ?;
649- let players = self
650- . internal_get_players_reg_state (
647+ let ( game_state, players_reg) = self
648+ . internal_get_game_state_and_players_reg_state (
649+ & game_account_pubkey,
651650 & game_state. players_reg_account ,
652651 game_state. access_version ,
653652 game_state. settle_version ,
654653 )
655- . await ?
656- . players ;
654+ . await ?;
655+ let players = players_reg . players ;
657656
658657 if game_state. settle_version != params. settle_version {
659658 return Err ( Error :: SettleVersionMismatch (
@@ -803,16 +802,16 @@ impl TransportT for SolanaTransport {
803802 tx. sign ( & [ payer] , blockhash) ;
804803 let sig = self . send_transaction ( tx) ?;
805804
806- let game_state = self . internal_get_game_state ( & game_account_pubkey) . await ?;
807-
808- let players = self
809- . internal_get_players_reg_state (
805+ let ( game_state, players_reg) = self
806+ . internal_get_game_state_and_players_reg_state (
807+ & game_account_pubkey,
810808 & game_state. players_reg_account ,
811809 game_state. access_version ,
812810 game_state. settle_version ,
813811 )
814- . await ?
815- . players ;
812+ . await ?;
813+
814+ let players = players_reg. players ;
816815
817816 Ok ( SettleResult {
818817 signature : sig. to_string ( ) ,
@@ -1303,27 +1302,28 @@ impl TransportT for SolanaTransport {
13031302 Ok ( x) => x,
13041303 Err ( e) => {
13051304 error!( "Game state deserialization error: {}" , e. to_string( ) ) ;
1306- yield( Err ( Error :: TransportError ( e. to_string( ) ) ) ) ;
13071305 unsub( ) . await ;
13081306 return ;
13091307 }
13101308 } ;
13111309
1312- let players = match self . internal_get_players_reg_state(
1310+ let ( game_state, players_reg) = match self . internal_get_game_state_and_players_reg_state(
1311+ & game_account_pubkey,
13131312 & state. players_reg_account,
13141313 state. access_version,
13151314 state. settle_version,
13161315 ) . await {
1317- Ok ( players_reg) => players_reg. players ,
1316+ Ok ( ( game_state , players_reg) ) => ( game_state , players_reg) ,
13181317 Err ( e) => {
13191318 error!( "Get players reg error: {}" , e. to_string( ) ) ;
13201319 unsub( ) . await ;
1321- yield Err ( Error :: TransportError ( e. to_string( ) ) ) ;
13221320 return ;
13231321 }
13241322 } ;
13251323
1326- let acc = match state. into_account( addr. clone( ) , players) {
1324+ let players = players_reg. players;
1325+
1326+ let acc = match game_state. into_account( addr. clone( ) , players) {
13271327 Ok ( x) => x,
13281328 Err ( e) => {
13291329 error!( "Game account parsing error: {}" , e. to_string( ) ) ;
@@ -1340,11 +1340,13 @@ impl TransportT for SolanaTransport {
13401340 async fn get_game_account ( & self , addr : & str ) -> Result < Option < GameAccount > > {
13411341 let game_account_pubkey = Self :: parse_pubkey ( addr) ?;
13421342 let game_state = self . internal_get_game_state ( & game_account_pubkey) . await ?;
1343- let players = self . internal_get_players_reg_state (
1343+ let ( game_state, players_reg) = self . internal_get_game_state_and_players_reg_state (
1344+ & game_account_pubkey,
13441345 & game_state. players_reg_account ,
13451346 game_state. access_version ,
13461347 game_state. settle_version
1347- ) . await ?. players ;
1348+ ) . await ?;
1349+ let players = players_reg. players ;
13481350 Ok ( Some ( game_state. into_account ( addr, players) ?) )
13491351 }
13501352
@@ -1688,47 +1690,44 @@ impl SolanaTransport {
16881690
16891691 /// Get the state of on-chain players registrations of a game
16901692 /// Not for public API usage
1691- async fn internal_get_players_reg_state (
1693+ async fn internal_get_game_state_and_players_reg_state (
16921694 & self ,
1695+ game_account_pubkey : & Pubkey ,
16931696 players_reg_account_pubkey : & Pubkey ,
16941697 access_version : u64 ,
16951698 settle_version : u64 ,
1696- ) -> TransportResult < PlayersReg > {
1697- let mut retries = 0 ;
1698- loop {
1699- if retries == MAX_RETRIES_FOR_GET_PLAYERS_REG {
1700- break ;
1701- }
1702- let players_reg_account = self
1703- . client
1704- . get_account_with_commitment (
1705- players_reg_account_pubkey,
1706- CommitmentConfig :: finalized ( ) ,
1707- )
1708- . map_err ( |e| TransportError :: AccountNotFound ( e. to_string ( ) ) ) ?
1709- . value
1710- . ok_or ( TransportError :: AccountNotFound ( players_reg_account_pubkey. to_string ( ) ) ) ?;
1699+ ) -> TransportResult < ( GameState , PlayersReg ) > {
1700+
1701+ let accounts_result = self . client . get_multiple_accounts_with_commitment ( & [
1702+ * game_account_pubkey,
1703+ * players_reg_account_pubkey,
1704+ ] , CommitmentConfig :: finalized ( ) )
1705+ . map_err ( |e| TransportError :: GetAccountError ( e. to_string ( ) ) ) ?
1706+ . value ;
1707+
1708+ let game_account_data = accounts_result[ 0 ]
1709+ . as_ref ( )
1710+ . map ( |acc| & acc. data )
1711+ . ok_or ( TransportError :: GameAccountNotFound ) ?;
17111712
1712- let mut players_reg = PlayersReg :: try_from_slice ( & players_reg_account. data . as_slice ( ) )
1713+ let players_reg_data = accounts_result[ 1 ]
1714+ . as_ref ( )
1715+ . map ( |acc| & acc. data )
1716+ . ok_or ( TransportError :: GameAccountPlayersNotFound ) ?;
1717+
1718+ let game_state = GameState :: deserialize ( & mut game_account_data. as_slice ( ) )
1719+ . map_err ( |_| TransportError :: GameStateDeserializeError ) ?;
1720+
1721+ let mut players_reg = PlayersReg :: try_from_slice ( & players_reg_data. as_slice ( ) )
17131722 . map_err ( |_| TransportError :: PlayersRegDeserializationError ) ?;
17141723
1715- if players_reg. access_version == access_version
1716- && players_reg. settle_version == settle_version
1717- {
1718- players_reg. players . retain ( |p| p. access_version != 0 ) ;
1724+ if players_reg. access_version == access_version && players_reg. settle_version == settle_version {
1725+ players_reg. players . retain ( |p| p. access_version != 0 ) ;
17191726
1720- return Ok ( players_reg) ;
1721- }
1722- println ! ( "Versions mismatches, PlayersReg: A {} S {}, GameAccount: A {} S {}" ,
1723- players_reg. access_version, players_reg. settle_version,
1724- access_version, settle_version) ;
1725- retries += 1 ;
1727+ return Ok ( ( game_state, players_reg) ) ;
17261728 }
1727- error ! (
1728- "Failed to get players_reg_account for {}" ,
1729- players_reg_account_pubkey
1730- ) ;
1731- Err ( TransportError :: GameAccountPlayersNotFound )
1729+
1730+ Err ( TransportError :: GameStatePlayersRegVersionMismatch )
17321731 }
17331732
17341733 /// Get the state of an on-chain game account by its public key
0 commit comments