lnwallet: convert CommitSpendRevoke+CommitSpendNoDelay to use Signer

This commit converts the rearming two commitment spend functions to use
the lnwallet.Signer interface directly rather than manually manage
private keys during the signing process. This commit is in preparation
for implementation of fully automated revoked uncooperative closure
detection and retribution.
This commit is contained in:
Olaoluwa Osuntokun 2016-11-18 15:23:26 -08:00
parent d98cac432b
commit c81e0a3ebb
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
3 changed files with 48 additions and 23 deletions

View File

@ -70,7 +70,17 @@ func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx, signDesc *SignDescriptor) ([]
return sig[:len(sig)-1], nil return sig[:len(sig)-1], nil
} }
func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx, signDesc *SignDescriptor) (*InputScript, error) { func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx, signDesc *SignDescriptor) (*InputScript, error) {
return nil, nil
witnessScript, err := txscript.WitnessScript(tx, signDesc.SigHashes,
signDesc.InputIndex, signDesc.Output.Value, signDesc.Output.PkScript,
txscript.SigHashAll, m.key, true)
if err != nil {
return nil, err
}
return &InputScript{
Witness: witnessScript,
}, nil
} }
type mockNotfier struct { type mockNotfier struct {

View File

@ -639,16 +639,13 @@ func CommitSpendTimeout(signer Signer, signDesc *SignDescriptor,
return witnessStack, nil return witnessStack, nil
} }
// commitSpendRevoke constructs a valid witness allowing a node to sweep the // CommitSpendRevoke constructs a valid witness allowing a node to sweep the
// settled output of a malicious counter-party who broadcasts a revoked // settled output of a malicious counter-party who broadcasts a revoked
// commitment transaction. // commitment transaction.
func commitSpendRevoke(commitScript []byte, outputAmt btcutil.Amount, func CommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
revocationPriv *btcec.PrivateKey, sweepTx *wire.MsgTx) (wire.TxWitness, error) { sweepTx *wire.MsgTx) (wire.TxWitness, error) {
hashCache := txscript.NewTxSigHashes(sweepTx) sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
sweepSig, err := txscript.RawTxInWitnessSignature(
sweepTx, hashCache, 0, int64(outputAmt), commitScript,
txscript.SigHashAll, revocationPriv)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -656,29 +653,26 @@ func commitSpendRevoke(commitScript []byte, outputAmt btcutil.Amount,
// Place a 1 as the first item in the evaluated witness stack to // Place a 1 as the first item in the evaluated witness stack to
// force script execution to the revocation clause. // force script execution to the revocation clause.
witnessStack := wire.TxWitness(make([][]byte, 3)) witnessStack := wire.TxWitness(make([][]byte, 3))
witnessStack[0] = sweepSig witnessStack[0] = append(sweepSig, byte(txscript.SigHashAll))
witnessStack[1] = []byte{1} witnessStack[1] = []byte{1}
witnessStack[2] = commitScript witnessStack[2] = signDesc.WitnessScript
return witnessStack, nil return witnessStack, nil
} }
// commitSpendNoDelay constructs a valid witness allowing a node to spend their // CommitSpendNoDelay constructs a valid witness allowing a node to spend their
// settled no-delay output on the counter-party's commitment transaction. // settled no-delay output on the counter-party's commitment transaction.
func commitSpendNoDelay(commitScript []byte, outputAmt btcutil.Amount, func CommitSpendNoDelay(signer Signer, signDesc *SignDescriptor,
commitPriv *btcec.PrivateKey, sweepTx *wire.MsgTx) (wire.TxWitness, error) { sweepTx *wire.MsgTx) (wire.TxWitness, error) {
// This is just a regular p2wkh spend which looks something like: // This is just a regular p2wkh spend which looks something like:
// * witness: <sig> <pubkey> // * witness: <sig> <pubkey>
hashCache := txscript.NewTxSigHashes(sweepTx) inputScript, err := signer.ComputeInputScript(sweepTx, signDesc)
witness, err := txscript.WitnessScript(sweepTx, hashCache, 0,
int64(outputAmt), commitScript, txscript.SigHashAll,
commitPriv, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return wire.TxWitness(witness), nil return wire.TxWitness(inputScript.Witness), nil
} }
// DeriveRevocationPubkey derives the revocation public key given the // DeriveRevocationPubkey derives the revocation public key given the

View File

@ -107,11 +107,21 @@ func TestCommitmentSpendValidation(t *testing.T) {
} }
// Next, we'll test bob spending with the derived revocation key to // Next, we'll test bob spending with the derived revocation key to
// simulate the scenario when alice broadcasts this commitmen // simulate the scenario when alice broadcasts this commitment
// transaction after it's been revoked. // transaction after it's been revoked.
revokePrivKey := DeriveRevocationPrivKey(bobKeyPriv, revocationPreimage) revokePrivKey := DeriveRevocationPrivKey(bobKeyPriv, revocationPreimage)
bobWitnessSpend, err := commitSpendRevoke(delayScript, channelBalance, bobRevokeSigner := &mockSigner{revokePrivKey}
revokePrivKey, sweepTx) signDesc = &SignDescriptor{
WitnessScript: delayScript,
SigHashes: txscript.NewTxSigHashes(sweepTx),
Output: &wire.TxOut{
Value: int64(channelBalance),
},
HashType: txscript.SigHashAll,
InputIndex: 0,
}
bobWitnessSpend, err := CommitSpendRevoke(bobRevokeSigner, signDesc,
sweepTx)
if err != nil { if err != nil {
t.Fatalf("unable to generate revocation witness: %v", err) t.Fatalf("unable to generate revocation witness: %v", err)
} }
@ -128,12 +138,23 @@ func TestCommitmentSpendValidation(t *testing.T) {
// Finally, we test bob sweeping his output as normal in the case that // Finally, we test bob sweeping his output as normal in the case that
// alice broadcasts this commitment transaction. // alice broadcasts this commitment transaction.
bobSigner := &mockSigner{bobKeyPriv}
bobScriptp2wkh, err := commitScriptUnencumbered(bobKeyPub) bobScriptp2wkh, err := commitScriptUnencumbered(bobKeyPub)
if err != nil { if err != nil {
t.Fatalf("unable to create bob p2wkh script: %v", err) t.Fatalf("unable to create bob p2wkh script: %v", err)
} }
bobRegularSpend, err := commitSpendNoDelay(bobScriptp2wkh, signDesc = &SignDescriptor{
channelBalance, bobKeyPriv, sweepTx) WitnessScript: bobScriptp2wkh,
SigHashes: txscript.NewTxSigHashes(sweepTx),
Output: &wire.TxOut{
Value: int64(channelBalance),
PkScript: bobScriptp2wkh,
},
HashType: txscript.SigHashAll,
InputIndex: 0,
}
bobRegularSpend, err := CommitSpendNoDelay(bobSigner, signDesc,
sweepTx)
if err != nil { if err != nil {
t.Fatalf("unable to create bob regular spend: %v", err) t.Fatalf("unable to create bob regular spend: %v", err)
} }