lnwallet: update to genRemoteHtlcSigJobs to generate taproot jobs

In this commit, we update the genRemoteHtlcSigJobs function to be able
to generate taproot jobs. We also modify the sigpool to now use a
input.Signature everywhere. This'll allow us to pass around both ECDSA
and Schnorr signatures via the same interface.

We use a tapscript sighash in this case, as all the HTLC spends will
actually be script path spends.
This commit is contained in:
Olaoluwa Osuntokun
2023-01-19 19:21:49 -08:00
parent ca21c4bdb4
commit 5336f03ac6
2 changed files with 49 additions and 19 deletions

View File

@@ -3297,7 +3297,7 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
// If the HTLC isn't dust, then we'll create an empty sign job
// to add to the batch momentarily.
sigJob := SignJob{}
var sigJob SignJob
sigJob.Cancel = cancelChan
sigJob.Resp = make(chan SignJobResp, 1)
@@ -3324,21 +3324,35 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
return nil, nil, err
}
// Construct a full hash cache as we may be signing a segwit v1
// sighash.
txOut := remoteCommitView.txn.TxOut[htlc.remoteOutputIndex]
prevFetcher := txscript.NewCannedPrevOutputFetcher(
txOut.PkScript, int64(htlc.Amount.ToSatoshis()),
)
hashCache := txscript.NewTxSigHashes(sigJob.Tx, prevFetcher)
// Finally, we'll generate a sign descriptor to generate a
// signature to give to the remote party for this commitment
// transaction. Note we use the raw HTLC amount.
txOut := remoteCommitView.txn.TxOut[htlc.remoteOutputIndex]
sigJob.SignDesc = input.SignDescriptor{
KeyDesc: localChanCfg.HtlcBasePoint,
SingleTweak: keyRing.LocalHtlcKeyTweak,
WitnessScript: htlc.theirWitnessScript,
Output: txOut,
HashType: sigHashType,
SigHashes: input.NewTxSigHashesV0Only(sigJob.Tx),
InputIndex: 0,
KeyDesc: localChanCfg.HtlcBasePoint,
SingleTweak: keyRing.LocalHtlcKeyTweak,
WitnessScript: htlc.theirWitnessScript,
Output: txOut,
PrevOutputFetcher: prevFetcher,
HashType: sigHashType,
SigHashes: hashCache,
InputIndex: 0,
}
sigJob.OutputIndex = htlc.remoteOutputIndex
// If this is a taproot channel, then we'll need to set the
// method type to ensure we generate a valid signature.
if chanType.IsTaproot() {
sigJob.SignDesc.SignMethod = input.TaprootScriptSpendSignMethod
}
sigBatch = append(sigBatch, sigJob)
}
for _, htlc := range remoteCommitView.outgoingHTLCs {
@@ -3378,21 +3392,35 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
return nil, nil, err
}
// Construct a full hash cache as we may be signing a segwit v1
// sighash.
txOut := remoteCommitView.txn.TxOut[htlc.remoteOutputIndex]
prevFetcher := txscript.NewCannedPrevOutputFetcher(
txOut.PkScript, int64(htlc.Amount.ToSatoshis()),
)
hashCache := txscript.NewTxSigHashes(sigJob.Tx, prevFetcher)
// Finally, we'll generate a sign descriptor to generate a
// signature to give to the remote party for this commitment
// transaction. Note we use the raw HTLC amount.
txOut := remoteCommitView.txn.TxOut[htlc.remoteOutputIndex]
sigJob.SignDesc = input.SignDescriptor{
KeyDesc: localChanCfg.HtlcBasePoint,
SingleTweak: keyRing.LocalHtlcKeyTweak,
WitnessScript: htlc.theirWitnessScript,
Output: txOut,
HashType: sigHashType,
SigHashes: input.NewTxSigHashesV0Only(sigJob.Tx),
InputIndex: 0,
KeyDesc: localChanCfg.HtlcBasePoint,
SingleTweak: keyRing.LocalHtlcKeyTweak,
WitnessScript: htlc.theirWitnessScript,
Output: txOut,
PrevOutputFetcher: prevFetcher,
HashType: sigHashType,
SigHashes: hashCache,
InputIndex: 0,
}
sigJob.OutputIndex = htlc.remoteOutputIndex
// If this is a taproot channel, then we'll need to set the
// method type to ensure we generate a valid signature.
if chanType.IsTaproot() {
sigJob.SignDesc.SignMethod = input.TaprootScriptSpendSignMethod
}
sigBatch = append(sigBatch, sigJob)
}

View File

@@ -113,8 +113,6 @@ type SignJobResp struct {
Err error
}
// TODO(roasbeef); fix description
// SigPool is a struct that is meant to allow the current channel state
// machine to parallelize all signature generation and verification. This
// struct is needed as _each_ HTLC when creating a commitment transaction
@@ -206,7 +204,11 @@ func (s *SigPool) poolWorker() {
}
}
// Use the sig mapper to go from the input.Signature
// into the serialized lnwire.Sig that we'll send
// across the wire.
sig, err := lnwire.NewSigFromSignature(rawSig)
select {
case sigMsg.Resp <- SignJobResp{
Sig: sig,