multi: move Input interface and related code

This commit is a step to split the lnwallet package. It puts the Input
interface and implementations in a separate package along with all their
dependencies from lnwallet.
This commit is contained in:
Joost Jager
2019-01-16 15:47:43 +01:00
parent 667474db75
commit 9e012ecc93
66 changed files with 811 additions and 689 deletions

View File

@@ -6,19 +6,17 @@ import (
"crypto/sha256"
"encoding/binary"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"os"
"sync"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/shachain"
@@ -143,7 +141,7 @@ func CreateTestChannels() (*LightningChannel, *LightningChannel, func(), error)
MaxPendingAmount: lnwire.NewMSatFromSatoshis(channelCapacity),
ChanReserve: channelCapacity / 100,
MinHTLC: 0,
MaxAcceptedHtlcs: MaxHTLCNumber / 2,
MaxAcceptedHtlcs: input.MaxHTLCNumber / 2,
CsvDelay: uint16(csvTimeoutAlice),
},
MultiSigKey: keychain.KeyDescriptor{
@@ -168,7 +166,7 @@ func CreateTestChannels() (*LightningChannel, *LightningChannel, func(), error)
MaxPendingAmount: lnwire.NewMSatFromSatoshis(channelCapacity),
ChanReserve: channelCapacity / 100,
MinHTLC: 0,
MaxAcceptedHtlcs: MaxHTLCNumber / 2,
MaxAcceptedHtlcs: input.MaxHTLCNumber / 2,
CsvDelay: uint16(csvTimeoutBob),
},
MultiSigKey: keychain.KeyDescriptor{
@@ -197,7 +195,7 @@ func CreateTestChannels() (*LightningChannel, *LightningChannel, func(), error)
if err != nil {
return nil, nil, nil, err
}
bobCommitPoint := ComputeCommitmentPoint(bobFirstRevoke[:])
bobCommitPoint := input.ComputeCommitmentPoint(bobFirstRevoke[:])
aliceRoot, err := chainhash.NewHash(aliceKeys[0].Serialize())
if err != nil {
@@ -208,7 +206,7 @@ func CreateTestChannels() (*LightningChannel, *LightningChannel, func(), error)
if err != nil {
return nil, nil, nil, err
}
aliceCommitPoint := ComputeCommitmentPoint(aliceFirstRevoke[:])
aliceCommitPoint := input.ComputeCommitmentPoint(aliceFirstRevoke[:])
aliceCommitTx, bobCommitTx, err := CreateCommitmentTxns(channelBal,
channelBal, &aliceCfg, &bobCfg, aliceCommitPoint, bobCommitPoint,
@@ -300,8 +298,8 @@ func CreateTestChannels() (*LightningChannel, *LightningChannel, func(), error)
Packager: channeldb.NewChannelPackager(shortChanID),
}
aliceSigner := &mockSigner{privkeys: aliceKeys}
bobSigner := &mockSigner{privkeys: bobKeys}
aliceSigner := &input.MockSigner{Privkeys: aliceKeys}
bobSigner := &input.MockSigner{Privkeys: bobKeys}
pCache := &mockPreimageCache{
// hash -> preimage
@@ -389,118 +387,6 @@ func initRevocationWindows(chanA, chanB *LightningChannel) error {
return nil
}
// mockSigner is a simple implementation of the Signer interface. Each one has
// a set of private keys in a slice and can sign messages using the appropriate
// one.
type mockSigner struct {
privkeys []*btcec.PrivateKey
netParams *chaincfg.Params
}
func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx, signDesc *SignDescriptor) ([]byte, error) {
pubkey := signDesc.KeyDesc.PubKey
switch {
case signDesc.SingleTweak != nil:
pubkey = TweakPubKeyWithTweak(pubkey, signDesc.SingleTweak)
case signDesc.DoubleTweak != nil:
pubkey = DeriveRevocationPubkey(pubkey, signDesc.DoubleTweak.PubKey())
}
hash160 := btcutil.Hash160(pubkey.SerializeCompressed())
privKey := m.findKey(hash160, signDesc.SingleTweak, signDesc.DoubleTweak)
if privKey == nil {
return nil, fmt.Errorf("Mock signer does not have key")
}
sig, err := txscript.RawTxInWitnessSignature(tx, signDesc.SigHashes,
signDesc.InputIndex, signDesc.Output.Value, signDesc.WitnessScript,
txscript.SigHashAll, privKey)
if err != nil {
return nil, err
}
return sig[:len(sig)-1], nil
}
func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx, signDesc *SignDescriptor) (*InputScript, error) {
scriptType, addresses, _, err := txscript.ExtractPkScriptAddrs(
signDesc.Output.PkScript, m.netParams)
if err != nil {
return nil, err
}
switch scriptType {
case txscript.PubKeyHashTy:
privKey := m.findKey(addresses[0].ScriptAddress(), signDesc.SingleTweak,
signDesc.DoubleTweak)
if privKey == nil {
return nil, fmt.Errorf("Mock signer does not have key for "+
"address %v", addresses[0])
}
sigScript, err := txscript.SignatureScript(
tx, signDesc.InputIndex, signDesc.Output.PkScript,
txscript.SigHashAll, privKey, true,
)
if err != nil {
return nil, err
}
return &InputScript{SigScript: sigScript}, nil
case txscript.WitnessV0PubKeyHashTy:
privKey := m.findKey(addresses[0].ScriptAddress(), signDesc.SingleTweak,
signDesc.DoubleTweak)
if privKey == nil {
return nil, fmt.Errorf("Mock signer does not have key for "+
"address %v", addresses[0])
}
witnessScript, err := txscript.WitnessSignature(tx, signDesc.SigHashes,
signDesc.InputIndex, signDesc.Output.Value,
signDesc.Output.PkScript, txscript.SigHashAll, privKey, true)
if err != nil {
return nil, err
}
return &InputScript{Witness: witnessScript}, nil
default:
return nil, fmt.Errorf("Unexpected script type: %v", scriptType)
}
}
// findKey searches through all stored private keys and returns one
// corresponding to the hashed pubkey if it can be found. The public key may
// either correspond directly to the private key or to the private key with a
// tweak applied.
func (m *mockSigner) findKey(needleHash160 []byte, singleTweak []byte,
doubleTweak *btcec.PrivateKey) *btcec.PrivateKey {
for _, privkey := range m.privkeys {
// First check whether public key is directly derived from private key.
hash160 := btcutil.Hash160(privkey.PubKey().SerializeCompressed())
if bytes.Equal(hash160, needleHash160) {
return privkey
}
// Otherwise check if public key is derived from tweaked private key.
switch {
case singleTweak != nil:
privkey = TweakPrivKey(privkey, singleTweak)
case doubleTweak != nil:
privkey = DeriveRevocationPrivKey(privkey, doubleTweak)
default:
continue
}
hash160 = btcutil.Hash160(privkey.PubKey().SerializeCompressed())
if bytes.Equal(hash160, needleHash160) {
return privkey
}
}
return nil
}
type mockPreimageCache struct {
sync.Mutex
preimageMap map[[32]byte][]byte