Skip to content

Commit 21b4452

Browse files
committed
add state to 'simplicity pset update-input'
1 parent a2ae36d commit 21b4452

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

src/bin/hal-simplicity/cmd/simplicity/pset/update_input.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use super::UpdatedPset;
1111

1212
use elements::schnorr::XOnlyPublicKey;
1313
use hal_simplicity::hal_simplicity::taproot_spend_info;
14+
use simplicity::hex::parse::FromHex as _;
1415

1516
pub fn cmd<'a>() -> clap::App<'a, 'a> {
1617
cmd::subcommand("update-input", "Attach UTXO data to a PSET input")
@@ -32,6 +33,13 @@ pub fn cmd<'a>() -> clap::App<'a, 'a> {
3233
.short("c")
3334
.takes_value(true)
3435
.required(false),
36+
cmd::opt(
37+
"state",
38+
"32-byte state commitment to put alongside the program when generating addresess (hex)",
39+
)
40+
.takes_value(true)
41+
.short("s")
42+
.required(false),
3543
// FIXME add merkle path, needed to compute nontrivial control blocks
3644
])
3745
}
@@ -43,8 +51,9 @@ pub fn exec<'a>(matches: &clap::ArgMatches<'a>) {
4351

4452
let internal_key = matches.value_of("internal-key");
4553
let cmr = matches.value_of("cmr");
54+
let state = matches.value_of("state");
4655

47-
match exec_inner(pset_b64, input_idx, input_utxo, internal_key, cmr) {
56+
match exec_inner(pset_b64, input_idx, input_utxo, internal_key, cmr, state) {
4857
Ok(info) => cmd::print_output(matches, &info),
4958
Err(e) => cmd::print_output(matches, &e),
5059
}
@@ -57,6 +66,7 @@ fn exec_inner(
5766
input_utxo: &str,
5867
internal_key: Option<&str>,
5968
cmr: Option<&str>,
69+
state: Option<&str>,
6070
) -> Result<UpdatedPset, Error> {
6171
let mut pset: elements::pset::PartiallySignedTransaction =
6272
pset_b64.parse().result_context("decoding PSET")?;
@@ -87,6 +97,14 @@ fn exec_inner(
8797
.result_context("input UTXO");
8898
}
8999

100+
// FIXME state is meaningless without CMR; should we warn here
101+
// FIXME also should we warn if you don't provide a CMR? seems like if you're calling `simplicity pset update-input`
102+
// you probably have a simplicity program right? maybe we should even provide a --no-cmr flag
103+
let state = state
104+
.map(<[u8; 32]>::from_hex)
105+
.transpose()
106+
.result_context("parsing 32-byte state commitment as hex")?;
107+
90108
let mut updated_values = vec![];
91109
if let Some(internal_key) = internal_key {
92110
updated_values.push("tap_internal_key");
@@ -97,7 +115,7 @@ fn exec_inner(
97115
// Guess that the given program is the only Tapleaf. This is the case for addresses
98116
// generated from the web IDE, and from `hal-simplicity simplicity info`, and for
99117
// most "test" scenarios. We need to design an API to handle more general cases.
100-
let spend_info = taproot_spend_info(internal_key, None, cmr);
118+
let spend_info = taproot_spend_info(internal_key, state, cmr);
101119
if spend_info.output_key().as_inner().serialize() != input_utxo.script_pubkey[2..] {
102120
// If our guess was wrong, at least error out..
103121
return Err(format!("CMR and internal key imply output key {}, which does not match input scriptPubKey {}", spend_info.output_key().as_inner(), input_utxo.script_pubkey))

0 commit comments

Comments
 (0)