Skip to content

Commit 545591c

Browse files
committed
support anchor outputs
1 parent 515063b commit 545591c

File tree

5 files changed

+50
-94
lines changed

5 files changed

+50
-94
lines changed

lightning/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ hex = "0.4"
5959
reqwest = { version = "0.11", default-features = false, features = ["json", "blocking"] }
6060
rgb-contracts = { version = "=0.10.2", features = ["electrum"] }
6161
rgb_core = { package = "rgb-core", version = "=0.10.8" }
62-
rgb-lib = "=0.2.0"
62+
rgb-lib = "=0.2.1"
6363
rgb-std = "=0.10.9"
6464
rgb-wallet = "=0.10.9"
6565
serde = { version = "^1.0", features = ["derive"] }

lightning/src/events/bump_transaction.rs

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -589,8 +589,6 @@ where
589589
previous_utxo: anchor_utxo,
590590
satisfaction_weight: commitment_tx.weight() as u64 + ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT,
591591
}];
592-
#[cfg(debug_assertions)]
593-
let must_spend_amount = must_spend.iter().map(|input| input.previous_utxo.value).sum::<u64>();
594592

595593
log_debug!(self.logger, "Peforming coin selection for commitment package (commitment and anchor transaction) targeting {} sat/kW",
596594
package_target_feerate_sat_per_1000_weight);
@@ -605,19 +603,10 @@ where
605603
output: vec![],
606604
};
607605

608-
#[cfg(debug_assertions)]
609-
let total_satisfaction_weight = ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT +
610-
coin_selection.confirmed_utxos.iter().map(|utxo| utxo.satisfaction_weight).sum::<u64>();
611-
#[cfg(debug_assertions)]
612-
let total_input_amount = must_spend_amount +
613-
coin_selection.confirmed_utxos.iter().map(|utxo| utxo.output.value).sum::<u64>();
614-
615606
self.process_coin_selection(&mut anchor_tx, coin_selection);
616607
let anchor_txid = anchor_tx.txid();
617608

618609
debug_assert_eq!(anchor_tx.output.len(), 1);
619-
#[cfg(debug_assertions)]
620-
let unsigned_tx_weight = anchor_tx.weight() as u64 - (anchor_tx.input.len() as u64 * EMPTY_SCRIPT_SIG_WEIGHT);
621610

622611
log_debug!(self.logger, "Signing anchor transaction {}", anchor_txid);
623612
anchor_tx = self.utxo_source.sign_tx(anchor_tx)?;
@@ -626,25 +615,6 @@ where
626615
let anchor_sig = signer.sign_holder_anchor_input(&anchor_tx, 0, &self.secp)?;
627616
anchor_tx.input[0].witness = anchor_descriptor.tx_input_witness(&anchor_sig);
628617

629-
#[cfg(debug_assertions)] {
630-
let signed_tx_weight = anchor_tx.weight() as u64;
631-
let expected_signed_tx_weight = unsigned_tx_weight + total_satisfaction_weight;
632-
// Our estimate should be within a 1% error margin of the actual weight and we should
633-
// never underestimate.
634-
assert!(expected_signed_tx_weight >= signed_tx_weight &&
635-
expected_signed_tx_weight - (expected_signed_tx_weight / 100) <= signed_tx_weight);
636-
637-
let expected_package_fee = fee_for_weight(package_target_feerate_sat_per_1000_weight,
638-
signed_tx_weight + commitment_tx.weight() as u64);
639-
let package_fee = total_input_amount -
640-
anchor_tx.output.iter().map(|output| output.value).sum::<u64>();
641-
// Our fee should be within a 5% error margin of the expected fee based on the
642-
// feerate and transaction weight and we should never pay less than required.
643-
let fee_error_margin = expected_package_fee * 5 / 100;
644-
assert!(package_fee >= expected_package_fee &&
645-
package_fee - fee_error_margin <= expected_package_fee);
646-
}
647-
648618
log_info!(self.logger, "Broadcasting anchor transaction {} to bump channel close with txid {}",
649619
anchor_txid, commitment_tx.txid());
650620
self.broadcaster.broadcast_transactions(&[&commitment_tx, &anchor_tx]);
@@ -683,28 +653,12 @@ where
683653
log_debug!(self.logger, "Peforming coin selection for HTLC transaction targeting {} sat/kW",
684654
target_feerate_sat_per_1000_weight);
685655

