mirror of
https://github.com/lightninglabs/loop
synced 2024-11-06 03:20:38 +00:00
sweepbatcher: factor out method musig2sign
It is long and is going to be even longer and hard to keep it inside a loop.
This commit is contained in:
parent
822e4746c1
commit
3d5b7db1f7
@ -896,11 +896,9 @@ func (b *batch) publishBatchCoop(ctx context.Context) (btcutil.Amount,
|
|||||||
return fee, err, false
|
return fee, err, false
|
||||||
}
|
}
|
||||||
|
|
||||||
prevOutputFetcher := txscript.NewMultiPrevOutFetcher(prevOuts)
|
|
||||||
|
|
||||||
// Attempt to cooperatively sign the batch tx with the server.
|
// Attempt to cooperatively sign the batch tx with the server.
|
||||||
err = b.coopSignBatchTx(
|
err = b.coopSignBatchTx(
|
||||||
ctx, packet, sweeps, prevOutputFetcher, prevOuts, psbtBuf,
|
ctx, packet, sweeps, prevOuts, psbtBuf.Bytes(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fee, err, false
|
return fee, err, false
|
||||||
@ -942,24 +940,44 @@ func (b *batch) debugLogTx(msg string, tx *wire.MsgTx) {
|
|||||||
// coopSignBatchTx collects the necessary signatures from the server in order
|
// coopSignBatchTx collects the necessary signatures from the server in order
|
||||||
// to cooperatively sweep the funds.
|
// to cooperatively sweep the funds.
|
||||||
func (b *batch) coopSignBatchTx(ctx context.Context, packet *psbt.Packet,
|
func (b *batch) coopSignBatchTx(ctx context.Context, packet *psbt.Packet,
|
||||||
sweeps []sweep, prevOutputFetcher *txscript.MultiPrevOutFetcher,
|
sweeps []sweep, prevOuts map[wire.OutPoint]*wire.TxOut,
|
||||||
prevOuts map[wire.OutPoint]*wire.TxOut, psbtBuf bytes.Buffer) error {
|
psbt []byte) error {
|
||||||
|
|
||||||
for i, sweep := range sweeps {
|
for i, sweep := range sweeps {
|
||||||
sweep := sweep
|
sweep := sweep
|
||||||
|
|
||||||
sigHashes := txscript.NewTxSigHashes(
|
finalSig, err := b.musig2sign(
|
||||||
packet.UnsignedTx, prevOutputFetcher,
|
ctx, i, sweep, packet.UnsignedTx, prevOuts, psbt,
|
||||||
)
|
|
||||||
|
|
||||||
sigHash, err := txscript.CalcTaprootSignatureHash(
|
|
||||||
sigHashes, txscript.SigHashDefault, packet.UnsignedTx,
|
|
||||||
i, prevOutputFetcher,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
packet.UnsignedTx.TxIn[i].Witness = wire.TxWitness{
|
||||||
|
finalSig,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// musig2sign signs one sweep using musig2.
|
||||||
|
func (b *batch) musig2sign(ctx context.Context, inputIndex int, sweep sweep,
|
||||||
|
unsignedTx *wire.MsgTx, prevOuts map[wire.OutPoint]*wire.TxOut,
|
||||||
|
psbt []byte) ([]byte, error) {
|
||||||
|
|
||||||
|
prevOutputFetcher := txscript.NewMultiPrevOutFetcher(prevOuts)
|
||||||
|
|
||||||
|
sigHashes := txscript.NewTxSigHashes(unsignedTx, prevOutputFetcher)
|
||||||
|
|
||||||
|
sigHash, err := txscript.CalcTaprootSignatureHash(
|
||||||
|
sigHashes, txscript.SigHashDefault, unsignedTx, inputIndex,
|
||||||
|
prevOutputFetcher,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
signers [][]byte
|
signers [][]byte
|
||||||
muSig2Version input.MuSig2Version
|
muSig2Version input.MuSig2Version
|
||||||
@ -983,20 +1001,18 @@ func (b *batch) coopSignBatchTx(ctx context.Context, packet *psbt.Packet,
|
|||||||
|
|
||||||
htlcScript, ok := sweep.htlc.HtlcScript.(*swap.HtlcScriptV3)
|
htlcScript, ok := sweep.htlc.HtlcScript.(*swap.HtlcScriptV3)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("invalid htlc script version")
|
return nil, fmt.Errorf("invalid htlc script version")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we're creating a local MuSig2 session using the receiver
|
// Now we're creating a local MuSig2 session using the receiver key's
|
||||||
// key's key locator and the htlc's root hash.
|
// key locator and the htlc's root hash.
|
||||||
|
keyLocator := &sweep.htlcKeys.ClientScriptKeyLocator
|
||||||
musig2SessionInfo, err := b.signerClient.MuSig2CreateSession(
|
musig2SessionInfo, err := b.signerClient.MuSig2CreateSession(
|
||||||
ctx, muSig2Version,
|
ctx, muSig2Version, keyLocator, signers,
|
||||||
&sweep.htlcKeys.ClientScriptKeyLocator, signers,
|
lndclient.MuSig2TaprootTweakOpt(htlcScript.RootHash[:], false),
|
||||||
lndclient.MuSig2TaprootTweakOpt(
|
|
||||||
htlcScript.RootHash[:], false,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("signerClient.MuSig2CreateSession "+
|
return nil, fmt.Errorf("signerClient.MuSig2CreateSession "+
|
||||||
"failed: %w", err)
|
"failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1007,11 +1023,10 @@ func (b *batch) coopSignBatchTx(ctx context.Context, packet *psbt.Packet,
|
|||||||
serverNonce, serverSig, err := b.muSig2SignSweep(
|
serverNonce, serverSig, err := b.muSig2SignSweep(
|
||||||
ctx, sweep.protocolVersion, sweep.swapHash,
|
ctx, sweep.protocolVersion, sweep.swapHash,
|
||||||
sweep.swapInvoicePaymentAddr,
|
sweep.swapInvoicePaymentAddr,
|
||||||
musig2SessionInfo.PublicNonce[:], psbtBuf.Bytes(),
|
musig2SessionInfo.PublicNonce[:], psbt, prevOuts,
|
||||||
prevOuts,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var serverPublicNonce [musig2.PubNonceSize]byte
|
var serverPublicNonce [musig2.PubNonceSize]byte
|
||||||
@ -1024,12 +1039,12 @@ func (b *batch) coopSignBatchTx(ctx context.Context, packet *psbt.Packet,
|
|||||||
[][musig2.PubNonceSize]byte{serverPublicNonce},
|
[][musig2.PubNonceSize]byte{serverPublicNonce},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanity check that we have all the nonces.
|
// Sanity check that we have all the nonces.
|
||||||
if !haveAllNonces {
|
if !haveAllNonces {
|
||||||
return fmt.Errorf("invalid MuSig2 session: " +
|
return nil, fmt.Errorf("invalid MuSig2 session: " +
|
||||||
"nonces missing")
|
"nonces missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1042,7 +1057,7 @@ func (b *batch) coopSignBatchTx(ctx context.Context, packet *psbt.Packet,
|
|||||||
ctx, musig2SessionInfo.SessionID, digest, false,
|
ctx, musig2SessionInfo.SessionID, digest, false,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now combine the partial signatures to use the final combined
|
// Now combine the partial signatures to use the final combined
|
||||||
@ -1051,29 +1066,22 @@ func (b *batch) coopSignBatchTx(ctx context.Context, packet *psbt.Packet,
|
|||||||
ctx, musig2SessionInfo.SessionID, [][]byte{serverSig},
|
ctx, musig2SessionInfo.SessionID, [][]byte{serverSig},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !haveAllSigs {
|
if !haveAllSigs {
|
||||||
return fmt.Errorf("failed to combine signatures")
|
return nil, fmt.Errorf("failed to combine signatures")
|
||||||
}
|
}
|
||||||
|
|
||||||
// To be sure that we're good, parse and validate that the
|
// To be sure that we're good, parse and validate that the
|
||||||
// combined signature is indeed valid for the sig hash and the
|
// combined signature is indeed valid for the sig hash and the
|
||||||
// internal pubkey.
|
// internal pubkey.
|
||||||
err = b.verifySchnorrSig(
|
err = b.verifySchnorrSig(htlcScript.TaprootKey, sigHash, finalSig)
|
||||||
htlcScript.TaprootKey, sigHash, finalSig,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
packet.UnsignedTx.TxIn[i].Witness = wire.TxWitness{
|
return finalSig, nil
|
||||||
finalSig,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateRbfRate updates the fee rate we should use for the new batch
|
// updateRbfRate updates the fee rate we should use for the new batch
|
||||||
|
Loading…
Reference in New Issue
Block a user