Skip to content

Commit 7aece00

Browse files
committed
dbc: make Anchor consensus-only data. Remove all tx info outside of the library
1 parent 5b93351 commit 7aece00

12 files changed

+129
-260
lines changed

consensus/src/block.rs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ use std::fmt::{Formatter, LowerHex};
2424
use std::str::FromStr;
2525

2626
use amplify::hex::{FromHex, ToHex};
27-
use amplify::{Bytes32StrRev, Wrapper};
27+
use amplify::{ByteArray, Bytes32StrRev, Wrapper};
2828

29-
use crate::{BlockDataParseError, ConsensusDecode, ConsensusEncode, LIB_NAME_BITCOIN};
29+
use crate::{BlockDataParseError, ConsensusDecode, ConsensusEncode, Txid, LIB_NAME_BITCOIN};
3030

3131
#[derive(Wrapper, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, From)]
3232
#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
@@ -58,6 +58,10 @@ pub struct TxMerkleNode(
5858
Bytes32StrRev,
5959
);
6060

61+
impl From<Txid> for TxMerkleNode {
62+
fn from(txid: Txid) -> Self { Self::from_byte_array(txid.to_byte_array()) }
63+
}
64+
6165
#[derive(Wrapper, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, From)]
6266
#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
6367
#[strict_type(lib = LIB_NAME_BITCOIN)]
@@ -73,6 +77,10 @@ pub struct BlockMerkleRoot(
7377
Bytes32StrRev,
7478
);
7579

80+
impl From<TxMerkleNode> for BlockMerkleRoot {
81+
fn from(node: TxMerkleNode) -> Self { Self::from_byte_array(node.to_byte_array()) }
82+
}
83+
7684
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
7785
#[display(LowerHex)]
7886
#[derive(StrictType, StrictEncode, StrictDecode, StrictDumb)]
@@ -112,6 +120,37 @@ impl FromStr for BlockHeader {
112120
}
113121
}
114122