686-
#[cfg(debug_assertions)]
687-
let must_spend_satisfaction_weight =
688-
must_spend.iter().map(|input| input.satisfaction_weight).sum::<u64>();
689-
#[cfg(debug_assertions)]
690-
let must_spend_amount = must_spend.iter().map(|input| input.previous_utxo.value).sum::<u64>();
691-
692656
let coin_selection = self.utxo_source.select_confirmed_utxos(
693657
claim_id, must_spend, &htlc_tx.output, target_feerate_sat_per_1000_weight,
694658
)?;
695659

696-
#[cfg(debug_assertions)]
697-
let total_satisfaction_weight = must_spend_satisfaction_weight +
698-
coin_selection.confirmed_utxos.iter().map(|utxo| utxo.satisfaction_weight).sum::<u64>();
699-
#[cfg(debug_assertions)]
700-
let total_input_amount = must_spend_amount +
701-
coin_selection.confirmed_utxos.iter().map(|utxo| utxo.output.value).sum::<u64>();
702-
703660
self.process_coin_selection(&mut htlc_tx, coin_selection);
704661

705-
#[cfg(debug_assertions)]
706-
let unsigned_tx_weight = htlc_tx.weight() as u64 - (htlc_tx.input.len() as u64 * EMPTY_SCRIPT_SIG_WEIGHT);
707-
708662
log_debug!(self.logger, "Signing HTLC transaction {}", htlc_tx.txid());
709663
htlc_tx = self.utxo_source.sign_tx(htlc_tx)?;
710664

@@ -717,24 +671,6 @@ where
717671
htlc_tx.input[idx].witness = htlc_descriptor.tx_input_witness(&htlc_sig, &witness_script);
718672
}
719673

720-
#[cfg(debug_assertions)] {
721-
let signed_tx_weight = htlc_tx.weight() as u64;
722-
let expected_signed_tx_weight = unsigned_tx_weight + total_satisfaction_weight;
723-
// Our estimate should be within a 1% error margin of the actual weight and we should
724-
// never underestimate.
725-
assert!(expected_signed_tx_weight >= signed_tx_weight &&
726-
expected_signed_tx_weight - (expected_signed_tx_weight / 100) <= signed_tx_weight);
727-
728-
let expected_signed_tx_fee = fee_for_weight(target_feerate_sat_per_1000_weight, signed_tx_weight);
729-
let signed_tx_fee = total_input_amount -
730-
htlc_tx.output.iter().map(|output| output.value).sum::<u64>();
731-
// Our fee should be within a 5% error margin of the expected fee based on the
732-
// feerate and transaction weight and we should never pay less than required.
733-
let fee_error_margin = expected_signed_tx_fee * 5 / 100;
734-
assert!(signed_tx_fee >= expected_signed_tx_fee &&
735-
signed_tx_fee - fee_error_margin <= expected_signed_tx_fee);
736-
}
737-
738674
log_info!(self.logger, "Broadcasting {}", log_tx!(htlc_tx));
739675
self.broadcaster.broadcast_transactions(&[&htlc_tx]);
740676
Ok(())

lightning/src/ln/channel.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ impl UnfundedChannelContext {
687687
}
688688

689689
/// Contains everything about the channel including state, and various flags.
690-
pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
690+
pub(crate) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
691691
config: LegacyChannelConfig,
692692

693693
// Track the previous `ChannelConfig` so that we can continue forwarding HTLCs that were
@@ -700,7 +700,7 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
700700
user_id: u128,
701701

