Skip to content

Commit

Permalink
Bugfixes for subgame
Browse files Browse the repository at this point in the history
  • Loading branch information
DogLooksGood committed Nov 20, 2024
1 parent ca39096 commit f2971ca
Show file tree
Hide file tree
Showing 24 changed files with 238 additions and 178 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions api/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,19 @@ pub trait BridgeEvent: Sized + BorshSerialize + BorshDeserialize {
Self::try_from_slice(slice).or(Err(HandleError::MalformedBridgeEvent))
}
}

#[cfg(test)]
mod tests {

use crate::effect::Effect;

use super::*;

#[test]
fn a() {
let v = vec![0,0,0,0,0,66,21,114,73,147,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
let e = Effect::try_from_slice(&v);

println!("{:?}", e);
}
}
15 changes: 8 additions & 7 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ readme.workspace = true
publish = true

[dependencies]
sha256 = { workspace = true }
race-api = { workspace = true }
async-trait = { workspace = true }
thiserror = { workspace = true }
sha256.workspace = true
race-api.workspace = true
async-trait.workspace = true
thiserror.workspace = true
serde = { workspace = true, features = ["derive"], optional = true }
serde_json = { workspace = true, optional = true }
borsh = { workspace = true }
futures = { workspace = true }
rs_merkle = { workspace = true }
borsh.workspace = true
futures.workspace = true
rs_merkle.workspace = true
tokio = { workspace = true, features = ["sync"] }

[dev-dependencies]
anyhow.workspace = true
Expand Down
4 changes: 2 additions & 2 deletions core/src/checkpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ impl Checkpoint {
}
}

