Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More psbt cleanups #3958

Merged
merged 3 commits into from
Aug 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 72 additions & 6 deletions bitcoin/psbt.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ static struct wally_psbt *init_psbt(const tal_t *ctx, size_t num_inputs, size_t
return tal_steal(ctx, psbt);
}

struct wally_psbt *create_psbt(const tal_t *ctx, size_t num_inputs, size_t num_outputs)
struct wally_psbt *create_psbt(const tal_t *ctx, size_t num_inputs, size_t num_outputs, u32 locktime)
{
int wally_err;
struct wally_tx *wtx;
struct wally_psbt *psbt;

if (wally_tx_init_alloc(WALLY_TX_VERSION_2, 0, num_inputs, num_outputs, &wtx) != WALLY_OK)
if (wally_tx_init_alloc(WALLY_TX_VERSION_2, locktime, num_inputs, num_outputs, &wtx) != WALLY_OK)
abort();

psbt = init_psbt(ctx, num_inputs, num_outputs);
Expand Down Expand Up @@ -108,10 +108,17 @@ struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt,

struct wally_psbt_input *psbt_append_input(struct wally_psbt *psbt,
const struct bitcoin_txid *txid,
u32 outnum, u32 sequence)
u32 outnum, u32 sequence,
const u8 *scriptSig,
struct amount_sat amount,
const u8 *scriptPubkey,
const u8 *input_wscript,
const u8 *redeemscript)
{
struct wally_tx_input *tx_in;
struct wally_psbt_input *input;
size_t input_num = psbt->num_inputs;
const u32 flags = WALLY_PSBT_FLAG_NON_FINAL; /* Skip script/witness */
int wally_err;

if (chainparams->is_elements) {
if (wally_tx_elements_input_init_alloc(txid->shad.sha.u.u8,
Expand All @@ -132,9 +139,68 @@ struct wally_psbt_input *psbt_append_input(struct wally_psbt *psbt,
abort();
}

input = psbt_add_input(psbt, tx_in, psbt->num_inputs);
wally_err = wally_psbt_add_input_at(psbt, input_num, flags, tx_in);
assert(wally_err == WALLY_OK);
wally_tx_input_free(tx_in);
return input;

if (input_wscript) {
/* Add the prev output's data into the PSBT struct */
if (is_elements(chainparams)) {
struct amount_asset asset;
/*FIXME: persist asset tags */
asset = amount_sat_to_asset(
&amount,
chainparams->fee_asset_tag);
psbt_elements_input_init_witness(psbt, input_num,
input_wscript,
&asset, NULL);
} else
psbt_input_set_prev_utxo_wscript(psbt, input_num,
input_wscript,
amount);
} else if (scriptPubkey) {
if (is_p2wsh(scriptPubkey, NULL) ||
is_p2wpkh(scriptPubkey, NULL) ||
/* FIXME: assert that p2sh inputs are
* witness/are accompanied by a
* redeemscript+witnessscript */
is_p2sh(scriptPubkey, NULL)) {
/* the only way to get here currently with
* a p2sh script is via a p2sh-p2wpkh script
* that we've created ...*/
/* BIP0174:
* ** Value: The entire transaction output in
* network serialization which the
* current input spends from.
* This should only be present for
* inputs which spend segwit outputs,
* including P2SH embedded ones.
*/
if (is_elements(chainparams)) {
struct amount_asset asset;
/*FIXME: persist asset tags */
asset = amount_sat_to_asset(
&amount,
chainparams->fee_asset_tag);
/* FIXME: persist nonces */
psbt_elements_input_init(psbt, input_num,
scriptPubkey,
&asset, NULL);
} else
psbt_input_set_prev_utxo(psbt, input_num,
scriptPubkey,
amount);
}
}

if (redeemscript) {
wally_err = wally_psbt_input_set_redeem_script(&psbt->inputs[input_num],
redeemscript,
tal_bytelen(redeemscript));
assert(wally_err == WALLY_OK);
}

return &psbt->inputs[input_num];
}

void psbt_rm_input(struct wally_psbt *psbt,
Expand Down
11 changes: 9 additions & 2 deletions bitcoin/psbt.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ void psbt_destroy(struct wally_psbt *psbt);
* @ctx - allocation context
* @num_inputs - number of inputs to allocate
* @num_outputs - number of outputs to allocate
* @locktime - locktime for the transaction
*/
struct wally_psbt *create_psbt(const tal_t *ctx, size_t num_inputs, size_t num_outputs);
struct wally_psbt *create_psbt(const tal_t *ctx, size_t num_inputs, size_t num_outputs, u32 locktime);

/*
* new_psbt - Create a PSBT, using the passed in tx
Expand Down Expand Up @@ -74,9 +75,15 @@ struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt,
struct wally_tx_input *input,
size_t insert_at);

/* One stop shop for adding an input + metadata to a PSBT */
struct wally_psbt_input *psbt_append_input(struct wally_psbt *psbt,
const struct bitcoin_txid *txid,
u32 outnum, u32 sequence);
u32 outnum, u32 sequence,
const u8 *scriptSig,
struct amount_sat amount,
const u8 *scriptPubkey,
const u8 *input_wscript,
const u8 *redeemscript);

void psbt_rm_input(struct wally_psbt *psbt,
size_t remove_at);
Expand Down
87 changes: 9 additions & 78 deletions bitcoin/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,88 +187,19 @@ int bitcoin_tx_add_input(struct bitcoin_tx *tx, const struct bitcoin_txid *txid,
struct amount_sat amount, const u8 *scriptPubkey,
const u8 *input_wscript)
{
struct wally_tx_input *input;
int wally_err;
size_t i;

assert(tx->wtx != NULL);
i = tx->wtx->num_inputs;
if (chainparams->is_elements)
wally_err =
wally_tx_elements_input_init_alloc(txid->shad.sha.u.u8,
sizeof(struct bitcoin_txid),
outnum, sequence,
scriptSig, tal_bytelen(scriptSig),
NULL /* Empty witness stack */,
NULL, 0, NULL, 0,
NULL, 0, NULL, 0,
NULL, 0, NULL, 0,
NULL, &input);
else
wally_err = wally_tx_input_init_alloc(txid->shad.sha.u.u8,
sizeof(struct bitcoin_txid),
outnum, sequence,
scriptSig, tal_bytelen(scriptSig),
NULL /* Empty witness stack */,
&input);
int input_num = tx->wtx->num_inputs;

psbt_append_input(tx->psbt, txid, outnum, sequence, scriptSig,
amount, scriptPubkey, input_wscript, NULL);
wally_err = wally_tx_add_input(tx->wtx,
&tx->psbt->tx->inputs[input_num]);
assert(wally_err == WALLY_OK);
wally_tx_add_input(tx->wtx, input);
psbt_add_input(tx->psbt, input, i);

if (input_wscript) {
/* Add the prev output's data into the PSBT struct */
if (is_elements(chainparams)) {
struct amount_asset asset;
/*FIXME: persist asset tags */
asset = amount_sat_to_asset(
&amount,
chainparams->fee_asset_tag);
psbt_elements_input_init_witness(tx->psbt, i,
input_wscript,
&asset, NULL);
} else
psbt_input_set_prev_utxo_wscript(tx->psbt, i,
input_wscript,
amount);
} else if (scriptPubkey) {
if (is_p2wsh(scriptPubkey, NULL) ||
is_p2wpkh(scriptPubkey, NULL) ||
/* FIXME: assert that p2sh inputs are
* witness/are accompanied by a
* redeemscript+witnessscript */
is_p2sh(scriptPubkey, NULL)) {
/* the only way to get here currently with
* a p2sh script is via a p2sh-p2wpkh script
* that we've created ...*/
/* BIP0174:
* ** Value: The entire transaction output in
* network serialization which the
* current input spends from.
* This should only be present for
* inputs which spend segwit outputs,
* including P2SH embedded ones.
*/
if (is_elements(chainparams)) {
struct amount_asset asset;
/*FIXME: persist asset tags */
asset = amount_sat_to_asset(
&amount,
chainparams->fee_asset_tag);
/* FIXME: persist nonces */
psbt_elements_input_init(tx->psbt, i,
scriptPubkey,
&asset, NULL);
} else
psbt_input_set_prev_utxo(tx->psbt, i,
scriptPubkey,
amount);
}
}
/* scriptsig isn't actually store in psbt input, so add that now */
wally_tx_set_input_script(tx->wtx, input_num,
scriptSig, tal_bytelen(scriptSig));

wally_tx_input_free(input);

return i;
return input_num;
}

bool bitcoin_tx_check(const struct bitcoin_tx *tx)
Expand Down
6 changes: 3 additions & 3 deletions common/psbt_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static const u8 *linearize_input(const tal_t *ctx,
const struct wally_psbt_input *in,
const struct wally_tx_input *tx_in)
{
struct wally_psbt *psbt = create_psbt(NULL, 1, 0);
struct wally_psbt *psbt = create_psbt(NULL, 1, 0, 0);
size_t byte_len;

if (wally_tx_add_input(psbt->tx, tx_in) != WALLY_OK)
Expand All @@ -87,13 +87,13 @@ static const u8 *linearize_output(const tal_t *ctx,
const struct wally_psbt_output *out,
const struct wally_tx_output *tx_out)
{
struct wally_psbt *psbt = create_psbt(NULL, 1, 1);
struct wally_psbt *psbt = create_psbt(NULL, 1, 1, 0);
size_t byte_len;
struct bitcoin_txid txid;

/* Add a 'fake' input so this will linearize the tx */
memset(&txid, 0, sizeof(txid));
psbt_append_input(psbt, &txid, 0, 0);
psbt_append_input(psbt, &txid, 0, 0, NULL, AMOUNT_SAT(0), NULL, NULL, NULL);

if (wally_tx_add_output(psbt->tx, tx_out) != WALLY_OK)
abort();
Expand Down
5 changes: 3 additions & 2 deletions common/test/run-psbt_diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ static void add_in_out_with_serial(struct wally_psbt *psbt,
struct wally_psbt_output *out;

memset(&txid, default_value, sizeof(txid));
in = psbt_append_input(psbt, &txid, default_value, default_value);
in = psbt_append_input(psbt, &txid, default_value, default_value,
NULL, AMOUNT_SAT(0), NULL, NULL, NULL);
if (!in)
abort();
psbt_input_add_serial_id(in, serial_id);
Expand All @@ -127,7 +128,7 @@ int main(int argc, const char *argv[])
chainparams = chainparams_for_network("bitcoin");

/* Create two psbts! */
end = create_psbt(tmpctx, 1, 1);
end = create_psbt(tmpctx, 1, 1, 0);
if (wally_psbt_clone_alloc(end, flags, &start) != WALLY_OK)
abort();
diff_count(start, end, 0, 0);
Expand Down