702702
/// The current channel ID.
703-
channel_id: ChannelId,
703+
pub(crate) channel_id: ChannelId,
704704
/// The temporary channel ID used during channel setup. Value kept even after transitioning to a final channel ID.
705705
/// Will be `None` for channels created prior to 0.0.115.
706706
temporary_channel_id: Option<ChannelId>,
@@ -915,7 +915,7 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
915915
historical_inbound_htlc_fulfills: HashSet<u64>,
916916

917917
/// This channel's type, as negotiated during channel open
918-
channel_type: ChannelTypeFeatures,
918+
pub(crate) channel_type: ChannelTypeFeatures,
919919

920920
// Our counterparty can offer us SCID aliases which they will map to this channel when routing
921921
// outbound payments. These can be used in invoice route hints to avoid explicitly revealing
@@ -952,7 +952,7 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
952952
/// The consignment endpoint used to exchange the RGB consignment
953953
pub(super) consignment_endpoint: Option<RgbTransport>,
954954

955-
ldk_data_dir: PathBuf,
955+
pub(crate) ldk_data_dir: PathBuf,
956956
}
957957

958958
impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
@@ -1108,7 +1108,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
11081108
self.channel_transaction_parameters.holder_selected_contest_delay
11091109
}
11101110

1111-
fn get_holder_pubkeys(&self) -> &ChannelPublicKeys {
1111+
pub(crate) fn get_holder_pubkeys(&self) -> &ChannelPublicKeys {
11121112
&self.channel_transaction_parameters.holder_pubkeys
11131113
}
11141114

@@ -1117,7 +1117,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
11171117
.as_ref().map(|params| params.selected_contest_delay)
11181118
}
11191119

