diff --git a/client/src/client.rs b/client/src/client.rs index b056343..f1996ac 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -279,7 +279,12 @@ impl Client { // Space => Outpoint mapping will be removed // since this type of revocation only happens when an // expired space is being re-opened for auction. - // No bids here so only remove Outpoint -> Spaceout + // Remove both Space -> Outpoint and Outpoint -> Spaceout mappings + if let Some(space) = update.output.spaceout.space.as_ref() { + let base_hash = Sha256::hash(space.name.as_ref()); + let space_key = SpaceKey::from(base_hash); + state.remove(space_key); + } let hash = OutpointKey::from_outpoint::(update.output.outpoint()); state.remove(hash); diff --git a/client/src/store.rs b/client/src/store.rs index e87dc3d..95a5f63 100644 --- a/client/src/store.rs +++ b/client/src/store.rs @@ -218,10 +218,19 @@ impl ChainState for LiveSnapshot { if let Some(outpoint) = outpoint { let spaceout = self.get_spaceout(&outpoint)?; - return Ok(Some(FullSpaceOut { - txid: outpoint.txid, - spaceout: spaceout.expect("should exist if outpoint exists"), - })); + // Handle data inconsistency gracefully: if outpoint exists but spaceout doesn't, + // this indicates the space was revoked but the space->outpoint mapping wasn't cleaned up. + // Clean up the inconsistent mapping and return None instead of panicking. + if let Some(spaceout) = spaceout { + return Ok(Some(FullSpaceOut { + txid: outpoint.txid, + spaceout, + })); + } else { + // Clean up the inconsistent space->outpoint mapping + self.remove(*space_hash); + return Ok(None); + } } Ok(None) } diff --git a/protocol/src/script.rs b/protocol/src/script.rs index b2f77b8..95a53e0 100644 --- a/protocol/src/script.rs +++ b/protocol/src/script.rs @@ -148,10 +148,18 @@ impl SpaceScript { let existing = src.get_space_outpoint(&spacehash)?; match existing { None => OpenHistory::NewSpace(name.to_owned()), - Some(outpoint) => OpenHistory::ExistingSpace(FullSpaceOut { - txid: outpoint.txid, - spaceout: src.get_spaceout(&outpoint)?.expect("spaceout exists"), - }), + Some(outpoint) => { + // Handle data inconsistency: if spaceout doesn't exist, treat as new space + // This can happen if the space was revoked but the space->outpoint mapping + // wasn't cleaned up properly + match src.get_spaceout(&outpoint)? { + Some(spaceout) => OpenHistory::ExistingSpace(FullSpaceOut { + txid: outpoint.txid, + spaceout, + }), + None => OpenHistory::NewSpace(name.to_owned()), + } + } } }; let open = Ok(kind);