pub fn init_data(&mut self, id: usize, game_spec: GameSpec, data: Vec<u8>) -> Result<(), Error> {
pub fn init_data(&mut self, id: usize, game_spec: GameSpec, versions: Versions, data: Vec<u8>) -> Result<(), Error> {
match self.data.entry(id) {
std::collections::hash_map::Entry::Occupied(_) => {
return Err(Error::CheckpointAlreadyExists);
Expand All @@ -154,7 +154,7 @@ impl Checkpoint {
data,
sha: sha.into(),
game_spec,
..Default::default()
versions,
};
v.insert(versioned_data);
self.update_root_and_proofs();
Expand Down
23 changes: 8 additions & 15 deletions core/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl ContextPlayer {
#[derive(Debug, Clone)]
pub enum SubGameInitSource {
FromCheckpoint(VersionedData),
FromInitAccount(InitAccount),
FromInitAccount(InitAccount, Versions),
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -214,6 +214,8 @@ impl GameContext {
pub fn try_new_with_sub_game_spec(init: SubGameInit) -> Result<Self> {
let SubGameInit { spec, nodes, source } = init;

println!("NODES: {:?}", nodes);

let (handler_state, versions, init_data, checkpoint) = match source {
SubGameInitSource::FromCheckpoint(versioned_data) => {
let mut checkpoint = Checkpoint::default();
Expand All @@ -222,11 +224,13 @@ impl GameContext {
checkpoint.init_versioned_data(versioned_data)?;
(data, versions, vec![], checkpoint)
}
SubGameInitSource::FromInitAccount(init_account) => {
(vec![], Default::default(), init_account.data, Default::default())
SubGameInitSource::FromInitAccount(init_account, versions) => {
(vec![], versions, init_account.data, Default::default())
}
};

println!("Versions: {}", versions);

Ok(Self {
spec,
nodes: nodes.clone(),
Expand Down Expand Up @@ -581,17 +585,6 @@ impl GameContext {
self.status = status;
}

/// Set player status by address.
/// Using it in custom event handler is not allowed.
pub fn set_node_status(&mut self, addr: &str, status: NodeStatus) -> Result<()> {
if let Some(n) = self.nodes.iter_mut().find(|n| n.addr.eq(&addr)) {
n.status = status;
} else {
return Err(Error::InvalidPlayerAddress);
}
Ok(())
}

pub fn add_node(&mut self, node_addr: String, access_version: u64, mode: ClientMode) {
self.nodes.retain(|n| n.addr.ne(&node_addr));
self.nodes
Expand Down Expand Up @@ -892,7 +885,7 @@ impl GameContext {
self.set_game_status(GameStatus::Idle);
} else if is_init {
self.bump_settle_version()?;
self.checkpoint.init_data(self.spec.game_id, self.spec.clone(), state)?;
self.checkpoint.init_data(self.spec.game_id, self.spec.clone(), self.versions, state)?;
self.checkpoint.set_access_version(self.versions.access_version);
self.set_game_status(GameStatus::Idle);
}
Expand Down
6 changes: 0 additions & 6 deletions core/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,6 @@ pub fn general_handle_event(
Ok(())
}

Event::Bridge {
..
} => {
Ok(())
}

_ => Ok(()),
}
}
Expand Down
19 changes: 19 additions & 0 deletions core/src/types/accounts/game_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ pub struct PlayerJoin {
pub verify_key: String,
}

impl std::fmt::Display for PlayerJoin {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Player#{}@{}", self.addr, self.access_version)
}
}

impl PlayerJoin {
pub fn new<S: Into<String>>(
addr: S,
Expand Down Expand Up @@ -91,6 +97,12 @@ impl ServerJoin {
}
}

impl std::fmt::Display for ServerJoin {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Server#{}@{}", self.addr, self.access_version)
}
}

/// Represent a player call the deposit instruction in contract.
#[derive(Debug, PartialEq, Eq, Clone, BorshSerialize, BorshDeserialize)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
Expand All @@ -101,6 +113,13 @@ pub struct PlayerDeposit {
pub settle_version: u64,
}

impl std::fmt::Display for PlayerDeposit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Deposit#{}-{}", self.addr, self.amount)
}
}


impl PlayerDeposit {
pub fn new<S: Into<String>>(addr: S, balance: u64, settle_version: u64) -> Self {
Self {
Expand Down
1 change: 1 addition & 0 deletions env/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub struct TransactorConfig {
pub disable_blacklist: Option<bool>,
pub debug_mode: Option<bool>,
pub log_dir: Option<String>,
pub bundle_dir: Option<String>,
}

#[derive(Deserialize)]
Expand Down
2 changes: 1 addition & 1 deletion facade/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ async fn run_server(context: Context) -> anyhow::Result<ServerHandle> {
let middleware = ServiceBuilder::new().layer(cors);

let http_server = ServerBuilder::default()
.max_response_body_size(64_000_000)
.max_response_body_size(1_000_000_000)
.set_host_filtering(AllowHosts::Any)
.set_middleware(middleware)
.build(HTTP_HOST.parse::<SocketAddr>()?)
Expand Down
2 changes: 1 addition & 1 deletion js/sdk-core/src/app-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ export class AppClient extends BaseClient {
if (checkpointOffChain !== undefined && checkpointOnChain !== undefined) {
this.__gameContext.checkpoint = Checkpoint.fromParts(checkpointOffChain, checkpointOnChain)
} else {
this.__gameContext.checkpoint = Checkpoint.default()
throw new Error('Game is not served. This is unexpected, mostly a bug.')
}

const gameContext = this.__gameContext.subContext(subGame, this.__gameContext.checkpoint);
Expand Down
17 changes: 17 additions & 0 deletions js/sdk-core/src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export type EventKind =
| 'SecretsReady'
| 'Shutdown'
| 'Bridge'
| 'SubGameReady'
// Client-only events
| 'Init'
| 'Checkpoint'
Expand Down Expand Up @@ -424,6 +425,22 @@ export class Bridge extends GameEvent implements IEventKind {
}
}

@variant(20)
export class SubGameReady extends GameEvent implements IEventKind {
@field('usize')
gameId!: number

constructor(fields: Fields<SubGameReady>) {
super()
Object.assign(this, fields)
Object.setPrototypeOf(this, SubGameReady.prototype)
}

kind(): EventKind {
return 'SubGameReady'
}
}

// Client-only events, they can't be serialized and deserialized.

export class Init extends GameEvent implements IEventKind {
Expand Down
26 changes: 21 additions & 5 deletions js/sdk-core/src/game-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,19 @@ export class GameContext {
settleVersion: gameAccount.settleVersion,
})

let subGames = []

for (const versionedData of checkpoint.data.values()) {
subGames.push(new SubGame({
gameId: versionedData.id,
bundleAddr: versionedData.spec.bundleAddr,
initAccount: new InitAccount({
maxPlayers: versionedData.spec.maxPlayers,
data: Uint8Array.of(),
})
}))
}

this.spec = spec
this.versions = versions
this.status = 'idle'
Expand All @@ -158,7 +171,7 @@ export class GameContext {
this.decisionStates = []
this.handlerState = handlerState
this.checkpoint = checkpoint
this.subGames = []
this.subGames = subGames
this.initData = gameAccount.data
this.players = players
this.entryType = gameAccount.entryType
Expand All @@ -171,6 +184,7 @@ export class GameContext {
// Use init_account or checkpoint
let versions: Versions
let initData: Uint8Array
let handlerState: Uint8Array
let spec = new GameSpec({
gameAddr: this.spec.gameAddr,
gameId: subGame.gameId,
Expand All @@ -180,13 +194,15 @@ export class GameContext {
if (source instanceof InitAccount) {
versions = Versions.default()
initData = source.data
handlerState = Uint8Array.of()
} else {
const v = source.getVersionedData(spec.gameId)?.versions
if (v === undefined){
const vd = source.getVersionedData(spec.gameId)
if (vd === undefined){
throw new Error('Missing checkpoint')
}
versions = v
versions = vd.versions
initData = Uint8Array.of()
handlerState = vd.data
}
c.versions = versions
c.nodes = this.nodes
Expand All @@ -195,7 +211,7 @@ export class GameContext {
c.timestamp = 0n
c.randomStates = []
c.decisionStates = []
c.handlerState = Uint8Array.of()
c.handlerState = handlerState;
c.checkpoint = this.checkpoint.clone()
c.subGames = []
c.initData = initData
Expand Down
2 changes: 1 addition & 1 deletion transactor/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ pub use wrapped_client::WrappedClient;
pub use wrapped_handler::WrappedHandler;
pub use wrapped_transport::WrappedTransport;
pub use wrapped_storage::WrappedStorage;
pub use event_bridge::{EventBridgeChild, EventBridgeParent};
pub use event_bridge::{EventBridgeChild, EventBridgeParent, BridgeToParent};
2 changes: 1 addition & 1 deletion transactor/src/component/broadcaster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ impl Component<ConsumerPorts, BroadcasterContext> for Broadcaster {

let mut event_backup_groups = ctx.event_backup_groups.lock().await;
if let Some(current) = event_backup_groups.back_mut() {
info!("{} Merge sync: {:?}", env.log_prefix, sync);
// info!("{} Merge sync: {:?}", env.log_prefix, sync);
current.sync.merge(&sync);
} else {
error!("{} Sync dropped", env.log_prefix);
Expand Down
22 changes: 17 additions & 5 deletions transactor/src/component/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use tracing::{info, warn};

use crate::{frame::EventFrame, utils::addr_shorthand};

use super::{event_bus::CloseReason};
use super::event_bus::CloseReason;

/// An interface for a component that can be attached to the event bus.
pub trait Attachable {
Expand Down Expand Up @@ -37,7 +37,11 @@ pub struct PortsHandle {
}

impl PortsHandle {
fn from_inner<S: Into<String>>(id: S, value: PortsHandleInner, join_handle: JoinHandle<CloseReason>) -> Self {
fn from_inner<S: Into<String>>(
id: S,
value: PortsHandleInner,
join_handle: JoinHandle<CloseReason>,
) -> Self {
Self {
id: id.into(),
input_tx: value.input_tx,
Expand All @@ -49,7 +53,13 @@ impl PortsHandle {

impl PortsHandle {
pub async fn wait(self) -> CloseReason {
self.join_handle.await.unwrap()
match self.join_handle.await {
Ok(close_reason) => close_reason,
Err(e) => CloseReason::Fault(race_core::error::Error::InternalError(format!(
"Error in waiting close reason: {:?}",
e
))),
}
}

#[allow(dead_code)]
Expand Down Expand Up @@ -182,7 +192,7 @@ impl PipelinePorts {

pub fn clone_as_producer(&self) -> ProducerPorts {
ProducerPorts {
tx: self.tx.clone()
tx: self.tx.clone(),
}
}

Expand Down Expand Up @@ -223,7 +233,9 @@ pub struct ComponentEnv {
impl ComponentEnv {
pub fn new(addr: &str, component_name: &str) -> Self {
let addr_short = addr_shorthand(addr);
Self { log_prefix: format!("[{}|{}]", addr_short, component_name)}
Self {
log_prefix: format!("[{}|{}]", addr_short, component_name),
}
}
}

Expand Down
Loading

0 comments on commit f2971ca

Please sign in to comment.