123+
/*
124+
#[derive(Wrapper, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, From)]
125+
#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
126+
#[strict_type(lib = LIB_NAME_BITCOIN)]
127+
#[cfg_attr(
128+
feature = "serde",
129+
derive(Serialize, Deserialize),
130+
serde(crate = "serde_crate", transparent)
131+
)]
132+
#[wrapper(BorrowSlice, Index, RangeOps, Debug)]
133+
pub struct TxMerklePath(TinyVec<TxMerkleNode>);
134+
135+
impl TxMerklePath {
136+
pub fn check(&self, txid: Txid, merkle_root: BlockMerkleRoot) -> Result<(), ()> {
137+
// For a zero-length merkle path the txid is coinbase, and it must be equal to
138+
// the merkle root.
139+
let mut node = TxMerkleNode::from(txid);
140+
141+
for step in &self.0 {
142+
node = TxMerkleNode::with(node, *step);
143+
}
144+
145+
if node != merkle_root.into() {
146+
Err(())
147+
} else {
148+
Ok(())
149+
}
150+
}
151+
}
152+
*/
153+
115154
#[cfg(test)]
116155
mod test {
117156
use super::*;

dbc/src/anchor.rs

Lines changed: 10 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ use bc::{Tx, TxMerkleNode, Txid};
3434
use commit_verify::mpc::{self, Message, ProtocolId};
3535
use strict_encoding::{StrictDumb, StrictEncode};
3636

37-
use crate::opret::OpretProof;
38-
use crate::tapret::TapretProof;
3937
use crate::{DbcMethod, Method, LIB_NAME_BPCORE};
4038

4139
mod dbc {
@@ -115,7 +113,7 @@ impl TxWitness {
115113
derive(Serialize, Deserialize),
116114
serde(crate = "serde_crate", rename_all = "camelCase")
117115
)]
118-
pub struct EtxWitness<L: mpc::Proof + StrictDumb, D: dbc::Proof<M>, M: DbcMethod = Method> {
116+
pub struct Anchor<L: mpc::Proof + StrictDumb, D: dbc::Proof<M>, M: DbcMethod = Method> {
119117
/// Structured multi-protocol LNPBP-4 data the transaction commits to.
120118
pub mpc_proof: L,
121119

@@ -127,7 +125,7 @@ pub struct EtxWitness<L: mpc::Proof + StrictDumb, D: dbc::Proof<M>, M: DbcMethod
127125
pub _method: PhantomData<M>,
128126
}
129127

130-
impl<L: mpc::Proof + StrictDumb, D: dbc::Proof<M>, M: DbcMethod> EtxWitness<L, D, M> {
128+
impl<L: mpc::Proof + StrictDumb, D: dbc::Proof<M>, M: DbcMethod> Anchor<L, D, M> {
131129
/// Constructs extra-transaction witness for a given MPC and DBC
132130
/// proofs.
133131
pub fn new(mpc_proof: L, dbc_proof: D) -> Self {
@@ -156,16 +154,16 @@ pub enum MergeError {
156154
DbcMismatch,
157155
}
158156

159-
impl<D: dbc::Proof<M>, M: DbcMethod> EtxWitness<mpc::MerkleProof, D, M> {
157+
impl<D: dbc::Proof<M>, M: DbcMethod> Anchor<mpc::MerkleProof, D, M> {
160158
/// Reconstructs anchor containing merkle block
161159
pub fn into_merkle_block(
162160
self,
163161
protocol_id: impl Into<ProtocolId>,
164162
message: impl Into<Message>,
165-
) -> Result<EtxWitness<mpc::MerkleBlock, D, M>, mpc::InvalidProof> {
163+
) -> Result<Anchor<mpc::MerkleBlock, D, M>, mpc::InvalidProof> {
166164
let lnpbp4_proof =
167165
mpc::MerkleBlock::with(&self.mpc_proof, protocol_id.into(), message.into())?;
168-
Ok(EtxWitness {
166+
Ok(Anchor {
169167
mpc_proof: lnpbp4_proof,
170168
dbc_proof: self.dbc_proof,
171169
_method: default!(),
@@ -177,7 +175,7 @@ impl<D: dbc::Proof<M>, M: DbcMethod> EtxWitness<mpc::MerkleProof, D, M> {
177175
&self,
178176
protocol_id: impl Into<ProtocolId>,
179177
message: impl Into<Message>,
180-
) -> Result<EtxWitness<mpc::MerkleBlock, D, M>, mpc::InvalidProof> {
178+
) -> Result<Anchor<mpc::MerkleBlock, D, M>, mpc::InvalidProof> {
181179
self.clone().into_merkle_block(protocol_id, message)
182180
}
183181

@@ -207,13 +205,13 @@ impl<D: dbc::Proof<M>, M: DbcMethod> EtxWitness<mpc::MerkleProof, D, M> {
207205
}
208206
}
209207

210-
impl<D: dbc::Proof<M>, M: DbcMethod> EtxWitness<mpc::MerkleBlock, D, M> {
208+
impl<D: dbc::Proof<M>, M: DbcMethod> Anchor<mpc::MerkleBlock, D, M> {
211209
/// Conceals all LNPBP-4 data except specific protocol and produces merkle
212210
/// proof anchor.
213211
pub fn to_merkle_proof(
214212
&self,
215213
protocol: impl Into<ProtocolId>,
216-
) -> Result<EtxWitness<mpc::MerkleProof, D, M>, mpc::LeafNotKnown> {
214+
) -> Result<Anchor<mpc::MerkleProof, D, M>, mpc::LeafNotKnown> {
217215
self.clone().into_merkle_proof(protocol)
218216
}
219217

@@ -222,9 +220,9 @@ impl<D: dbc::Proof<M>, M: DbcMethod> EtxWitness<mpc::MerkleBlock, D, M> {
222220
pub fn into_merkle_proof(
223221
self,
224222
protocol: impl Into<ProtocolId>,
225-
) -> Result<EtxWitness<mpc::MerkleProof, D, M>, mpc::LeafNotKnown> {
223+
) -> Result<Anchor<mpc::MerkleProof, D, M>, mpc::LeafNotKnown> {
226224
let lnpbp4_proof = self.mpc_proof.to_merkle_proof(protocol.into())?;
227-
Ok(EtxWitness {
225+
Ok(Anchor {
228226
mpc_proof: lnpbp4_proof,
229227
dbc_proof: self.dbc_proof,
230228
_method: default!(),
@@ -248,110 +246,3 @@ impl<D: dbc::Proof<M>, M: DbcMethod> EtxWitness<mpc::MerkleBlock, D, M> {
248246
Ok(self)
249247
}
250248
}
251-
252-
#[derive(Clone, Eq, PartialEq, Debug)]
253-
#[derive(StrictType, StrictEncode, StrictDecode)]
254-
#[strict_type(lib = LIB_NAME_BPCORE, tags = custom)]
255-
#[cfg_attr(
256-
feature = "serde",
257-
derive(Serialize, Deserialize),
258-
serde(crate = "serde_crate", rename_all = "camelCase", untagged)
259-
)]
260-
pub enum Anchor<P: mpc::Proof + StrictDumb = mpc::MerkleProof> {
261-
#[strict_type(tag = 0x01)]
262-
Tapret {
263-
tapret: EtxWitness<P, TapretProof>,
264-
txw: TxWitness,
265-
},
266-
#[strict_type(tag = 0x02)]
267-
Opret {
268-
opret: EtxWitness<P, OpretProof>,
269-
txw: TxWitness,
270-
},
271-
#[strict_type(tag = 0x03)]
272-
Dual {
273-
tapret: EtxWitness<P, TapretProof>,
274-
opret: EtxWitness<P, OpretProof>,
275-
txw: TxWitness,
276-
},
277-
}
278-
279-
impl<P: mpc::Proof + StrictDumb> StrictDumb for Anchor<P> {
280-
fn strict_dumb() -> Self {
281-
Self::Tapret {
282-
tapret: strict_dumb!(),
283-
txw: strict_dumb!(),
284-
}
285-
}
286-
}
287-
288-
impl<P: mpc::Proof + StrictDumb> Anchor<P> {
289-
pub fn txid(&self) -> Txid {
290-
match self {
291-
Anchor::Tapret { txw, .. } | Anchor::Opret { txw, .. } | Anchor::Dual { txw, .. } => {
292-
txw.txid()
293-
}
294-
}
295-
}
296-
297-
pub fn tx_witness(&self) -> &TxWitness {
298-
match self {
299-
Anchor::Tapret { txw, .. } | Anchor::Opret { txw, .. } | Anchor::Dual { txw, .. } => {
300-
txw
301-
}
302-
}
303-
}
304-
305-
pub fn mpc_proofs(&self) -> impl Iterator<Item = &P> {
306-
let (t, o) = match self {
307-
Anchor::Tapret { tapret, txw: _ } => (Some(tapret), None),
308-
Anchor::Opret { opret, txw: _ } => (None, Some(opret)),
309-
Anchor::Dual {
310-
tapret,
311-
opret,
312-
txw: _,
313-
} => (Some(tapret), Some(opret)),
314-
};
315-
t.map(|a| &a.mpc_proof)
316-
.into_iter()
317-
.chain(o.map(|a| &a.mpc_proof))
318-
}
319-
320-
fn split(
321-
self,
322-
) -> (TxWitness, Option<EtxWitness<P, TapretProof>>, Option<EtxWitness<P, OpretProof>>) {
323-
match self {
324-
Anchor::Tapret { tapret, txw } => (txw, Some(tapret), None),
325-
Anchor::Opret { opret, txw } => (txw, None, Some(opret)),
326-
Anchor::Dual { tapret, opret, txw } => (txw, Some(tapret), Some(opret)),
327-
}
328-
}
329-
}
330-
331-
impl Anchor<mpc::MerkleBlock> {
332-
/// Merges two anchors keeping revealed data.
333-
pub fn merge_reveal(self, other: Self) -> Result<Self, MergeError> {
334-
if self == other {
335-
return Ok(self);
336-
}
337-
let (txw1, tapret1, opret1) = self.split();
338-
let (txw2, tapret2, opret2) = other.split();
339-
let txw = txw1.merge_reveal(txw2)?;
340-
let tapret = match (tapret1, tapret2) {
341-
(None, None) => None,
342-
(Some(tapret), None) | (None, Some(tapret)) => Some(tapret),
343-
(Some(tapret1), Some(tapret2)) => Some(tapret1.merge_reveal(tapret2)?),
344-
};
345-
let opret = match (opret1, opret2) {
346-
(None, None) => None,
347-
(Some(opret), None) | (None, Some(opret)) => Some(opret),
348-
(Some(opret1), Some(opret2)) => Some(opret1.merge_reveal(opret2)?),
349-
};
350-
Ok(match (tapret, opret) {
351-
(None, None) => unreachable!(),
352-
(Some(tapret), None) => Self::Tapret { tapret, txw },
353-
(None, Some(opret)) => Self::Opret { opret, txw },
354-
(Some(tapret), Some(opret)) => Self::Dual { tapret, opret, txw },
355-
})
356-
}
357-
}

dbc/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,5 @@ pub mod sigtweak;
5858
pub mod tapret;
5959
mod proof;
6060

61-
pub use anchor::Anchor;
61+
pub use anchor::{Anchor, TxWitness};
6262
pub use proof::{DbcMethod, Method, MethodParseError, Proof};

seals/src/txout/witness.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@ use std::marker::PhantomData;
2323

2424
use bc::{Tx, Txid};
2525
use commit_verify::mpc;
26-
use dbc::anchor::EtxWitness;
2726
use dbc::{DbcMethod, Method};
2827
use single_use_seals::SealWitness;
29-
use strict_encoding::StrictDumb;
3028

3129
use crate::txout::{TxoSeal, VerifyError};
3230
use crate::SealCloseMethod;
@@ -53,11 +51,11 @@ pub struct Witness<D: dbc::Proof<M>, M: DbcMethod = Method> {
5351
impl<D: dbc::Proof<M>, M: DbcMethod> Witness<D, M> {
5452
/// Constructs witness from a witness transaction and extra-transaction
5553
/// proof, taken from an anchor.
56-
pub fn with<L: mpc::Proof + StrictDumb>(tx: Tx, etx: EtxWitness<L, D, M>) -> Witness<D, M> {
54+
pub fn with(tx: Tx, dbc: D) -> Witness<D, M> {
5755
Witness {
5856
txid: tx.txid(),
5957
tx,
60-
proof: etx.dbc_proof,
58+
proof: dbc,
6159
_phantom: default!(),
6260
}
6361
}

src/stl.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,29 @@
2323
2424
use bc::Txid;
2525
use commit_verify::mpc;
26+
use dbc::opret::OpretProof;
27+
use dbc::tapret::TapretProof;
2628
use dbc::{Method, LIB_NAME_BPCORE};
2729
use seals::txout::TxPtr;
2830
use strict_types::{CompileError, LibBuilder, TypeLib};
2931

3032
/// Strict types id for the library providing data types from [`dbc`] and
3133
/// [`seals`] crates.
3234
pub const LIB_ID_BPCORE: &str =
33-
"urn:ubideco:stl:3uf6LCUN84pnw4JuwTuPscYa1vxtbYHHmA7EHUUgHdcX#escape-precise-andrea";
35+
"urn:ubideco:stl:6skrch4mJzDzVaTYnCgCxFJLw23SSUxNhK7PKgPdSapR#roof-parent-reunion";
3436

3537
fn _bp_core_stl() -> Result<TypeLib, CompileError> {
3638
LibBuilder::new(libname!(LIB_NAME_BPCORE), tiny_bset! {
3739
strict_types::stl::std_stl().to_dependency(),
3840
bc::stl::bp_tx_stl().to_dependency(),
3941
commit_verify::stl::commit_verify_stl().to_dependency()
4042
})
41-
.transpile::<dbc::Anchor<mpc::MerkleTree>>()
42-
.transpile::<dbc::Anchor<mpc::MerkleBlock>>()
43-
.transpile::<dbc::Anchor<mpc::MerkleProof>>()
43+
.transpile::<dbc::Anchor<mpc::MerkleTree, TapretProof>>()
44+
.transpile::<dbc::Anchor<mpc::MerkleBlock, TapretProof>>()
45+
.transpile::<dbc::Anchor<mpc::MerkleProof, TapretProof>>()
46+
.transpile::<dbc::Anchor<mpc::MerkleTree, OpretProof>>()
47+
.transpile::<dbc::Anchor<mpc::MerkleBlock, OpretProof>>()
48+
.transpile::<dbc::Anchor<mpc::MerkleProof, OpretProof>>()
4449
.transpile::<seals::txout::ExplicitSeal<TxPtr, Method>>()
4550
.transpile::<seals::txout::ExplicitSeal<Txid, Method>>()
4651
.transpile::<seals::SecretSeal>()

stl/Anchor.MerkleBlock.Tapret.vesper

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
AnchorMerkleBlockTapretProof rec
2-
reserved1 bytes len=1 aka=ReservedBytes1
3-
txid bytes len=32 aka=Txid
4-
reserved2 bytes len=1 aka=ReservedBytes1
52
mpcProof rec MerkleBlock
63
depth enum {
74
U5 _0=0 _1=1 _2=2 _3=3 _4=4 _5=5 _6=6 _7=7

stl/Anchor.MerkleProof.Tapret.vesper

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
AnchorMerkleProofTapretProof rec
2-
reserved1 bytes len=1 aka=ReservedBytes1
3-
txid bytes len=32 aka=Txid
4-
reserved2 bytes len=1 aka=ReservedBytes1
52
mpcProof rec MerkleProof
63
pos is U32
74
cofactor is U16

stl/Anchor.MerkleTree.Opret.vesper

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
AnchorMerkleTreeOpretProof rec
2-
reserved1 bytes len=1 aka=ReservedBytes1
3-
txid bytes len=32 aka=Txid
4-
reserved2 bytes len=1 aka=ReservedBytes1
52
mpcProof rec MerkleTree
63
depth enum {
74
U5 _0=0 _1=1 _2=2 _3=3 _4=4 _5=5 _6=6 _7=7

stl/Anchor.MerkleTree.Tapret.vesper

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
AnchorMerkleTreeTapretProof rec
2-
reserved1 bytes len=1 aka=ReservedBytes1
3-
txid bytes len=32 aka=Txid
4-
reserved2 bytes len=1 aka=ReservedBytes1
52
mpcProof rec MerkleTree
63
depth enum {
74
U5 _0=0 _1=1 _2=2 _3=3 _4=4 _5=5 _6=6 _7=7

0 commit comments

Comments
 (0)