Skip to content

Commit

Permalink
psbt: implement everything
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Dec 18, 2023
1 parent beeab18 commit 258003b
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 110 deletions.
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 46 additions & 13 deletions psbt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,39 +26,71 @@ mod rgb;

use bp::dbc::opret::OpretProof;
use bp::dbc::tapret::TapretProof;
use psbt::Psbt;
use rgbstd::containers::{Batch, CloseMethodSet, Fascia, XchainOutpoint};
use psbt::{DbcPsbtError, Psbt};
use rgbstd::containers::{Batch, Fascia, XchainOutpoint};
use rgbstd::{AnchorSet, XAnchor};

pub use self::rgb::{
ProprietaryKeyRgb, RgbExt, RgbInExt, RgbOutExt, RgbPsbtError, PSBT_GLOBAL_RGB_TRANSITION,
PSBT_IN_RGB_CONSUMED_BY, PSBT_OUT_RGB_VELOCITY_HINT, PSBT_RGB_PREFIX,
};

pub enum EmbedError {}
pub enum CommitError {}
#[derive(Clone, Eq, PartialEq, Debug, Display, Error)]
#[display(doc_comments)]
pub enum EmbedError {
/// provided transaction batch references inputs which are absent from the
/// PSBT. Possible it was created for a different PSBT.
AbsentInputs,

/// the provided PSBT is invalid since it doublespends on some of its
/// inputs.
PsbtRepeatedInputs,
}

#[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)]
#[display(inner)]
pub enum CommitError {
#[from]
Rgb(RgbPsbtError),

#[from]
Dbc(DbcPsbtError),
}

#[derive(Clone, Eq, PartialEq, Debug, Display, Error)]
#[display(doc_comments)]
pub enum ExtractError {}

// TODO: Batch must be homomorphic by the outpoint type (chain)

pub trait RgbPsbt {
fn rgb_embed(&mut self, batch: Batch) -> Result<(), EmbedError>;
fn rgb_commit(&mut self) -> Result<Fascia, CommitError>;
fn rgb_extract(&mut self) -> Result<Fascia, ExtractError>;
fn rgb_extract(&self) -> Result<Fascia, ExtractError>;
}

impl RgbPsbt for Psbt {
fn rgb_embed(&mut self, batch: Batch) -> Result<(), EmbedError> {
// TODO: Mark outputs for hosting opret/taprets
for item in batch {
let contract_id = item.transition.contract_id;
for info in batch {
let contract_id = info.transition.contract_id;
let mut inputs = info.inputs.into_inner();
for input in self.inputs_mut() {
let outpoint = input.prevout().outpoint();
if item.inputs.contains(&XchainOutpoint::Bitcoin(outpoint)) {
input.set_rgb_consumer(contract_id, item.id)?;
if let Some(pos) = inputs
.iter()
.position(|i| i == &XchainOutpoint::Bitcoin(outpoint))
{
inputs.remove(pos);
input
.set_rgb_consumer(contract_id, info.id)
.map_err(|_| EmbedError::PsbtRepeatedInputs)?;
}
}
self.push_rgb_transition(item.transition, item.methods)?;
if !inputs.is_empty() {
return Err(EmbedError::AbsentInputs);
}
self.push_rgb_transition(info.transition, info.methods)
.expect("transitions are unique since they are in BTreeMap indexed by opid");
}
Ok(())
}
Expand All @@ -72,10 +104,11 @@ impl RgbPsbt for Psbt {
if methods.has_tapret_first() {
tapret_anchor = Some(self.dbc_commit::<TapretProof>()?);
}
if methods.has_tapret_first() {
if methods.has_opret_first() {
opret_anchor = Some(self.dbc_commit::<OpretProof>()?);
}
let anchor = AnchorSet::from_split(tapret_anchor, opret_anchor)?;
let anchor = AnchorSet::from_split(tapret_anchor, opret_anchor)
.expect("at least one of DBC are present due to CloseMethodSet type guarantees");
Ok(Fascia {
anchor: XAnchor::Bitcoin(anchor),
bundles,
Expand Down
Loading

0 comments on commit 258003b

Please sign in to comment.