diff --git a/test-cli/open-anchor.c b/test-cli/open-anchor.c new file mode 100644 index 000000000..8be4e47ce --- /dev/null +++ b/test-cli/open-anchor.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include "lightning.pb-c.h" +#include "bitcoin/base58.h" +#include "pkt.h" +#include "funding.h" +#include "bitcoin/script.h" +#include "bitcoin/address.h" +#include "bitcoin/tx.h" +#include "bitcoin/pubkey.h" +#include "bitcoin/privkey.h" +#include "bitcoin/shadouble.h" +#include "commit_tx.h" +#include "protobuf_convert.h" +#include "find_p2sh_out.h" +#include +#include +#include "opt_bits.h" + +int main(int argc, char *argv[]) +{ + const tal_t *ctx = tal_arr(NULL, char, 0); + struct bitcoin_tx *anchor, *commit; + OpenChannel *o1, *o2; + OpenAnchor oa = OPEN_ANCHOR__INIT; + struct sha256_double txid; + struct sha256 rhash; + struct pkt *pkt; + uint64_t to_them, to_us; + struct pubkey pubkey1, pubkey2; + struct privkey privkey; + struct signature sig; + bool testnet; + u8 *redeemscript; + + err_set_progname(argv[0]); + + opt_register_noarg("--help|-h", opt_usage_and_exit, + " \n" + "A test program to output open_anchor message on stdout.", + "Print this message."); + + opt_parse(&argc, argv, opt_log_stderr_exit); + + if (argc != 5) + opt_usage_exit_fail("Expected 4 arguments"); + + o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open; + o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; + if (!proto_to_pubkey(o2->commit_key, &pubkey2)) + errx(1, "Invalid o2 commit_key"); + + anchor = bitcoin_tx_from_file(ctx, argv[3]); + bitcoin_txid(anchor, &txid); + + if (!key_from_base58(argv[4], strlen(argv[4]), &testnet, &privkey, &pubkey1)) + errx(1, "Invalid private key '%s'", argv[4]); + if (!testnet) + errx(1, "Private key '%s' not on testnet!", argv[4]); + + /* Figure out which output we want for commit tx. */ + redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); + oa.txid = sha256_to_proto(ctx, &txid.sha); + oa.output_index = find_p2sh_out(anchor, redeemscript); + oa.amount = anchor->output[oa.output_index].amount; + + /* Figure out initial how much to us, how much to them. */ + if (!initial_funding(o1, o2, &oa, commit_fee(o1, o2), &to_us, &to_them)) + errx(1, "Invalid open combination (need 1 anchor offer)"); + + /* Now, create signature for their commitment tx. */ + proto_to_sha256(o2->revocation_hash, &rhash); + commit = create_commit_tx(ctx, o2, o1, &oa, &rhash, to_them, to_us); + + sign_tx_input(ctx, commit, 0, redeemscript, tal_count(redeemscript), + &privkey, &pubkey1, &sig); + + oa.commit_sig = signature_to_proto(ctx, &sig); + pkt = open_anchor_pkt(ctx, &oa); + if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt))) + err(1, "Writing out packet"); + + tal_free(ctx); + return 0; +}