1120-
fn get_counterparty_pubkeys(&self) -> &ChannelPublicKeys {
1120+
pub(crate) fn get_counterparty_pubkeys(&self) -> &ChannelPublicKeys {
11211121
&self.channel_transaction_parameters.counterparty_parameters.as_ref().unwrap().pubkeys
11221122
}
11231123

@@ -2606,7 +2606,7 @@ impl<SP: Deref> Channel<SP> where
26062606
let counterparty_keys = self.context.build_remote_transaction_keys();
26072607
let mut counterparty_initial_commitment_tx = self.context.build_commitment_transaction(self.context.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx;
26082608
if self.context.is_colored() {
2609-
color_commitment(&self.context.channel_id, &self.context.channel_transaction_parameters.funding_outpoint.unwrap(), &mut counterparty_initial_commitment_tx, &self.context.ldk_data_dir, true)?;
2609+
color_commitment(&self.context, &mut counterparty_initial_commitment_tx, true)?;
26102610
}
26112611
let counterparty_trusted_tx = counterparty_initial_commitment_tx.trust();
26122612
let counterparty_initial_bitcoin_tx = counterparty_trusted_tx.built_transaction();
@@ -2617,7 +2617,7 @@ impl<SP: Deref> Channel<SP> where
26172617
let holder_signer = self.context.build_holder_transaction_keys(self.context.cur_holder_commitment_transaction_number);
26182618
let mut initial_commitment_tx = self.context.build_commitment_transaction(self.context.cur_holder_commitment_transaction_number, &holder_signer, true, false, logger).tx;
26192619
if self.context.is_colored() {
2620-
color_commitment(&self.context.channel_id, &self.context.channel_transaction_parameters.funding_outpoint.unwrap(), &mut initial_commitment_tx, &self.context.ldk_data_dir, false)?;
2620+
color_commitment(&self.context, &mut initial_commitment_tx, false)?;
26212621
}
26222622
{
26232623
let trusted_tx = initial_commitment_tx.trust();
@@ -3023,7 +3023,7 @@ impl<SP: Deref> Channel<SP> where
30233023

30243024
let mut commitment_stats = self.context.build_commitment_transaction(self.context.cur_holder_commitment_transaction_number, &keys, true, false, logger);
30253025
if self.context.is_colored() {
3026-
color_commitment(&self.context.channel_id, &self.context.channel_transaction_parameters.funding_outpoint.unwrap(), &mut commitment_stats.tx, &self.context.ldk_data_dir, false)?;
3026+
color_commitment(&self.context, &mut commitment_stats.tx, false)?;
30273027
}
30283028
let commitment_txid = {
30293029
let trusted_tx = commitment_stats.tx.trust();
@@ -3682,7 +3682,7 @@ impl<SP: Deref> Channel<SP> where
36823682
let keys = self.context.build_holder_transaction_keys(self.context.cur_holder_commitment_transaction_number);
36833683
let mut commitment_stats = self.context.build_commitment_transaction(self.context.cur_holder_commitment_transaction_number, &keys, true, true, logger);
36843684
if self.context.is_colored() {
3685-
if let Err(e) = color_commitment(&self.context.channel_id, &self.context.channel_transaction_parameters.funding_outpoint.unwrap(), &mut commitment_stats.tx, &self.context.ldk_data_dir, false) {
3685+
if let Err(e) = color_commitment(&self.context, &mut commitment_stats.tx, false) {
36863686
log_error!(logger, "Cannot color commitment: {e:?}");
36873687
return None;
36883688
}
@@ -5541,7 +5541,7 @@ impl<SP: Deref> Channel<SP> where
55415541
let counterparty_keys = self.context.build_remote_transaction_keys();
55425542
let mut commitment_stats = self.context.build_commitment_transaction(self.context.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, true, logger);
55435543
if self.context.is_colored() {
5544-
color_commitment(&self.context.channel_id, &self.context.channel_transaction_parameters.funding_outpoint.unwrap(), &mut commitment_stats.tx, &self.context.ldk_data_dir, true).expect("successful commitment coloring");
5544+
color_commitment(&self.context, &mut commitment_stats.tx, true).expect("successful commitment coloring");
55455545
}
55465546
let counterparty_commitment_tx = commitment_stats.tx;
55475547

@@ -5576,7 +5576,7 @@ impl<SP: Deref> Channel<SP> where
55765576
let counterparty_keys = self.context.build_remote_transaction_keys();
55775577
let mut commitment_stats = self.context.build_commitment_transaction(self.context.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, true, logger);
55785578
if self.context.is_colored() {
5579-
color_commitment(&self.context.channel_id, &self.context.channel_transaction_parameters.funding_outpoint.unwrap(), &mut commitment_stats.tx, &self.context.ldk_data_dir, true)?;
5579+
color_commitment(&self.context, &mut commitment_stats.tx, true)?;
55805580
}
55815581
let counterparty_commitment_txid = commitment_stats.tx.trust().txid();
55825582

@@ -5995,7 +5995,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
59955995
let counterparty_keys = self.context.build_remote_transaction_keys();
59965996
let mut counterparty_initial_commitment_tx = self.context.build_commitment_transaction(self.context.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx;
59975997
if self.context.is_colored() {
5998-
color_commitment(&self.context.channel_id, &self.context.channel_transaction_parameters.funding_outpoint.unwrap(), &mut counterparty_initial_commitment_tx, &self.context.ldk_data_dir, true)?;
5998+
color_commitment(&self.context, &mut counterparty_initial_commitment_tx, true)?;
59995999
}
60006000
match &self.context.holder_signer {
60016001
// TODO (taproot|arik): move match into calling method for Taproot
@@ -6727,7 +6727,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
67276727
let keys = self.context.build_holder_transaction_keys(self.context.cur_holder_commitment_transaction_number);
67286728
let mut initial_commitment_tx = self.context.build_commitment_transaction(self.context.cur_holder_commitment_transaction_number, &keys, true, false, logger).tx;
67296729
if self.context.is_colored() {
6730-
color_commitment(&self.context.channel_id, &self.context.channel_transaction_parameters.funding_outpoint.unwrap(), &mut initial_commitment_tx, &self.context.ldk_data_dir, false)?;
6730+
color_commitment(&self.context, &mut initial_commitment_tx, false)?;
67316731
}
67326732
{
67336733
let trusted_tx = initial_commitment_tx.trust();
@@ -6744,7 +6744,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
67446744
let counterparty_keys = self.context.build_remote_transaction_keys();
67456745
let mut counterparty_initial_commitment_tx = self.context.build_commitment_transaction(self.context.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx;
67466746
if self.context.is_colored() {
6747-
color_commitment(&self.context.channel_id, &self.context.channel_transaction_parameters.funding_outpoint.unwrap(), &mut counterparty_initial_commitment_tx, &self.context.ldk_data_dir, true)?;
6747+
color_commitment(&self.context, &mut counterparty_initial_commitment_tx, true)?;
67486748
}
67496749

67506750
let counterparty_trusted_tx = counterparty_initial_commitment_tx.trust();

lightning/src/rgb_utils/mod.rs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@
33
pub mod proxy;
44

55
use crate::chain::transaction::OutPoint;
6+
use crate::ln::features::ChannelTypeFeatures;
67
use crate::ln::{PaymentHash, ChannelId};
7-
use crate::ln::chan_utils::{BuiltCommitmentTransaction, ClosingTransaction, CommitmentTransaction, HTLCOutputInCommitment};
8+
use crate::ln::chan_utils::{BuiltCommitmentTransaction, ClosingTransaction, CommitmentTransaction, HTLCOutputInCommitment, get_counterparty_payment_script};
89
use crate::ln::channelmanager::{ChannelDetails, MsgHandleErrInternal};
9-
use crate::ln::channel::ChannelError;
10+
use crate::ln::channel::{ChannelError, ChannelContext};
11+
use crate::sign::SignerProvider;
1012

1113
use alloc::collections::BTreeMap;
1214
use amplify::none;
1315
use bitcoin::{TxOut, Script};
1416
use bitcoin::blockdata::transaction::Transaction;
1517
use bitcoin::hashes::hex::ToHex;
1618
use bitcoin::psbt::PartiallySignedTransaction;
19+
use bitcoin::secp256k1::PublicKey;
1720
use bitcoin_30::psbt::PartiallySignedTransaction as RgbPsbt;
1821
use bitcoin_30::hashes::Hash;
1922
use bp::Outpoint as RgbOutpoint;
@@ -38,6 +41,7 @@ use rgbwallet::psbt::{PsbtDbc, RgbExt, RgbInExt};
3841
use rgbwallet::psbt::opret::OutputOpret;
3942
use strict_encoding::{TypeName, FieldName};
4043

44+
use core::ops::Deref;
4145
use std::fs;
4246
use std::convert::TryFrom;
4347
use std::path::{PathBuf, Path};
@@ -128,8 +132,19 @@ pub fn write_rgb_transfer_info(path: &PathBuf, info: &TransferInfo) {
128132
fs::write(path, serialized_info).expect("able to write transfer info file")
129133
}
130134

135+
fn counterparty_output_index(outputs: &Vec<TxOut>, channel_type_features: &ChannelTypeFeatures, payment_key: &PublicKey) -> Option<usize> {
136+
let counterparty_payment_script = get_counterparty_payment_script(channel_type_features, payment_key);
137+
outputs.iter().enumerate()
138+
.find(|(_, out)| out.script_pubkey == counterparty_payment_script)
139+
.map(|(idx, _)| idx)
140+
}
141+
131142
/// Color commitment transaction
132-
pub(crate) fn color_commitment(channel_id: &ChannelId, funding_outpoint: &OutPoint, commitment_tx: &mut CommitmentTransaction, ldk_data_dir: &Path, counterparty: bool) -> Result<(), ChannelError> {
143+
pub(crate) fn color_commitment<SP: Deref>(channel_context: &ChannelContext<SP>, commitment_tx: &mut CommitmentTransaction, counterparty: bool) -> Result<(), ChannelError> where <SP as std::ops::Deref>::Target: SignerProvider {
144+
let channel_id = &channel_context.channel_id;
145+
let funding_outpoint = channel_context.channel_transaction_parameters.funding_outpoint.unwrap();
146+
let ldk_data_dir = channel_context.ldk_data_dir.as_path();
147+
133148
let mut transaction = commitment_tx.clone().built.transaction;
134149
transaction.output.push(TxOut { value: 0, script_pubkey: Script::new_op_return(&[1]) });
135150
let psbt = PartiallySignedTransaction::from_unsigned_tx(transaction.clone()).expect("valid transaction");
@@ -144,14 +159,12 @@ pub(crate) fn color_commitment(channel_id: &ChannelId, funding_outpoint: &OutPoi
144159
let mut rgb_offered_htlc = 0;
145160
let mut rgb_received_htlc = 0;
146161
let mut last_rgb_payment_info = None;
147-
let mut htlc_vouts: Vec<u32> = vec![];
148162
let mut asset_transition_builder = runtime.runtime.transition_builder(rgb_info.contract_id, TypeName::try_from("RGB20").unwrap(), None::<&str>).expect("ok");
149163
let assignment_id = asset_transition_builder
150164
.assignments_type(&FieldName::from("beneficiary")).expect("valid assignment");
151165

152166
for htlc in commitment_tx.htlcs() {
153167
let htlc_vout = htlc.transaction_output_index.unwrap();
154-
htlc_vouts.push(htlc_vout);
155168

156169
let htlc_payment_hash = hex::encode(htlc.payment_hash.0);
157170
let htlc_proxy_id = format!("{chan_id}{htlc_payment_hash}");
@@ -209,19 +222,26 @@ pub(crate) fn color_commitment(channel_id: &ChannelId, funding_outpoint: &OutPoi
209222
(remote_amt, local_amt)
210223
};
211224

212-
let non_htlc_outputs: Vec<(u32, &TxOut)> = transaction.output.iter().enumerate().filter(|(index, _)| !htlc_vouts.contains(&(*index as u32)))
213-
.map(|(index, txout)| (index as u32, txout)).collect();
214-
let (vout_p2wpkh, _) = non_htlc_outputs.iter().find(|(_, txout)| txout.script_pubkey.is_v0_p2wpkh()).unwrap();
215-
let (vout_p2wsh, _) = non_htlc_outputs.iter().find(|(index, _)| index != vout_p2wpkh).unwrap();
225+
let payment_point = if counterparty {
226+
channel_context.get_holder_pubkeys().payment_point
227+
} else {
228+
channel_context.get_counterparty_pubkeys().payment_point
229+
};
230+
let vout_p2wpkh = counterparty_output_index(
231+
&transaction.output,
232+
&channel_context.channel_type,
233+
&payment_point
234+
).unwrap() as u32;
235+
let vout_p2wsh = commitment_tx.trust().revokeable_output_index().unwrap() as u32;
216236

217237
if vout_p2wpkh_amt > 0 {
218-
let seal_p2wpkh = BuilderSeal::Revealed(GraphSeal::with_vout(CloseMethod::OpretFirst, *vout_p2wpkh, STATIC_BLINDING));
238+
let seal_p2wpkh = BuilderSeal::Revealed(GraphSeal::with_vout(CloseMethod::OpretFirst, vout_p2wpkh, STATIC_BLINDING));
219239
beneficiaries.push(seal_p2wpkh);
220240
asset_transition_builder = asset_transition_builder
221241
.add_raw_state_static(assignment_id, seal_p2wpkh, TypedState::Amount(vout_p2wpkh_amt)).expect("ok");
222242
}
223243
if vout_p2wsh_amt > 0 {
224-
let seal_p2wsh = BuilderSeal::Revealed(GraphSeal::with_vout(CloseMethod::OpretFirst, *vout_p2wsh, STATIC_BLINDING));
244+
let seal_p2wsh = BuilderSeal::Revealed(GraphSeal::with_vout(CloseMethod::OpretFirst, vout_p2wsh, STATIC_BLINDING));
225245
beneficiaries.push(seal_p2wsh);
226246
asset_transition_builder = asset_transition_builder
227247
.add_raw_state_static(assignment_id, seal_p2wsh, TypedState::Amount(vout_p2wsh_amt)).expect("ok");

0 commit comments

Comments
 (0)