elements icon indicating copy to clipboard operation
elements copied to clipboard

signrawtransactionwithwallet seems broken with taproot descriptor wallets

Open stevenroose opened this issue 2 years ago • 1 comments

I'm trying to make a manual pegout (sendtomainchain doesn't work with descriptor wallets). Creating the tx works and the signing using signtransactionwithwallet seems to work, but then when sending, the signature seems wrong:

let sidechain_info = sidechaind.sidechain_info().unwrap();

let (addr, pk, sk) = bitcoind.create_address(None);
let pak_proof = {
    let sumkey = self.pegout_sumkey(&sk, MASTER_OFFLINE_PUB);
    self.pegout_proof(&sumkey, &pk, MASTER_ONLINE_PUB);
};
let fee = Amount::from_sat(PEGOUT_FEE_SAT);
let amount = state.amount - fee;

let tx = elements::Transaction {
    version: 1,
    lock_time: 0,
    input: vec![elements::TxIn {
        previous_output: state.utxo,
        script_sig: bitcoin::Script::new(),
        sequence: 0,
        witness: Default::default(),
        asset_issuance: Default::default(),
        has_issuance: false,
        is_pegin: false,
    }],
    output: vec![
        elements::TxOut {
            asset: sidechaind.bitcoin_asset(),
            script_pubkey: bitcoin::blockdata::script::Builder::new()
                .push_opcode(bitcoin::blockdata::opcodes::all::OP_RETURN)
                .push_slice(&sidechain_info.parent_blockhash[..])
                .push_slice(&addr.script_pubkey()[..])
                .push_key(&pk)
                .push_slice(&pak_proof)
                .into_script(),
            value: elements::confidential::Value::Explicit(amount.as_sat()),
            nonce: elements::confidential::Nonce::Null,
            witness: Default::default(),
        },
        elements::TxOut {
            asset: sidechaind.bitcoin_asset(),
            script_pubkey: bitcoin::Script::new(),
            value: elements::confidential::Value::Explicit(fee.as_sat()),
            nonce: elements::confidential::Nonce::Null,
            witness: Default::default(),
        },
    ],
};

let (tx_signed, _) = taproot_wallet.sign_tx(&tx);
debug!("Pegout tx {}", elements::encode::serialize(&tx_signed).to_hex());
let txid = taproot_wallet.send_tx(&tx_signed).unwrap();

This results in the following error being returned by the RPC:

Rpc(RpcError { code: -26, message: "non-mandatory-script-verify-flag (Invalid Schnorr signature)", data: None })

stevenroose avatar Dec 13 '21 14:12 stevenroose

I am surprised that this gets as far as it does, given that 0.21 does not have taproot wallet support.

apoelstra avatar Dec 22 '21 22:12 apoelstra