From 1827c627f29c2080322cff167b237358a87646f8 Mon Sep 17 00:00:00 2001 From: "0x_Dave." Date: Wed, 27 May 2026 15:43:12 +0000 Subject: [PATCH] feat(escrow): release game_id on cancelled/expired matches (#567) --- contracts/escrow/src/lib.rs | 10 ++++++ contracts/escrow/src/tests.rs | 65 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/contracts/escrow/src/lib.rs b/contracts/escrow/src/lib.rs index 47b793d..53a1476 100644 --- a/contracts/escrow/src/lib.rs +++ b/contracts/escrow/src/lib.rs @@ -443,6 +443,11 @@ impl EscrowContract { MATCH_TTL_LEDGERS, ); + // Release game_id so it can be reused in a rematch + env.storage() + .persistent() + .remove(&DataKey::GameId(m.game_id.clone())); + // Remove from active match index Self::remove_from_active(&env, match_id); @@ -579,6 +584,11 @@ impl EscrowContract { MATCH_TTL_LEDGERS, ); + // Release game_id so it can be reused in a rematch + env.storage() + .persistent() + .remove(&DataKey::GameId(m.game_id.clone())); + // Remove from active match index Self::remove_from_active(&env, match_id); diff --git a/contracts/escrow/src/tests.rs b/contracts/escrow/src/tests.rs index 1ae8522..dda2549 100644 --- a/contracts/escrow/src/tests.rs +++ b/contracts/escrow/src/tests.rs @@ -2681,3 +2681,68 @@ fn test_expire_match_refunds_both_players_when_both_deposited_but_still_pending( assert_eq!(token_client.balance(&player1) - p1_balance_before, 100); assert_eq!(token_client.balance(&player2) - p2_balance_before, 100); } + +/// Issue #567 — game_id must be released after cancel so the same ID can be reused. +#[test] +fn test_game_id_released_after_cancel() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let game_id = String::from_str(&env, "rematch_game"); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + client.cancel_match(&id, &player1); + + // Same game_id must be accepted for a new match after cancellation + let id2 = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + assert_ne!(id, id2); +} + +/// Issue #567 — game_id must be released after expire so the same ID can be reused. +#[test] +fn test_game_id_released_after_expire() { + let (env, contract_id, _oracle, player1, player2, token, _admin) = setup(); + let client = EscrowContractClient::new(&env, &contract_id); + + let game_id = String::from_str(&env, "expired_game"); + + let id = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + + // Advance ledger past the default timeout (17_280 ledgers) + env.ledger().with_mut(|li| { + li.sequence_number += 17_281; + }); + client.expire_match(&id); + + // Same game_id must be accepted for a new match after expiry + let id2 = client.create_match( + &player1, + &player2, + &100, + &token, + &game_id, + &Platform::Lichess, + ); + assert_ne!(id, id2); +} \ No newline at end of file