Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 4 additions & 1 deletion ree-cookie-canister/src/canister.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
},
state::{ExchangeState, GameStatus, PoolState},
utils::{
calculate_premine_rune_amount, tweak_pubkey_with_empty, AddLiquidityInfo, RegisterInfo,
calculate_premine_rune_amount, tweak_pubkey_with_empty, AddLiquidityInfo, ExecuteTxGuard, RegisterInfo
},
ExchangeError, Seconds, MIN_BTC_VALUE,
};
Expand Down Expand Up @@ -291,6 +291,9 @@ pub async fn execute_tx(args: ExecuteTxArgs) -> ExecuteTxResponse {
output_coins,
} = intention;

let _guard = ExecuteTxGuard::new(pool_address.clone())
.ok_or(format!("Pool {0} Executing", pool_address).to_string())?;

read_state(|s| {
return s
.address
Expand Down
4 changes: 4 additions & 0 deletions ree-cookie-canister/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use ic_stable_structures::Storable;
use itertools::Itertools;
use ree_types::{CoinBalance, CoinId, InputCoin, OutputCoin};
use std::borrow::Cow;
use std::collections::HashSet;

use crate::game::game::Game;
use crate::memory::{read_state, GAMER};
Expand All @@ -26,6 +27,8 @@ pub struct ExchangeState {
pub etching_key: Option<String>,
pub richswap_pool_address: String,
pub game_status: GameStatus,
#[serde(default)]
pub executing_pools: HashSet<String>
}

#[derive(CandidType, Deserialize, Serialize, Clone, Debug)]
Expand Down Expand Up @@ -110,6 +113,7 @@ impl ExchangeState {
etching_key: None,
richswap_pool_address,
game_status: GameStatus::InitKey,
executing_pools: HashSet::new(),
}
}

Expand Down
26 changes: 25 additions & 1 deletion ree-cookie-canister/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
use ic_cdk::api::management_canister::bitcoin::{BitcoinNetwork, Satoshi};
use ree_types::bitcoin::key::{Secp256k1, TapTweak, TweakedPublicKey};

use crate::{memory::read_state, *};
use crate::{memory::{mutate_state, read_state}, *};

#[must_use]
pub struct ExecuteTxGuard(String);

impl ExecuteTxGuard {
pub fn new(pool_address: String) -> Option<Self> {
mutate_state( |s| {
if s.executing_pools.contains(&pool_address) {
return None::<ExecuteTxGuard>;
Copy link

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The explicit type annotation in 'return None::' may be redundant; consider simplifying the return statement to 'None' for clarity.

Suggested change
return None::<ExecuteTxGuard>;
return None;

Copilot uses AI. Check for mistakes.

}

s.executing_pools.insert(pool_address.clone());
Some(ExecuteTxGuard(pool_address))
})
}
}

impl Drop for ExecuteTxGuard {
fn drop(&mut self) {
mutate_state(|s| {
s.executing_pools.remove(&self.0);
});
}
}

pub(crate) fn tweak_pubkey_with_empty(untweaked: Pubkey) -> TweakedPublicKey {
let secp = Secp256k1::new();
Expand Down