Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ pub enum Error {
#[error("Game uninitialized")]
GameUninitialized,

#[error("Game closed")]
GameClosed,

#[error("Invalid bridge event")]
InvalidBridgeEvent,

Expand Down
2 changes: 1 addition & 1 deletion examples/minimal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl Minimal {

impl GameHandler for Minimal {

fn init_state(init_account: InitAccount) -> Result<Self, HandleError> {
fn init_state(_effect: &mut Effect, init_account: InitAccount) -> Result<Self, HandleError> {
let account_data: MinimalAccountData = init_account.data()?;
Ok(Self {
n: account_data.init_n,
Expand Down
18 changes: 10 additions & 8 deletions transactor/src/component/wrapped_transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,16 @@ impl TransportT for WrappedTransport {
return;
}
None => {
info!("Restart subscription after {} seconds", interval);
tokio::time::sleep(std::time::Duration::from_secs(interval)).await;
let new_sub = self.inner.subscribe_game_account(addr).await;
sub = match new_sub {
Ok(new_sub) => new_sub,
Err(e) => {
yield Err(e);
return;
sub = loop {
info!("Restart subscription after {} seconds", interval);
tokio::time::sleep(std::time::Duration::from_secs(interval)).await;
let new_sub = self.inner.subscribe_game_account(addr).await;
match new_sub {
Ok(new_sub) => break new_sub,
Err(e) => {
error!("Subscribe game account err: {}", e.to_string());
continue;
}
}
};
}
Expand Down
27 changes: 21 additions & 6 deletions transport/src/solana.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use race_core::{
use std::str::FromStr;
use std::{path::PathBuf, pin::Pin};

use solana_account_decoder::UiAccountEncoding;
use solana_account_decoder::{UiAccount, UiAccountEncoding};
use solana_pubsub_client::nonblocking::pubsub_client::PubsubClient;
use solana_rpc_client::rpc_client::RpcClient;
use solana_rpc_client_api::config::{RpcAccountInfoConfig, RpcSendTransactionConfig};
Expand Down Expand Up @@ -1278,20 +1278,27 @@ impl TransportT for SolanaTransport {
.await
{
Ok((stream, unsub)) => (stream, unsub),
Err(e) => {
Err(_) => {
error!("Failed on calling account_subscribe");
yield Err(Error::TransportError(e.to_string()));
return;
}
};

while let Some(rpc_response) = stream.next().await {
let ui_account = rpc_response.value;
let ui_account: UiAccount = rpc_response.value;

let Some(data) = ui_account.data.decode() else {
error!("Found an empty account data");
unsub().await;
return;
};
if data.as_slice().len() == 1 {
info!("Game closed, quit sub loop");
unsub().await;
yield Err(Error::GameClosed);
return;
}

let state = match GameState::deserialize(&mut data.as_slice()) {
Ok(x) => x,
Err(e) => {
Expand All @@ -1302,11 +1309,19 @@ impl TransportT for SolanaTransport {
}
};

let players = self.internal_get_players_reg_state(
let players = match self.internal_get_players_reg_state(
&state.players_reg_account,
state.access_version,
state.settle_version,
).await?.players;
).await {
Ok(players_reg) => players_reg.players,
Err(e) => {
error!("Get players reg error: {}", e.to_string());
unsub().await;
yield Err(Error::TransportError(e.to_string()));
return;
}
};

let acc = match state.into_account(addr.clone(), players) {
Ok(x) => x,
Expand Down
10 changes: 9 additions & 1 deletion transport/src/solana/types/state/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,19 @@ impl From<PlayerBalance> for race_core::types::PlayerBalance {
}
}

#[derive(Default, BorshDeserialize, BorshSerialize, Debug, PartialEq, Eq, Clone)]
pub enum GameStatus {
#[default]
Initializing,
Initialized,
Closed,
}

// State of on-chain GameAccount
#[cfg_attr(test, derive(PartialEq, Clone))]
#[derive(Default, BorshDeserialize, BorshSerialize, Debug)]
pub struct GameState {
pub is_initialized: bool,
pub game_status: GameStatus,
// the contract version, used for upgrade
pub version: String,
// game name displayed on chain
Expand Down
Loading