From d28d7e64a0c08d323f1a9a0befd3f47d8d89c3c9 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Tue, 17 Sep 2024 19:21:21 +0200 Subject: [PATCH] persistence: always add opret anchors when preset to a consignment Closes #271 --- src/persistence/stash.rs | 4 ++++ src/persistence/stock.rs | 52 ++++++++++++++++++++++++++++------------ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/persistence/stash.rs b/src/persistence/stash.rs index deda9605..c751d7fc 100644 --- a/src/persistence/stash.rs +++ b/src/persistence/stash.rs @@ -28,6 +28,7 @@ use amplify::confinement; use amplify::confinement::{Confined, MediumBlob, TinyOrdMap}; use bp::dbc::anchor::MergeError; use bp::dbc::tapret::TapretCommitment; +use bp::seals::txout::CloseMethod; use commit_verify::mpc; use nonasync::persistence::{CloneNoPersistence, Persisting}; use rgb::validation::Scripts; @@ -118,6 +119,9 @@ pub enum StashInconsistency { /// information about witness {0} is absent. WitnessAbsent(XWitnessId), + /// witness {0} for the bundle {1} misses contract {2} information in {3} anchor. + WitnessMissesContract(XWitnessId, BundleId, ContractId, CloseMethod), + /// bundle {0} is absent. BundleAbsent(BundleId), diff --git a/src/persistence/stock.rs b/src/persistence/stock.rs index 051e31c1..4e48e5cb 100644 --- a/src/persistence/stock.rs +++ b/src/persistence/stock.rs @@ -1352,24 +1352,46 @@ impl Stock { AnchorSet::Opret(opret) => (None, Some(opret)), AnchorSet::Double { tapret, opret } => (Some(tapret), Some(opret)), }; - let mut anchor = None; - if let Some(a) = tapret { - if let Ok(a) = a.to_merkle_proof(contract_id) { - anchor = Some(EAnchor::new(a.mpc_proof, DbcProof::Tapret(a.dbc_proof))); - } - } - if anchor.is_none() { - if let Some(a) = opret { - if let Ok(a) = a.to_merkle_proof(contract_id) { - anchor = Some(EAnchor::new(a.mpc_proof, DbcProof::Opret(a.dbc_proof))); - } + let Ok(tapret) = tapret.map(|a| a.to_merkle_proof(contract_id)).transpose() else { + return Err(StashInconsistency::WitnessMissesContract( + witness_id, + bundle_id, + contract_id, + CloseMethod::TapretFirst, + ) + .into()); + }; + let Ok(opret) = opret.map(|a| a.to_merkle_proof(contract_id)).transpose() else { + return Err(StashInconsistency::WitnessMissesContract( + witness_id, + bundle_id, + contract_id, + CloseMethod::OpretFirst, + ) + .into()); + }; + let anchored_bundles = match (opret, tapret) { + (Some(opret), Some(tapret)) => AnchoredBundles::Double { + tapret_anchor: tapret, + tapret_bundle: bundle.clone(), + opret_anchor: opret, + opret_bundle: bundle, + }, + (Some(opret), None) => AnchoredBundles::with( + EAnchor::new(opret.mpc_proof, DbcProof::Opret(opret.dbc_proof)), + bundle, + ), + (None, Some(tapret)) => AnchoredBundles::with( + EAnchor::new(tapret.mpc_proof, DbcProof::Tapret(tapret.dbc_proof)), + bundle, + ), + (None, None) => { + return Err( + StashInconsistency::BundleMissedInAnchors(bundle_id, contract_id).into() + ); } - } - let Some(anchor) = anchor else { - return Err(StashInconsistency::BundleMissedInAnchors(bundle_id, contract_id).into()); }; - let anchored_bundles = AnchoredBundles::with(anchor, bundle); // TODO: Conceal all transitions except the one we need Ok(BundledWitness {