diff --git a/breacharbiter.go b/breacharbiter.go index 269a7b12..42207c89 100644 --- a/breacharbiter.go +++ b/breacharbiter.go @@ -19,8 +19,8 @@ import ( "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/htlcswitch" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" - "github.com/lightningnetwork/lnd/sweep" ) var ( @@ -100,7 +100,7 @@ type BreachConfig struct { // Signer is used by the breach arbiter to generate sweep transactions, // which move coins from previously open channels back to the user's // wallet. - Signer lnwallet.Signer + Signer input.Signer // Store is a persistent resource that maintains information regarding // breached channels. This is used in conjunction with DB to recover @@ -282,7 +282,7 @@ func convertToSecondLevelRevoke(bo *breachedOutput, breachInfo *retributionInfo, // In this case, we'll modify the witness type of this output to // actually prepare for a second level revoke. - bo.witnessType = lnwallet.HtlcSecondLevelRevoke + bo.witnessType = input.HtlcSecondLevelRevoke // We'll also redirect the outpoint to this second level output, so the // spending transaction updates it inputs accordingly. @@ -346,8 +346,8 @@ func (b *breachArbiter) waitForSpendEvent(breachInfo *retributionInfo, breachedOutput := &breachInfo.breachedOutputs[i] // If this isn't an HTLC output, then we can skip it. - if breachedOutput.witnessType != lnwallet.HtlcAcceptedRevoke && - breachedOutput.witnessType != lnwallet.HtlcOfferedRevoke { + if breachedOutput.witnessType != input.HtlcAcceptedRevoke && + breachedOutput.witnessType != input.HtlcOfferedRevoke { continue } @@ -581,18 +581,18 @@ justiceTxBroadcast: // Compute both the total value of funds being swept and the // amount of funds that were revoked from the counter party. var totalFunds, revokedFunds btcutil.Amount - for _, input := range breachInfo.breachedOutputs { - totalFunds += input.Amount() + for _, inp := range breachInfo.breachedOutputs { + totalFunds += inp.Amount() // If the output being revoked is the remote commitment // output or an offered HTLC output, it's amount // contributes to the value of funds being revoked from // the counter party. - switch input.WitnessType() { - case lnwallet.CommitmentRevoke: - revokedFunds += input.Amount() - case lnwallet.HtlcOfferedRevoke: - revokedFunds += input.Amount() + switch inp.WitnessType() { + case input.CommitmentRevoke: + revokedFunds += inp.Amount() + case input.HtlcOfferedRevoke: + revokedFunds += inp.Amount() default: } } @@ -755,21 +755,21 @@ func (b *breachArbiter) handleBreachHandoff(breachEvent *ContractBreachEvent) { type breachedOutput struct { amt btcutil.Amount outpoint wire.OutPoint - witnessType lnwallet.WitnessType - signDesc lnwallet.SignDescriptor + witnessType input.WitnessType + signDesc input.SignDescriptor confHeight uint32 secondLevelWitnessScript []byte - witnessFunc lnwallet.WitnessGenerator + witnessFunc input.WitnessGenerator } // makeBreachedOutput assembles a new breachedOutput that can be used by the // breach arbiter to construct a justice or sweep transaction. func makeBreachedOutput(outpoint *wire.OutPoint, - witnessType lnwallet.WitnessType, + witnessType input.WitnessType, secondLevelScript []byte, - signDescriptor *lnwallet.SignDescriptor, + signDescriptor *input.SignDescriptor, confHeight uint32) breachedOutput { amount := signDescriptor.Output.Value @@ -797,13 +797,13 @@ func (bo *breachedOutput) OutPoint() *wire.OutPoint { // WitnessType returns the type of witness that must be generated to spend the // breached output. -func (bo *breachedOutput) WitnessType() lnwallet.WitnessType { +func (bo *breachedOutput) WitnessType() input.WitnessType { return bo.witnessType } // SignDesc returns the breached output's SignDescriptor, which is used during // signing to compute the witness. -func (bo *breachedOutput) SignDesc() *lnwallet.SignDescriptor { +func (bo *breachedOutput) SignDesc() *input.SignDescriptor { return &bo.signDesc } @@ -812,8 +812,8 @@ func (bo *breachedOutput) SignDesc() *lnwallet.SignDescriptor { // generation function, which parameterized primarily by the witness type and // sign descriptor. The method then returns the witness computed by invoking // this function on the first and subsequent calls. -func (bo *breachedOutput) CraftInputScript(signer lnwallet.Signer, txn *wire.MsgTx, - hashCache *txscript.TxSigHashes, txinIdx int) (*lnwallet.InputScript, error) { +func (bo *breachedOutput) CraftInputScript(signer input.Signer, txn *wire.MsgTx, + hashCache *txscript.TxSigHashes, txinIdx int) (*input.Script, error) { // First, we ensure that the witness generation function has been // initialized for this breached output. @@ -842,7 +842,7 @@ func (bo *breachedOutput) HeightHint() uint32 { // Add compile-time constraint ensuring breachedOutput implements the Input // interface. -var _ sweep.Input = (*breachedOutput)(nil) +var _ input.Input = (*breachedOutput)(nil) // retributionInfo encapsulates all the data needed to sweep all the contested // funds within a channel whose contract has been breached by the prior @@ -883,7 +883,7 @@ func newRetributionInfo(chanPoint *wire.OutPoint, if breachInfo.LocalOutputSignDesc != nil { localOutput := makeBreachedOutput( &breachInfo.LocalOutpoint, - lnwallet.CommitmentNoDelay, + input.CommitmentNoDelay, // No second level script as this is a commitment // output. nil, @@ -901,7 +901,7 @@ func newRetributionInfo(chanPoint *wire.OutPoint, if breachInfo.RemoteOutputSignDesc != nil { remoteOutput := makeBreachedOutput( &breachInfo.RemoteOutpoint, - lnwallet.CommitmentRevoke, + input.CommitmentRevoke, // No second level script as this is a commitment // output. nil, @@ -919,11 +919,11 @@ func newRetributionInfo(chanPoint *wire.OutPoint, // Using the breachedHtlc's incoming flag, determine the // appropriate witness type that needs to be generated in order // to sweep the HTLC output. - var htlcWitnessType lnwallet.WitnessType + var htlcWitnessType input.WitnessType if breachedHtlc.IsIncoming { - htlcWitnessType = lnwallet.HtlcAcceptedRevoke + htlcWitnessType = input.HtlcAcceptedRevoke } else { - htlcWitnessType = lnwallet.HtlcOfferedRevoke + htlcWitnessType = input.HtlcOfferedRevoke } htlcOutput := makeBreachedOutput( @@ -956,13 +956,13 @@ func (b *breachArbiter) createJusticeTx( // outputs, while simultaneously computing the estimated weight of the // transaction. var ( - spendableOutputs []sweep.Input - weightEstimate lnwallet.TxWeightEstimator + spendableOutputs []input.Input + weightEstimate input.TxWeightEstimator ) // Allocate enough space to potentially hold each of the breached // outputs in the retribution info. - spendableOutputs = make([]sweep.Input, 0, len(r.breachedOutputs)) + spendableOutputs = make([]input.Input, 0, len(r.breachedOutputs)) // The justice transaction we construct will be a segwit transaction // that pays to a p2wkh output. Components such as the version, @@ -975,38 +975,38 @@ func (b *breachArbiter) createJusticeTx( // finally adding to our list of spendable outputs. for i := range r.breachedOutputs { // Grab locally scoped reference to breached output. - input := &r.breachedOutputs[i] + inp := &r.breachedOutputs[i] // First, select the appropriate estimated witness weight for // the give witness type of this breached output. If the witness // type is unrecognized, we will omit it from the transaction. var witnessWeight int - switch input.WitnessType() { - case lnwallet.CommitmentNoDelay: - witnessWeight = lnwallet.P2WKHWitnessSize + switch inp.WitnessType() { + case input.CommitmentNoDelay: + witnessWeight = input.P2WKHWitnessSize - case lnwallet.CommitmentRevoke: - witnessWeight = lnwallet.ToLocalPenaltyWitnessSize + case input.CommitmentRevoke: + witnessWeight = input.ToLocalPenaltyWitnessSize - case lnwallet.HtlcOfferedRevoke: - witnessWeight = lnwallet.OfferedHtlcPenaltyWitnessSize + case input.HtlcOfferedRevoke: + witnessWeight = input.OfferedHtlcPenaltyWitnessSize - case lnwallet.HtlcAcceptedRevoke: - witnessWeight = lnwallet.AcceptedHtlcPenaltyWitnessSize + case input.HtlcAcceptedRevoke: + witnessWeight = input.AcceptedHtlcPenaltyWitnessSize - case lnwallet.HtlcSecondLevelRevoke: - witnessWeight = lnwallet.ToLocalPenaltyWitnessSize + case input.HtlcSecondLevelRevoke: + witnessWeight = input.ToLocalPenaltyWitnessSize default: brarLog.Warnf("breached output in retribution info "+ "contains unexpected witness type: %v", - input.WitnessType()) + inp.WitnessType()) continue } weightEstimate.AddWitnessInput(witnessWeight) // Finally, append this input to our list of spendable outputs. - spendableOutputs = append(spendableOutputs, input) + spendableOutputs = append(spendableOutputs, inp) } txWeight := int64(weightEstimate.Weight()) @@ -1016,7 +1016,7 @@ func (b *breachArbiter) createJusticeTx( // sweepSpendableOutputsTxn creates a signed transaction from a sequence of // spendable outputs by sweeping the funds into a single p2wkh output. func (b *breachArbiter) sweepSpendableOutputsTxn(txWeight int64, - inputs ...sweep.Input) (*wire.MsgTx, error) { + inputs ...input.Input) (*wire.MsgTx, error) { // First, we obtain a new public key script from the wallet which we'll // sweep the funds to. @@ -1078,7 +1078,7 @@ func (b *breachArbiter) sweepSpendableOutputsTxn(txWeight int64, // witness, and attaching it to the transaction. This function accepts // an integer index representing the intended txin index, and the // breached output from which it will spend. - addWitness := func(idx int, so sweep.Input) error { + addWitness := func(idx int, so input.Input) error { // First, we construct a valid witness for this outpoint and // transaction using the SpendableOutput's witness generation // function. @@ -1435,7 +1435,7 @@ func (bo *breachedOutput) Encode(w io.Writer) error { return err } - err := lnwallet.WriteSignDescriptor(w, &bo.signDesc) + err := input.WriteSignDescriptor(w, &bo.signDesc) if err != nil { return err } @@ -1466,7 +1466,7 @@ func (bo *breachedOutput) Decode(r io.Reader) error { return err } - if err := lnwallet.ReadSignDescriptor(r, &bo.signDesc); err != nil { + if err := input.ReadSignDescriptor(r, &bo.signDesc); err != nil { return err } @@ -1479,7 +1479,7 @@ func (bo *breachedOutput) Decode(r io.Reader) error { if _, err := io.ReadFull(r, scratch[:2]); err != nil { return err } - bo.witnessType = lnwallet.WitnessType( + bo.witnessType = input.WitnessType( binary.BigEndian.Uint16(scratch[:2]), ) diff --git a/breacharbiter_test.go b/breacharbiter_test.go index 986cfb2d..bfdffd83 100644 --- a/breacharbiter_test.go +++ b/breacharbiter_test.go @@ -27,6 +27,7 @@ import ( "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/htlcswitch" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" @@ -94,8 +95,8 @@ var ( { amt: btcutil.Amount(1e7), outpoint: breachOutPoints[0], - witnessType: lnwallet.CommitmentNoDelay, - signDesc: lnwallet.SignDescriptor{ + witnessType: input.CommitmentNoDelay, + signDesc: input.SignDescriptor{ SingleTweak: []byte{ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, @@ -138,8 +139,8 @@ var ( { amt: btcutil.Amount(2e9), outpoint: breachOutPoints[1], - witnessType: lnwallet.CommitmentRevoke, - signDesc: lnwallet.SignDescriptor{ + witnessType: input.CommitmentRevoke, + signDesc: input.SignDescriptor{ SingleTweak: []byte{ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, @@ -182,8 +183,8 @@ var ( { amt: btcutil.Amount(3e4), outpoint: breachOutPoints[2], - witnessType: lnwallet.CommitmentDelayOutput, - signDesc: lnwallet.SignDescriptor{ + witnessType: input.CommitmentDelayOutput, + signDesc: input.SignDescriptor{ SingleTweak: []byte{ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, @@ -1009,7 +1010,7 @@ func TestBreachHandoffSuccess(t *testing.T) { ProcessACK: make(chan error, 1), BreachRetribution: &lnwallet.BreachRetribution{ BreachTransaction: bobClose.CloseTx, - LocalOutputSignDesc: &lnwallet.SignDescriptor{ + LocalOutputSignDesc: &input.SignDescriptor{ Output: &wire.TxOut{ PkScript: breachKeys[0], }, @@ -1041,7 +1042,7 @@ func TestBreachHandoffSuccess(t *testing.T) { ProcessACK: make(chan error, 1), BreachRetribution: &lnwallet.BreachRetribution{ BreachTransaction: bobClose.CloseTx, - LocalOutputSignDesc: &lnwallet.SignDescriptor{ + LocalOutputSignDesc: &input.SignDescriptor{ Output: &wire.TxOut{ PkScript: breachKeys[0], }, @@ -1090,7 +1091,7 @@ func TestBreachHandoffFail(t *testing.T) { ProcessACK: make(chan error, 1), BreachRetribution: &lnwallet.BreachRetribution{ BreachTransaction: bobClose.CloseTx, - LocalOutputSignDesc: &lnwallet.SignDescriptor{ + LocalOutputSignDesc: &input.SignDescriptor{ Output: &wire.TxOut{ PkScript: breachKeys[0], }, @@ -1130,7 +1131,7 @@ func TestBreachHandoffFail(t *testing.T) { ProcessACK: make(chan error, 1), BreachRetribution: &lnwallet.BreachRetribution{ BreachTransaction: bobClose.CloseTx, - LocalOutputSignDesc: &lnwallet.SignDescriptor{ + LocalOutputSignDesc: &input.SignDescriptor{ Output: &wire.TxOut{ PkScript: breachKeys[0], }, @@ -1444,7 +1445,7 @@ func createInitChannels(revocationWindow int) (*lnwallet.LightningChannel, *lnwa if err != nil { return nil, nil, nil, err } - bobCommitPoint := lnwallet.ComputeCommitmentPoint(bobFirstRevoke[:]) + bobCommitPoint := input.ComputeCommitmentPoint(bobFirstRevoke[:]) aliceRoot, err := chainhash.NewHash(aliceKeyPriv.Serialize()) if err != nil { @@ -1455,7 +1456,7 @@ func createInitChannels(revocationWindow int) (*lnwallet.LightningChannel, *lnwa if err != nil { return nil, nil, nil, err } - aliceCommitPoint := lnwallet.ComputeCommitmentPoint(aliceFirstRevoke[:]) + aliceCommitPoint := input.ComputeCommitmentPoint(aliceFirstRevoke[:]) aliceCommitTx, bobCommitTx, err := lnwallet.CreateCommitmentTxns(channelBal, channelBal, &aliceCfg, &bobCfg, aliceCommitPoint, bobCommitPoint, diff --git a/chainregistry.go b/chainregistry.go index 1d0c84da..40d48cc5 100644 --- a/chainregistry.go +++ b/chainregistry.go @@ -25,6 +25,7 @@ import ( "github.com/lightningnetwork/lnd/chainntnfs/neutrinonotify" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/htlcswitch" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet/btcwallet" @@ -63,14 +64,14 @@ const ( // TODO(halseth): make configurable at startup? var defaultBtcChannelConstraints = channeldb.ChannelConstraints{ DustLimit: lnwallet.DefaultDustLimit(), - MaxAcceptedHtlcs: lnwallet.MaxHTLCNumber / 2, + MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, } // defaultLtcChannelConstraints is the default set of channel constraints that are // meant to be used when initially funding a Litecoin channel. var defaultLtcChannelConstraints = channeldb.ChannelConstraints{ DustLimit: defaultLitecoinDustLimit, - MaxAcceptedHtlcs: lnwallet.MaxHTLCNumber / 2, + MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, } // chainCode is an enum-like structure for keeping track of the chains @@ -105,7 +106,7 @@ type chainControl struct { feeEstimator lnwallet.FeeEstimator - signer lnwallet.Signer + signer input.Signer keyRing keychain.KeyRing diff --git a/contractcourt/briefcase.go b/contractcourt/briefcase.go index 76840fc2..3af1da08 100644 --- a/contractcourt/briefcase.go +++ b/contractcourt/briefcase.go @@ -10,6 +10,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/coreos/bbolt" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" ) @@ -908,7 +909,7 @@ func encodeIncomingResolution(w io.Writer, i *lnwallet.IncomingHtlcResolution) e if err := binary.Write(w, endian, i.ClaimOutpoint.Index); err != nil { return err } - err := lnwallet.WriteSignDescriptor(w, &i.SweepSignDesc) + err := input.WriteSignDescriptor(w, &i.SweepSignDesc) if err != nil { return err } @@ -945,7 +946,7 @@ func decodeIncomingResolution(r io.Reader, h *lnwallet.IncomingHtlcResolution) e return err } - return lnwallet.ReadSignDescriptor(r, &h.SweepSignDesc) + return input.ReadSignDescriptor(r, &h.SweepSignDesc) } func encodeOutgoingResolution(w io.Writer, o *lnwallet.OutgoingHtlcResolution) error { @@ -977,7 +978,7 @@ func encodeOutgoingResolution(w io.Writer, o *lnwallet.OutgoingHtlcResolution) e return err } - return lnwallet.WriteSignDescriptor(w, &o.SweepSignDesc) + return input.WriteSignDescriptor(w, &o.SweepSignDesc) } func decodeOutgoingResolution(r io.Reader, o *lnwallet.OutgoingHtlcResolution) error { @@ -1010,7 +1011,7 @@ func decodeOutgoingResolution(r io.Reader, o *lnwallet.OutgoingHtlcResolution) e return err } - return lnwallet.ReadSignDescriptor(r, &o.SweepSignDesc) + return input.ReadSignDescriptor(r, &o.SweepSignDesc) } func encodeCommitResolution(w io.Writer, @@ -1024,7 +1025,7 @@ func encodeCommitResolution(w io.Writer, return err } - err = lnwallet.WriteSignDescriptor(w, &c.SelfOutputSignDesc) + err = input.WriteSignDescriptor(w, &c.SelfOutputSignDesc) if err != nil { return err } @@ -1044,7 +1045,7 @@ func decodeCommitResolution(r io.Reader, return err } - err = lnwallet.ReadSignDescriptor(r, &c.SelfOutputSignDesc) + err = input.ReadSignDescriptor(r, &c.SelfOutputSignDesc) if err != nil { return err } diff --git a/contractcourt/briefcase_test.go b/contractcourt/briefcase_test.go index f0c8f937..c64c7ac2 100644 --- a/contractcourt/briefcase_test.go +++ b/contractcourt/briefcase_test.go @@ -17,6 +17,7 @@ import ( "github.com/coreos/bbolt" "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" ) @@ -63,7 +64,7 @@ var ( 0xb4, 0x12, 0xa3, } - testSignDesc = lnwallet.SignDescriptor{ + testSignDesc = input.SignDescriptor{ SingleTweak: []byte{ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, diff --git a/contractcourt/chain_arbitrator.go b/contractcourt/chain_arbitrator.go index 6652df23..556fba2d 100644 --- a/contractcourt/chain_arbitrator.go +++ b/contractcourt/chain_arbitrator.go @@ -11,6 +11,7 @@ import ( "github.com/btcsuite/btcutil" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/sweep" @@ -120,7 +121,7 @@ type ChainArbitratorConfig struct { // Signer is a signer backed by the active lnd node. This should be // capable of producing a signature as specified by a valid // SignDescriptor. - Signer lnwallet.Signer + Signer input.Signer // FeeEstimator will be used to return fee estimates. FeeEstimator lnwallet.FeeEstimator diff --git a/contractcourt/chain_watcher.go b/contractcourt/chain_watcher.go index 49959392..719b2068 100644 --- a/contractcourt/chain_watcher.go +++ b/contractcourt/chain_watcher.go @@ -14,6 +14,7 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" ) @@ -93,7 +94,7 @@ type chainWatcherConfig struct { // signer is the main signer instances that will be responsible for // signing any HTLC and commitment transaction generated by the state // machine. - signer lnwallet.Signer + signer input.Signer // contractBreach is a method that will be called by the watcher if it // detects that a contract breach transaction has been confirmed. Only @@ -191,13 +192,13 @@ func (c *chainWatcher) Start() error { localKey := chanState.LocalChanCfg.MultiSigKey.PubKey.SerializeCompressed() remoteKey := chanState.RemoteChanCfg.MultiSigKey.PubKey.SerializeCompressed() - multiSigScript, err := lnwallet.GenMultiSigScript( + multiSigScript, err := input.GenMultiSigScript( localKey, remoteKey, ) if err != nil { return err } - pkScript, err := lnwallet.WitnessScriptHash(multiSigScript) + pkScript, err := input.WitnessScriptHash(multiSigScript) if err != nil { return err } diff --git a/contractcourt/channel_arbitrator_test.go b/contractcourt/channel_arbitrator_test.go index e910de0a..4518fac0 100644 --- a/contractcourt/channel_arbitrator_test.go +++ b/contractcourt/channel_arbitrator_test.go @@ -10,6 +10,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" ) @@ -542,7 +543,7 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) { // our commitment transaction got confirmed. outgoingRes := lnwallet.OutgoingHtlcResolution{ Expiry: 10, - SweepSignDesc: lnwallet.SignDescriptor{ + SweepSignDesc: input.SignDescriptor{ Output: &wire.TxOut{}, }, SignedTimeoutTx: &wire.MsgTx{ diff --git a/contractcourt/commit_sweep_resolver.go b/contractcourt/commit_sweep_resolver.go index 52118f73..2c32ad25 100644 --- a/contractcourt/commit_sweep_resolver.go +++ b/contractcourt/commit_sweep_resolver.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/binary" "fmt" + "github.com/lightningnetwork/lnd/input" "io" "io/ioutil" @@ -100,9 +101,9 @@ func (c *commitSweepResolver) Resolve() (ContractResolver, error) { // we'll now craft an input with all the information required // to create a fully valid sweeping transaction to recover // these coins. - input := sweep.MakeBaseInput( + inp := input.MakeBaseInput( &c.commitResolution.SelfOutPoint, - lnwallet.CommitmentNoDelay, + input.CommitmentNoDelay, &c.commitResolution.SelfOutputSignDesc, c.broadcastHeight, ) @@ -117,7 +118,7 @@ func (c *commitSweepResolver) Resolve() (ContractResolver, error) { // // TODO: Use time-based sweeper and result chan. c.sweepTx, err = c.Sweeper.CreateSweepTx( - []sweep.Input{&input}, + []input.Input{&inp}, sweep.FeePreference{ ConfTarget: sweepConfTarget, }, 0, diff --git a/contractcourt/htlc_outgoing_contest_resolver.go b/contractcourt/htlc_outgoing_contest_resolver.go index 49bd2803..826631dd 100644 --- a/contractcourt/htlc_outgoing_contest_resolver.go +++ b/contractcourt/htlc_outgoing_contest_resolver.go @@ -2,12 +2,12 @@ package contractcourt import ( "fmt" + "github.com/lightningnetwork/lnd/input" "io" "github.com/btcsuite/btcd/wire" "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/chainntnfs" - "github.com/lightningnetwork/lnd/lnwallet" ) // htlcOutgoingContestResolver is a ContractResolver that's able to resolve an @@ -119,7 +119,7 @@ func (h *htlcOutgoingContestResolver) Resolve() (ContractResolver, error) { // re-construct the pkScipt we need to watch. outPointToWatch = h.htlcResolution.SignedTimeoutTx.TxIn[0].PreviousOutPoint witness := h.htlcResolution.SignedTimeoutTx.TxIn[0].Witness - scriptToWatch, err = lnwallet.WitnessScriptHash( + scriptToWatch, err = input.WitnessScriptHash( witness[len(witness)-1], ) if err != nil { diff --git a/contractcourt/htlc_success_resolver.go b/contractcourt/htlc_success_resolver.go index 3a35c850..817addfd 100644 --- a/contractcourt/htlc_success_resolver.go +++ b/contractcourt/htlc_success_resolver.go @@ -3,6 +3,7 @@ package contractcourt import ( "encoding/binary" "fmt" + "github.com/lightningnetwork/lnd/input" "io" "github.com/lightningnetwork/lnd/channeldb" @@ -104,7 +105,7 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) { // need to create an input which contains all the items // required to add this input to a sweeping transaction, // and generate a witness. - input := sweep.MakeHtlcSucceedInput( + inp := input.MakeHtlcSucceedInput( &h.htlcResolution.ClaimOutpoint, &h.htlcResolution.SweepSignDesc, h.htlcResolution.Preimage[:], @@ -122,7 +123,7 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) { // TODO: Use time-based sweeper and result chan. var err error h.sweepTx, err = h.Sweeper.CreateSweepTx( - []sweep.Input{&input}, + []input.Input{&inp}, sweep.FeePreference{ ConfTarget: sweepConfTarget, }, 0, diff --git a/docs/go-fuzz/wirefuzz.go b/docs/go-fuzz/wirefuzz.go index 3d71871d..59f496f2 100644 --- a/docs/go-fuzz/wirefuzz.go +++ b/docs/go-fuzz/wirefuzz.go @@ -3,8 +3,9 @@ package wirefuzz import ( "bytes" "fmt" - "github.com/lightningnetwork/lnd/lnwire" "reflect" + + "github.com/lightningnetwork/lnd/lnwire" ) // Fuzz is used by go-fuzz to fuzz for potentially malicious input diff --git a/fundingmanager.go b/fundingmanager.go index b5127c0f..8fe43358 100644 --- a/fundingmanager.go +++ b/fundingmanager.go @@ -18,6 +18,7 @@ import ( "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/htlcswitch" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnpeer" "github.com/lightningnetwork/lnd/lnrpc" @@ -1847,12 +1848,12 @@ func makeFundingScript(channel *channeldb.OpenChannel) ([]byte, error) { localKey := channel.LocalChanCfg.MultiSigKey.PubKey.SerializeCompressed() remoteKey := channel.RemoteChanCfg.MultiSigKey.PubKey.SerializeCompressed() - multiSigScript, err := lnwallet.GenMultiSigScript(localKey, remoteKey) + multiSigScript, err := input.GenMultiSigScript(localKey, remoteKey) if err != nil { return nil, err } - return lnwallet.WitnessScriptHash(multiSigScript) + return input.WitnessScriptHash(multiSigScript) } // waitForFundingConfirmation handles the final stages of the channel funding diff --git a/fundingmanager_test.go b/fundingmanager_test.go index 196712df..6231ff4d 100644 --- a/fundingmanager_test.go +++ b/fundingmanager_test.go @@ -24,6 +24,7 @@ import ( "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/htlcswitch" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnpeer" "github.com/lightningnetwork/lnd/lnrpc" @@ -202,7 +203,7 @@ func (n *testNode) AddNewChannel(channel *channeldb.OpenChannel, func createTestWallet(cdb *channeldb.DB, netParams *chaincfg.Params, notifier chainntnfs.ChainNotifier, wc lnwallet.WalletController, - signer lnwallet.Signer, keyRing keychain.SecretKeyRing, + signer input.Signer, keyRing keychain.SecretKeyRing, bio lnwallet.BlockChainIO, estimator lnwallet.FeeEstimator) (*lnwallet.LightningWallet, error) { @@ -340,7 +341,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey, return lnwire.NewMSatFromSatoshis(chanAmt) - reserve }, RequiredRemoteMaxHTLCs: func(chanAmt btcutil.Amount) uint16 { - return uint16(lnwallet.MaxHTLCNumber / 2) + return uint16(input.MaxHTLCNumber / 2) }, WatchNewChannel: func(*channeldb.OpenChannel, *btcec.PublicKey) error { return nil diff --git a/htlcswitch/link.go b/htlcswitch/link.go index 8d9aa458..18da280e 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -15,6 +15,7 @@ import ( "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/contractcourt" "github.com/lightningnetwork/lnd/htlcswitch/hodl" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnpeer" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" @@ -348,7 +349,7 @@ func NewChannelLink(cfg ChannelLinkConfig, shortChanID: channel.ShortChanID(), // TODO(roasbeef): just do reserve here? logCommitTimer: time.NewTimer(300 * time.Millisecond), - overflowQueue: newPacketQueue(lnwallet.MaxHTLCNumber / 2), + overflowQueue: newPacketQueue(input.MaxHTLCNumber / 2), htlcUpdates: make(chan []channeldb.HTLC), quit: make(chan struct{}), } diff --git a/htlcswitch/link_test.go b/htlcswitch/link_test.go index d9e77698..5b329047 100644 --- a/htlcswitch/link_test.go +++ b/htlcswitch/link_test.go @@ -26,6 +26,7 @@ import ( "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/contractcourt" "github.com/lightningnetwork/lnd/htlcswitch/hodl" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnpeer" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" @@ -302,7 +303,7 @@ func TestChannelLinkBidirectionalOneHopPayments(t *testing.T) { // Send max available payment number in both sides, thereby testing // the property of channel link to cope with overflowing. - count := 2 * lnwallet.MaxHTLCNumber + count := 2 * input.MaxHTLCNumber resultChan := make(chan *result, count) for i := 0; i < count/2; i++ { go func(i int) { @@ -1802,7 +1803,7 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { t.Fatalf("unable to query fee estimator: %v", err) } htlcFee := lnwire.NewMSatFromSatoshis( - feePerKw.FeeForWeight(lnwallet.HtlcWeight), + feePerKw.FeeForWeight(input.HtlcWeight), ) // The starting bandwidth of the channel should be exactly the amount @@ -2242,7 +2243,7 @@ func TestChannelLinkBandwidthConsistencyOverflow(t *testing.T) { // consistency along the way htlcAmt := lnwire.NewMSatFromSatoshis(100000) totalHtlcAmt := lnwire.MilliSatoshi(0) - const numHTLCs = lnwallet.MaxHTLCNumber / 2 + const numHTLCs = input.MaxHTLCNumber / 2 var preImages [][32]byte for i := 0; i < numHTLCs; i++ { preImage := addLinkHTLC(htlcID, htlcAmt) @@ -2280,7 +2281,7 @@ func TestChannelLinkBandwidthConsistencyOverflow(t *testing.T) { // TODO(roasbeef): increase sleep time.Sleep(time.Second * 1) - commitWeight := lnwallet.CommitWeight + lnwallet.HtlcWeight*numHTLCs + commitWeight := input.CommitWeight + input.HtlcWeight*numHTLCs htlcFee := lnwire.NewMSatFromSatoshis( feePerKw.FeeForWeight(commitWeight), ) @@ -2462,7 +2463,7 @@ func TestChannelLinkTrimCircuitsPending(t *testing.T) { defaultCommitFee := alice.channel.StateSnapshot().CommitFee htlcFee := lnwire.NewMSatFromSatoshis( - feePerKw.FeeForWeight(lnwallet.HtlcWeight), + feePerKw.FeeForWeight(input.HtlcWeight), ) // The starting bandwidth of the channel should be exactly the amount @@ -2740,7 +2741,7 @@ func TestChannelLinkTrimCircuitsNoCommit(t *testing.T) { defaultCommitFee := alice.channel.StateSnapshot().CommitFee htlcFee := lnwire.NewMSatFromSatoshis( - feePerKw.FeeForWeight(lnwallet.HtlcWeight), + feePerKw.FeeForWeight(input.HtlcWeight), ) // The starting bandwidth of the channel should be exactly the amount @@ -2996,7 +2997,7 @@ func TestChannelLinkBandwidthChanReserve(t *testing.T) { t.Fatalf("unable to query fee estimator: %v", err) } htlcFee := lnwire.NewMSatFromSatoshis( - feePerKw.FeeForWeight(lnwallet.HtlcWeight), + feePerKw.FeeForWeight(input.HtlcWeight), ) // The starting bandwidth of the channel should be exactly the amount diff --git a/htlcswitch/mock.go b/htlcswitch/mock.go index d6c1d820..b2473af1 100644 --- a/htlcswitch/mock.go +++ b/htlcswitch/mock.go @@ -23,6 +23,7 @@ import ( "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/contractcourt" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnpeer" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" @@ -747,7 +748,7 @@ type mockSigner struct { key *btcec.PrivateKey } -func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx, signDesc *lnwallet.SignDescriptor) ([]byte, error) { +func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx, signDesc *input.SignDescriptor) ([]byte, error) { amt := signDesc.Output.Value witnessScript := signDesc.WitnessScript privKey := m.key @@ -758,10 +759,10 @@ func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx, signDesc *lnwallet.SignDescri switch { case signDesc.SingleTweak != nil: - privKey = lnwallet.TweakPrivKey(privKey, + privKey = input.TweakPrivKey(privKey, signDesc.SingleTweak) case signDesc.DoubleTweak != nil: - privKey = lnwallet.DeriveRevocationPrivKey(privKey, + privKey = input.DeriveRevocationPrivKey(privKey, signDesc.DoubleTweak) } @@ -774,7 +775,7 @@ func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx, signDesc *lnwallet.SignDescri return sig[:len(sig)-1], nil } -func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx, signDesc *lnwallet.SignDescriptor) (*lnwallet.InputScript, error) { +func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx, signDesc *input.SignDescriptor) (*input.Script, error) { // TODO(roasbeef): expose tweaked signer from lnwallet so don't need to // duplicate this code? @@ -783,10 +784,10 @@ func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx, signDesc *lnwallet.SignD switch { case signDesc.SingleTweak != nil: - privKey = lnwallet.TweakPrivKey(privKey, + privKey = input.TweakPrivKey(privKey, signDesc.SingleTweak) case signDesc.DoubleTweak != nil: - privKey = lnwallet.DeriveRevocationPrivKey(privKey, + privKey = input.DeriveRevocationPrivKey(privKey, signDesc.DoubleTweak) } @@ -797,7 +798,7 @@ func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx, signDesc *lnwallet.SignD return nil, err } - return &lnwallet.InputScript{ + return &input.Script{ Witness: witnessScript, }, nil } diff --git a/htlcswitch/test_utils.go b/htlcswitch/test_utils.go index f2e44a73..d7518de1 100644 --- a/htlcswitch/test_utils.go +++ b/htlcswitch/test_utils.go @@ -24,6 +24,7 @@ import ( "github.com/go-errors/errors" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/contractcourt" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnpeer" "github.com/lightningnetwork/lnd/lnwallet" @@ -168,7 +169,7 @@ func createTestChannel(alicePrivKey, bobPrivKey []byte, channelCapacity), ChanReserve: aliceReserve, MinHTLC: 0, - MaxAcceptedHtlcs: lnwallet.MaxHTLCNumber / 2, + MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, CsvDelay: uint16(csvTimeoutAlice), } @@ -178,7 +179,7 @@ func createTestChannel(alicePrivKey, bobPrivKey []byte, channelCapacity), ChanReserve: bobReserve, MinHTLC: 0, - MaxAcceptedHtlcs: lnwallet.MaxHTLCNumber / 2, + MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, CsvDelay: uint16(csvTimeoutBob), } @@ -241,7 +242,7 @@ func createTestChannel(alicePrivKey, bobPrivKey []byte, if err != nil { return nil, nil, nil, nil, err } - bobCommitPoint := lnwallet.ComputeCommitmentPoint(bobFirstRevoke[:]) + bobCommitPoint := input.ComputeCommitmentPoint(bobFirstRevoke[:]) aliceRoot, err := chainhash.NewHash(aliceKeyPriv.Serialize()) if err != nil { @@ -252,7 +253,7 @@ func createTestChannel(alicePrivKey, bobPrivKey []byte, if err != nil { return nil, nil, nil, nil, err } - aliceCommitPoint := lnwallet.ComputeCommitmentPoint(aliceFirstRevoke[:]) + aliceCommitPoint := input.ComputeCommitmentPoint(aliceFirstRevoke[:]) aliceCommitTx, bobCommitTx, err := lnwallet.CreateCommitmentTxns(aliceAmount, bobAmount, &aliceCfg, &bobCfg, aliceCommitPoint, bobCommitPoint, diff --git a/sweep/input.go b/input/input.go similarity index 81% rename from sweep/input.go rename to input/input.go index 57a954df..77ecbd5a 100644 --- a/sweep/input.go +++ b/input/input.go @@ -1,9 +1,8 @@ -package sweep +package input import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" - "github.com/lightningnetwork/lnd/lnwallet" ) // Input represents an abstract UTXO which is to be spent using a sweeping @@ -17,21 +16,21 @@ type Input interface { // WitnessType returns an enum specifying the type of witness that must // be generated in order to spend this output. - WitnessType() lnwallet.WitnessType + WitnessType() WitnessType // SignDesc returns a reference to a spendable output's sign // descriptor, which is used during signing to compute a valid witness // that spends this output. - SignDesc() *lnwallet.SignDescriptor + SignDesc() *SignDescriptor // CraftInputScript returns a valid set of input scripts allowing this // output to be spent. The returns input scripts should target the // input at location txIndex within the passed transaction. The input // scripts generated by this method support spending p2wkh, p2wsh, and // also nested p2sh outputs. - CraftInputScript(signer lnwallet.Signer, txn *wire.MsgTx, + CraftInputScript(signer Signer, txn *wire.MsgTx, hashCache *txscript.TxSigHashes, - txinIdx int) (*lnwallet.InputScript, error) + txinIdx int) (*Script, error) // BlocksToMaturity returns the relative timelock, as a number of // blocks, that must be built on top of the confirmation height before @@ -46,8 +45,8 @@ type Input interface { type inputKit struct { outpoint wire.OutPoint - witnessType lnwallet.WitnessType - signDesc lnwallet.SignDescriptor + witnessType WitnessType + signDesc SignDescriptor heightHint uint32 } @@ -59,13 +58,13 @@ func (i *inputKit) OutPoint() *wire.OutPoint { // WitnessType returns the type of witness that must be generated to spend the // breached output. -func (i *inputKit) WitnessType() lnwallet.WitnessType { +func (i *inputKit) WitnessType() WitnessType { return i.witnessType } // SignDesc returns the breached output's SignDescriptor, which is used during // signing to compute the witness. -func (i *inputKit) SignDesc() *lnwallet.SignDescriptor { +func (i *inputKit) SignDesc() *SignDescriptor { return &i.signDesc } @@ -83,8 +82,8 @@ type BaseInput struct { // MakeBaseInput assembles a new BaseInput that can be used to construct a // sweep transaction. -func MakeBaseInput(outpoint *wire.OutPoint, witnessType lnwallet.WitnessType, - signDescriptor *lnwallet.SignDescriptor, heightHint uint32) BaseInput { +func MakeBaseInput(outpoint *wire.OutPoint, witnessType WitnessType, + signDescriptor *SignDescriptor, heightHint uint32) BaseInput { return BaseInput{ inputKit{ @@ -100,8 +99,8 @@ func MakeBaseInput(outpoint *wire.OutPoint, witnessType lnwallet.WitnessType, // to be spent. The returns input scripts should target the input at location // txIndex within the passed transaction. The input scripts generated by this // method support spending p2wkh, p2wsh, and also nested p2sh outputs. -func (bi *BaseInput) CraftInputScript(signer lnwallet.Signer, txn *wire.MsgTx, - hashCache *txscript.TxSigHashes, txinIdx int) (*lnwallet.InputScript, error) { +func (bi *BaseInput) CraftInputScript(signer Signer, txn *wire.MsgTx, + hashCache *txscript.TxSigHashes, txinIdx int) (*Script, error) { witnessFunc := bi.witnessType.GenWitnessFunc( signer, bi.SignDesc(), @@ -129,13 +128,13 @@ type HtlcSucceedInput struct { // MakeHtlcSucceedInput assembles a new redeem input that can be used to // construct a sweep transaction. func MakeHtlcSucceedInput(outpoint *wire.OutPoint, - signDescriptor *lnwallet.SignDescriptor, + signDescriptor *SignDescriptor, preimage []byte, heightHint uint32) HtlcSucceedInput { return HtlcSucceedInput{ inputKit: inputKit{ outpoint: *outpoint, - witnessType: lnwallet.HtlcAcceptedRemoteSuccess, + witnessType: HtlcAcceptedRemoteSuccess, signDesc: *signDescriptor, heightHint: heightHint, }, @@ -147,21 +146,21 @@ func MakeHtlcSucceedInput(outpoint *wire.OutPoint, // to be spent. The returns input scripts should target the input at location // txIndex within the passed transaction. The input scripts generated by this // method support spending p2wkh, p2wsh, and also nested p2sh outputs. -func (h *HtlcSucceedInput) CraftInputScript(signer lnwallet.Signer, txn *wire.MsgTx, - hashCache *txscript.TxSigHashes, txinIdx int) (*lnwallet.InputScript, error) { +func (h *HtlcSucceedInput) CraftInputScript(signer Signer, txn *wire.MsgTx, + hashCache *txscript.TxSigHashes, txinIdx int) (*Script, error) { desc := h.signDesc desc.SigHashes = hashCache desc.InputIndex = txinIdx - witness, err := lnwallet.SenderHtlcSpendRedeem( + witness, err := SenderHtlcSpendRedeem( signer, &desc, txn, h.preimage, ) if err != nil { return nil, err } - return &lnwallet.InputScript{ + return &Script{ Witness: witness, }, nil } diff --git a/lnwallet/script_utils.go b/input/script_utils.go similarity index 96% rename from lnwallet/script_utils.go rename to input/script_utils.go index abfa892d..c3d49ed0 100644 --- a/lnwallet/script_utils.go +++ b/input/script_utils.go @@ -1,4 +1,4 @@ -package lnwallet +package input import ( "bytes" @@ -139,7 +139,7 @@ func Ripemd160H(d []byte) []byte { return h.Sum(nil) } -// senderHTLCScript constructs the public key script for an outgoing HTLC +// SenderHTLCScript constructs the public key script for an outgoing HTLC // output payment for the sender's version of the commitment transaction. The // possible script paths from this output include: // @@ -169,7 +169,7 @@ func Ripemd160H(d []byte) []byte { // OP_CHECKSIG // OP_ENDIF // OP_ENDIF -func senderHTLCScript(senderHtlcKey, receiverHtlcKey, +func SenderHTLCScript(senderHtlcKey, receiverHtlcKey, revocationKey *btcec.PublicKey, paymentHash []byte) ([]byte, error) { builder := txscript.NewScriptBuilder() @@ -249,14 +249,14 @@ func senderHTLCScript(senderHtlcKey, receiverHtlcKey, return builder.Script() } -// senderHtlcSpendRevoke constructs a valid witness allowing the receiver of an +// SenderHtlcSpendRevokeWithKey constructs a valid witness allowing the receiver of an // HTLC to claim the output with knowledge of the revocation private key in the // scenario that the sender of the HTLC broadcasts a previously revoked // commitment transaction. A valid spend requires knowledge of the private key // that corresponds to their revocation base point and also the private key fro // the per commitment point, and a valid signature under the combined public // key. -func senderHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor, +func SenderHtlcSpendRevokeWithKey(signer Signer, signDesc *SignDescriptor, revokeKey *btcec.PublicKey, sweepTx *wire.MsgTx) (wire.TxWitness, error) { sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc) @@ -299,7 +299,7 @@ func SenderHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor, signDesc.DoubleTweak.PubKey(), ) - return senderHtlcSpendRevoke(signer, signDesc, revokeKey, sweepTx) + return SenderHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx) } // SenderHtlcSpendRedeem constructs a valid witness allowing the receiver of an @@ -326,11 +326,11 @@ func SenderHtlcSpendRedeem(signer Signer, signDesc *SignDescriptor, return witnessStack, nil } -// senderHtlcSpendTimeout constructs a valid witness allowing the sender of an +// SenderHtlcSpendTimeout constructs a valid witness allowing the sender of an // HTLC to activate the time locked covenant clause of a soon to be expired // HTLC. This script simply spends the multi-sig output using the // pre-generated HTLC timeout transaction. -func senderHtlcSpendTimeout(receiverSig []byte, signer Signer, +func SenderHtlcSpendTimeout(receiverSig []byte, signer Signer, signDesc *SignDescriptor, htlcTimeoutTx *wire.MsgTx) (wire.TxWitness, error) { sweepSig, err := signer.SignOutputRaw(htlcTimeoutTx, signDesc) @@ -352,7 +352,7 @@ func senderHtlcSpendTimeout(receiverSig []byte, signer Signer, return witnessStack, nil } -// receiverHTLCScript constructs the public key script for an incoming HTLC +// ReceiverHTLCScript constructs the public key script for an incoming HTLC // output payment for the receiver's version of the commitment transaction. The // possible execution paths from this script include: // * The receiver of the HTLC uses its second level HTLC transaction to @@ -382,7 +382,7 @@ func senderHtlcSpendTimeout(receiverSig []byte, signer Signer, // OP_CHECKSIG // OP_ENDIF // OP_ENDIF -func receiverHTLCScript(cltvExpiry uint32, senderHtlcKey, +func ReceiverHTLCScript(cltvExpiry uint32, senderHtlcKey, receiverHtlcKey, revocationKey *btcec.PublicKey, paymentHash []byte) ([]byte, error) { @@ -473,7 +473,7 @@ func receiverHTLCScript(cltvExpiry uint32, senderHtlcKey, return builder.Script() } -// receiverHtlcSpendRedeem constructs a valid witness allowing the receiver of +// ReceiverHtlcSpendRedeem constructs a valid witness allowing the receiver of // an HTLC to redeem the conditional payment in the event that their commitment // transaction is broadcast. This clause transitions the state of the HLTC // output into the delay+claim state by activating the off-chain covenant bound @@ -481,7 +481,7 @@ func receiverHTLCScript(cltvExpiry uint32, senderHtlcKey, // signed has a relative timelock delay enforced by its sequence number. This // delay give the sender of the HTLC enough time to revoke the output if this // is a breach commitment transaction. -func receiverHtlcSpendRedeem(senderSig, paymentPreimage []byte, +func ReceiverHtlcSpendRedeem(senderSig, paymentPreimage []byte, signer Signer, signDesc *SignDescriptor, htlcSuccessTx *wire.MsgTx) (wire.TxWitness, error) { @@ -507,11 +507,11 @@ func receiverHtlcSpendRedeem(senderSig, paymentPreimage []byte, return witnessStack, nil } -// receiverHtlcSpendRevoke constructs a valid witness allowing the sender of an +// ReceiverHtlcSpendRevokeWithKey constructs a valid witness allowing the sender of an // HTLC within a previously revoked commitment transaction to re-claim the // pending funds in the case that the receiver broadcasts this revoked // commitment transaction. -func receiverHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor, +func ReceiverHtlcSpendRevokeWithKey(signer Signer, signDesc *SignDescriptor, revokeKey *btcec.PublicKey, sweepTx *wire.MsgTx) (wire.TxWitness, error) { // First, we'll generate a signature for the sweep transaction. The @@ -556,10 +556,10 @@ func ReceiverHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor, signDesc.DoubleTweak.PubKey(), ) - return receiverHtlcSpendRevoke(signer, signDesc, revokeKey, sweepTx) + return ReceiverHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx) } -// receiverHtlcSpendTimeout constructs a valid witness allowing the sender of +// ReceiverHtlcSpendTimeout constructs a valid witness allowing the sender of // an HTLC to recover the pending funds after an absolute timeout in the // scenario that the receiver of the HTLC broadcasts their version of the // commitment transaction. If the caller has already set the lock time on the @@ -568,7 +568,7 @@ func ReceiverHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor, // // NOTE: The target input of the passed transaction MUST NOT have a final // sequence number. Otherwise, the OP_CHECKLOCKTIMEVERIFY check will fail. -func receiverHtlcSpendTimeout(signer Signer, signDesc *SignDescriptor, +func ReceiverHtlcSpendTimeout(signer Signer, signDesc *SignDescriptor, sweepTx *wire.MsgTx, cltvExpiry int32) (wire.TxWitness, error) { // If the caller set a proper timeout value, then we'll apply it @@ -599,7 +599,7 @@ func receiverHtlcSpendTimeout(signer Signer, signDesc *SignDescriptor, return witnessStack, nil } -// secondLevelHtlcScript is the uniform script that's used as the output for +// SecondLevelHtlcScript is the uniform script that's used as the output for // the second-level HTLC transactions. The second level transaction act as a // sort of covenant, ensuring that a 2-of-2 multi-sig output can only be // spent in a particular way, and to a particular output. @@ -625,7 +625,7 @@ func receiverHtlcSpendTimeout(signer Signer, signDesc *SignDescriptor, // TODO(roasbeef): possible renames for second-level // * transition? // * covenant output -func secondLevelHtlcScript(revocationKey, delayKey *btcec.PublicKey, +func SecondLevelHtlcScript(revocationKey, delayKey *btcec.PublicKey, csvDelay uint32) ([]byte, error) { builder := txscript.NewScriptBuilder() @@ -665,16 +665,16 @@ func secondLevelHtlcScript(revocationKey, delayKey *btcec.PublicKey, return builder.Script() } -// htlcSpendSuccess spends a second-level HTLC output. This function is to be +// HtlcSpendSuccess spends a second-level HTLC output. This function is to be // used by the sender of an HTLC to claim the output after a relative timeout // or the receiver of the HTLC to claim on-chain with the pre-image. -func htlcSpendSuccess(signer Signer, signDesc *SignDescriptor, +func HtlcSpendSuccess(signer Signer, signDesc *SignDescriptor, sweepTx *wire.MsgTx, csvDelay uint32) (wire.TxWitness, error) { // We're required to wait a relative period of time before we can sweep // the output in order to allow the other party to contest our claim of // validity to this version of the commitment transaction. - sweepTx.TxIn[0].Sequence = lockTimeToSequence(false, csvDelay) + sweepTx.TxIn[0].Sequence = LockTimeToSequence(false, csvDelay) // Finally, OP_CSV requires that the version of the transaction // spending a pkscript with OP_CSV within it *must* be >= 2. @@ -704,10 +704,10 @@ func htlcSpendSuccess(signer Signer, signDesc *SignDescriptor, return witnessStack, nil } -// htlcSpendRevoke spends a second-level HTLC output. This function is to be +// HtlcSpendRevoke spends a second-level HTLC output. This function is to be // used by the sender or receiver of an HTLC to claim the HTLC after a revoked // commitment transaction was broadcast. -func htlcSpendRevoke(signer Signer, signDesc *SignDescriptor, +func HtlcSpendRevoke(signer Signer, signDesc *SignDescriptor, revokeTx *wire.MsgTx) (wire.TxWitness, error) { // We don't need any spacial modifications to the transaction as this @@ -760,11 +760,11 @@ func HtlcSecondLevelSpend(signer Signer, signDesc *SignDescriptor, return witnessStack, nil } -// lockTimeToSequence converts the passed relative locktime to a sequence +// LockTimeToSequence converts the passed relative locktime to a sequence // number in accordance to BIP-68. // See: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki // * (Compatibility) -func lockTimeToSequence(isSeconds bool, locktime uint32) uint32 { +func LockTimeToSequence(isSeconds bool, locktime uint32) uint32 { if !isSeconds { // The locktime is to be expressed in confirmations. return locktime diff --git a/lnwallet/script_utils_test.go b/input/script_utils_test.go similarity index 95% rename from lnwallet/script_utils_test.go rename to input/script_utils_test.go index 35525485..1c6c5bc9 100644 --- a/lnwallet/script_utils_test.go +++ b/input/script_utils_test.go @@ -1,4 +1,4 @@ -package lnwallet +package input import ( "bytes" @@ -146,7 +146,7 @@ func TestHTLCSenderSpendValidation(t *testing.T) { revocationKey := DeriveRevocationPubkey(bobKeyPub, commitPoint) // Generate the raw HTLC redemption scripts, and its p2wsh counterpart. - htlcWitnessScript, err := senderHTLCScript(aliceLocalKey, bobLocalKey, + htlcWitnessScript, err := SenderHTLCScript(aliceLocalKey, bobLocalKey, revocationKey, paymentHash[:]) if err != nil { t.Fatalf("unable to create htlc sender script: %v", err) @@ -188,8 +188,8 @@ func TestHTLCSenderSpendValidation(t *testing.T) { // Finally, we'll create mock signers for both of them based on their // private keys. This test simplifies a bit and uses the same key as // the base point for all scripts and derivations. - bobSigner := &mockSigner{privkeys: []*btcec.PrivateKey{bobKeyPriv}} - aliceSigner := &mockSigner{privkeys: []*btcec.PrivateKey{aliceKeyPriv}} + bobSigner := &MockSigner{Privkeys: []*btcec.PrivateKey{bobKeyPriv}} + aliceSigner := &MockSigner{Privkeys: []*btcec.PrivateKey{aliceKeyPriv}} // We'll also generate a signature on the sweep transaction above // that will act as Bob's signature to Alice for the second level HTLC @@ -230,7 +230,7 @@ func TestHTLCSenderSpendValidation(t *testing.T) { InputIndex: 0, } - return senderHtlcSpendRevoke(bobSigner, signDesc, + return SenderHtlcSpendRevokeWithKey(bobSigner, signDesc, revocationKey, sweepTx) }), true, @@ -295,7 +295,7 @@ func TestHTLCSenderSpendValidation(t *testing.T) { InputIndex: 0, } - return senderHtlcSpendTimeout(bobRecvrSig, aliceSigner, + return SenderHtlcSpendTimeout(bobRecvrSig, aliceSigner, signDesc, sweepTx) }), true, @@ -401,7 +401,7 @@ func TestHTLCReceiverSpendValidation(t *testing.T) { revocationKey := DeriveRevocationPubkey(aliceKeyPub, commitPoint) // Generate the raw HTLC redemption scripts, and its p2wsh counterpart. - htlcWitnessScript, err := receiverHTLCScript(cltvTimeout, aliceLocalKey, + htlcWitnessScript, err := ReceiverHTLCScript(cltvTimeout, aliceLocalKey, bobLocalKey, revocationKey, paymentHash[:]) if err != nil { t.Fatalf("unable to create htlc sender script: %v", err) @@ -446,8 +446,8 @@ func TestHTLCReceiverSpendValidation(t *testing.T) { // Finally, we'll create mock signers for both of them based on their // private keys. This test simplifies a bit and uses the same key as // the base point for all scripts and derivations. - bobSigner := &mockSigner{privkeys: []*btcec.PrivateKey{bobKeyPriv}} - aliceSigner := &mockSigner{privkeys: []*btcec.PrivateKey{aliceKeyPriv}} + bobSigner := &MockSigner{Privkeys: []*btcec.PrivateKey{bobKeyPriv}} + aliceSigner := &MockSigner{Privkeys: []*btcec.PrivateKey{aliceKeyPriv}} // We'll also generate a signature on the sweep transaction above // that will act as Alice's signature to Bob for the second level HTLC @@ -488,7 +488,7 @@ func TestHTLCReceiverSpendValidation(t *testing.T) { InputIndex: 0, } - return receiverHtlcSpendRedeem(aliceSenderSig, + return ReceiverHtlcSpendRedeem(aliceSenderSig, bytes.Repeat([]byte{1}, 45), bobSigner, signDesc, sweepTx) @@ -510,7 +510,7 @@ func TestHTLCReceiverSpendValidation(t *testing.T) { InputIndex: 0, } - return receiverHtlcSpendRedeem(aliceSenderSig, + return ReceiverHtlcSpendRedeem(aliceSenderSig, paymentPreimage[:], bobSigner, signDesc, sweepTx) }), @@ -531,7 +531,7 @@ func TestHTLCReceiverSpendValidation(t *testing.T) { InputIndex: 0, } - return receiverHtlcSpendRevoke(aliceSigner, + return ReceiverHtlcSpendRevokeWithKey(aliceSigner, signDesc, revocationKey, sweepTx) }), true, @@ -551,7 +551,7 @@ func TestHTLCReceiverSpendValidation(t *testing.T) { InputIndex: 0, } - return receiverHtlcSpendTimeout(aliceSigner, signDesc, + return ReceiverHtlcSpendTimeout(aliceSigner, signDesc, sweepTx, int32(cltvTimeout-2)) }), false, @@ -571,7 +571,7 @@ func TestHTLCReceiverSpendValidation(t *testing.T) { InputIndex: 0, } - return receiverHtlcSpendTimeout(aliceSigner, signDesc, + return ReceiverHtlcSpendTimeout(aliceSigner, signDesc, sweepTx, int32(cltvTimeout)) }), true, @@ -674,7 +674,7 @@ func TestSecondLevelHtlcSpends(t *testing.T) { // Finally we'll generate the HTLC script itself that we'll be spending // from. The revocation clause can be claimed by Alice, while Bob can // sweep the output after a particular delay. - htlcWitnessScript, err := secondLevelHtlcScript(revocationKey, + htlcWitnessScript, err := SecondLevelHtlcScript(revocationKey, delayKey, claimDelay) if err != nil { t.Fatalf("unable to create htlc script: %v", err) @@ -694,8 +694,8 @@ func TestSecondLevelHtlcSpends(t *testing.T) { // Finally, we'll create mock signers for both of them based on their // private keys. This test simplifies a bit and uses the same key as // the base point for all scripts and derivations. - bobSigner := &mockSigner{privkeys: []*btcec.PrivateKey{bobKeyPriv}} - aliceSigner := &mockSigner{privkeys: []*btcec.PrivateKey{aliceKeyPriv}} + bobSigner := &MockSigner{Privkeys: []*btcec.PrivateKey{bobKeyPriv}} + aliceSigner := &MockSigner{Privkeys: []*btcec.PrivateKey{aliceKeyPriv}} testCases := []struct { witness func() wire.TxWitness @@ -717,7 +717,7 @@ func TestSecondLevelHtlcSpends(t *testing.T) { InputIndex: 0, } - return htlcSpendRevoke(aliceSigner, signDesc, + return HtlcSpendRevoke(aliceSigner, signDesc, sweepTx) }), false, @@ -737,7 +737,7 @@ func TestSecondLevelHtlcSpends(t *testing.T) { InputIndex: 0, } - return htlcSpendRevoke(aliceSigner, signDesc, + return HtlcSpendRevoke(aliceSigner, signDesc, sweepTx) }), true, @@ -759,7 +759,7 @@ func TestSecondLevelHtlcSpends(t *testing.T) { InputIndex: 0, } - return htlcSpendSuccess(bobSigner, signDesc, + return HtlcSpendSuccess(bobSigner, signDesc, sweepTx, claimDelay-3) }), false, @@ -780,7 +780,7 @@ func TestSecondLevelHtlcSpends(t *testing.T) { InputIndex: 0, } - return htlcSpendSuccess(bobSigner, signDesc, + return HtlcSpendSuccess(bobSigner, signDesc, sweepTx, claimDelay) }), false, @@ -801,7 +801,7 @@ func TestSecondLevelHtlcSpends(t *testing.T) { InputIndex: 0, } - return htlcSpendSuccess(bobSigner, signDesc, + return HtlcSpendSuccess(bobSigner, signDesc, sweepTx, claimDelay) }), true, diff --git a/lnwallet/signdescriptor.go b/input/signdescriptor.go similarity index 99% rename from lnwallet/signdescriptor.go rename to input/signdescriptor.go index de8b8851..0dfb5d46 100644 --- a/lnwallet/signdescriptor.go +++ b/input/signdescriptor.go @@ -1,4 +1,4 @@ -package lnwallet +package input import ( "encoding/binary" diff --git a/lnwallet/signdescriptor_test.go b/input/signdescriptor_test.go similarity index 99% rename from lnwallet/signdescriptor_test.go rename to input/signdescriptor_test.go index 7f9d8eef..1e81e6ee 100644 --- a/lnwallet/signdescriptor_test.go +++ b/input/signdescriptor_test.go @@ -1,4 +1,4 @@ -package lnwallet +package input import ( "bytes" diff --git a/input/signer.go b/input/signer.go new file mode 100644 index 00000000..cd320255 --- /dev/null +++ b/input/signer.go @@ -0,0 +1,41 @@ +package input + +import ( + "github.com/btcsuite/btcd/wire" +) + +// Signer represents an abstract object capable of generating raw signatures as +// well as full complete input scripts given a valid SignDescriptor and +// transaction. This interface fully abstracts away signing paving the way for +// Signer implementations such as hardware wallets, hardware tokens, HSM's, or +// simply a regular wallet. +type Signer interface { + // SignOutputRaw generates a signature for the passed transaction + // according to the data within the passed SignDescriptor. + // + // NOTE: The resulting signature should be void of a sighash byte. + SignOutputRaw(tx *wire.MsgTx, signDesc *SignDescriptor) ([]byte, error) + + // ComputeInputScript generates a complete InputIndex for the passed + // transaction with the signature as defined within the passed + // SignDescriptor. This method should be capable of generating the + // proper input script for both regular p2wkh output and p2wkh outputs + // nested within a regular p2sh output. + // + // NOTE: This method will ignore any tweak parameters set within the + // passed SignDescriptor as it assumes a set of typical script + // templates (p2wkh, np2wkh, etc). + ComputeInputScript(tx *wire.MsgTx, signDesc *SignDescriptor) (*Script, error) +} + +// Script represents any script inputs required to redeem a previous +// output. This struct is used rather than just a witness, or scripSig in order +// to accommodate nested p2sh which utilizes both types of input scripts. +type Script struct { + // Witness is the full witness stack required to unlock this output. + Witness wire.TxWitness + + // SigScript will only be populated if this is an input script sweeping + // a nested p2sh output. + SigScript []byte +} diff --git a/lnwallet/size.go b/input/size.go similarity index 99% rename from lnwallet/size.go rename to input/size.go index a19653ab..07055dc8 100644 --- a/lnwallet/size.go +++ b/input/size.go @@ -1,4 +1,4 @@ -package lnwallet +package input import ( "github.com/btcsuite/btcd/blockchain" @@ -359,10 +359,10 @@ const ( OfferedHtlcPenaltyWitnessSize = 1 + 1 + 73 + 1 + 33 + 1 + OfferedHtlcScriptSize ) -// estimateCommitTxWeight estimate commitment transaction weight depending on +// EstimateCommitTxWeight estimate commitment transaction weight depending on // the precalculated weight of base transaction, witness data, which is needed // for paying for funding tx, and htlc weight multiplied by their count. -func estimateCommitTxWeight(count int, prediction bool) int64 { +func EstimateCommitTxWeight(count int, prediction bool) int64 { // Make prediction about the size of commitment transaction with // additional HTLC. if prediction { diff --git a/input/test_utils.go b/input/test_utils.go new file mode 100644 index 00000000..45c11f11 --- /dev/null +++ b/input/test_utils.go @@ -0,0 +1,189 @@ +package input + +import ( + "bytes" + "encoding/hex" + "fmt" + + "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" +) + +var ( + + // For simplicity a single priv key controls all of our test outputs. + testWalletPrivKey = []byte{ + 0x2b, 0xd8, 0x06, 0xc9, 0x7f, 0x0e, 0x00, 0xaf, + 0x1a, 0x1f, 0xc3, 0x32, 0x8f, 0xa7, 0x63, 0xa9, + 0x26, 0x97, 0x23, 0xc8, 0xdb, 0x8f, 0xac, 0x4f, + 0x93, 0xaf, 0x71, 0xdb, 0x18, 0x6d, 0x6e, 0x90, + } + + // We're alice :) + bobsPrivKey = []byte{ + 0x81, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda, + 0x63, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17, + 0xd, 0xe7, 0x95, 0xe4, 0xb7, 0x25, 0xb8, 0x4d, + 0x1e, 0xb, 0x4c, 0xfd, 0x9e, 0xc5, 0x8c, 0xe9, + } + + // Use a hard-coded HD seed. + testHdSeed = chainhash.Hash{ + 0xb7, 0x94, 0x38, 0x5f, 0x2d, 0x1e, 0xf7, 0xab, + 0x4d, 0x92, 0x73, 0xd1, 0x90, 0x63, 0x81, 0xb4, + 0x4f, 0x2f, 0x6f, 0x25, 0x88, 0xa3, 0xef, 0xb9, + 0x6a, 0x49, 0x18, 0x83, 0x31, 0x98, 0x47, 0x53, + } +) + +// 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 +} + +// SignOutputRaw generates a signature for the passed transaction according to +// the data within the passed SignDescriptor. +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 +} + +// ComputeInputScript generates a complete InputIndex for the passed transaction +// with the signature as defined within the passed SignDescriptor. This method +// should be capable of generating the proper input script for both regular +// p2wkh output and p2wkh outputs nested within a regular p2sh output. +func (m *MockSigner) ComputeInputScript(tx *wire.MsgTx, signDesc *SignDescriptor) (*Script, 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 &Script{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 &Script{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 +} + +// pubkeyFromHex parses a Bitcoin public key from a hex encoded string. +func pubkeyFromHex(keyHex string) (*btcec.PublicKey, error) { + bytes, err := hex.DecodeString(keyHex) + if err != nil { + return nil, err + } + return btcec.ParsePubKey(bytes, btcec.S256()) +} + +// privkeyFromHex parses a Bitcoin private key from a hex encoded string. +func privkeyFromHex(keyHex string) (*btcec.PrivateKey, error) { + bytes, err := hex.DecodeString(keyHex) + if err != nil { + return nil, err + } + key, _ := btcec.PrivKeyFromBytes(btcec.S256(), bytes) + return key, nil + +} + +// pubkeyToHex serializes a Bitcoin public key to a hex encoded string. +func pubkeyToHex(key *btcec.PublicKey) string { + return hex.EncodeToString(key.SerializeCompressed()) +} + +// privkeyFromHex serializes a Bitcoin private key to a hex encoded string. +func privkeyToHex(key *btcec.PrivateKey) string { + return hex.EncodeToString(key.Serialize()) +} diff --git a/lnwallet/txout.go b/input/txout.go similarity index 98% rename from lnwallet/txout.go rename to input/txout.go index 3cfb0f92..381c6be9 100644 --- a/lnwallet/txout.go +++ b/input/txout.go @@ -1,4 +1,4 @@ -package lnwallet +package input import ( "encoding/binary" diff --git a/lnwallet/txout_test.go b/input/txout_test.go similarity index 98% rename from lnwallet/txout_test.go rename to input/txout_test.go index 33e2909b..5587f192 100644 --- a/lnwallet/txout_test.go +++ b/input/txout_test.go @@ -1,4 +1,4 @@ -package lnwallet +package input import ( "bytes" diff --git a/lnwallet/witnessgen.go b/input/witnessgen.go similarity index 94% rename from lnwallet/witnessgen.go rename to input/witnessgen.go index 732836b5..32e547c6 100644 --- a/lnwallet/witnessgen.go +++ b/input/witnessgen.go @@ -1,4 +1,4 @@ -package lnwallet +package input import ( "fmt" @@ -125,7 +125,7 @@ func (wt WitnessType) String() string { // outputs. This function acts as an abstraction layer, hiding the details of // the underlying script. type WitnessGenerator func(tx *wire.MsgTx, hc *txscript.TxSigHashes, - inputIndex int) (*InputScript, error) + inputIndex int) (*Script, error) // GenWitnessFunc will return a WitnessGenerator function that an output uses // to generate the witness and optionally the sigScript for a sweep @@ -135,7 +135,7 @@ func (wt WitnessType) GenWitnessFunc(signer Signer, descriptor *SignDescriptor) WitnessGenerator { return func(tx *wire.MsgTx, hc *txscript.TxSigHashes, - inputIndex int) (*InputScript, error) { + inputIndex int) (*Script, error) { desc := descriptor desc.SigHashes = hc @@ -148,7 +148,7 @@ func (wt WitnessType) GenWitnessFunc(signer Signer, return nil, err } - return &InputScript{ + return &Script{ Witness: witness, }, nil @@ -158,7 +158,7 @@ func (wt WitnessType) GenWitnessFunc(signer Signer, return nil, err } - return &InputScript{ + return &Script{ Witness: witness, }, nil @@ -168,7 +168,7 @@ func (wt WitnessType) GenWitnessFunc(signer Signer, return nil, err } - return &InputScript{ + return &Script{ Witness: witness, }, nil @@ -178,7 +178,7 @@ func (wt WitnessType) GenWitnessFunc(signer Signer, return nil, err } - return &InputScript{ + return &Script{ Witness: witness, }, nil @@ -188,7 +188,7 @@ func (wt WitnessType) GenWitnessFunc(signer Signer, return nil, err } - return &InputScript{ + return &Script{ Witness: witness, }, nil @@ -198,7 +198,7 @@ func (wt WitnessType) GenWitnessFunc(signer Signer, return nil, err } - return &InputScript{ + return &Script{ Witness: witness, }, nil @@ -208,7 +208,7 @@ func (wt WitnessType) GenWitnessFunc(signer Signer, return nil, err } - return &InputScript{ + return &Script{ Witness: witness, }, nil @@ -216,22 +216,22 @@ func (wt WitnessType) GenWitnessFunc(signer Signer, // We pass in a value of -1 for the timeout, as we // expect the caller to have already set the lock time // value. - witness, err := receiverHtlcSpendTimeout(signer, desc, tx, -1) + witness, err := ReceiverHtlcSpendTimeout(signer, desc, tx, -1) if err != nil { return nil, err } - return &InputScript{ + return &Script{ Witness: witness, }, nil case HtlcSecondLevelRevoke: - witness, err := htlcSpendRevoke(signer, desc, tx) + witness, err := HtlcSpendRevoke(signer, desc, tx) if err != nil { return nil, err } - return &InputScript{ + return &Script{ Witness: witness, }, nil diff --git a/invoices/invoiceregistry.go b/invoices/invoiceregistry.go index 48123624..e330ccaa 100644 --- a/invoices/invoiceregistry.go +++ b/invoices/invoiceregistry.go @@ -4,11 +4,11 @@ import ( "bytes" "crypto/sha256" "fmt" - "github.com/btcsuite/btcd/chaincfg" "sync" "sync/atomic" "time" + "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcutil" "github.com/davecgh/go-spew/spew" diff --git a/lnrpc/signrpc/config_active.go b/lnrpc/signrpc/config_active.go index a72d8fbd..1e959ae4 100644 --- a/lnrpc/signrpc/config_active.go +++ b/lnrpc/signrpc/config_active.go @@ -3,7 +3,7 @@ package signrpc import ( - "github.com/lightningnetwork/lnd/lnwallet" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/macaroons" ) @@ -29,5 +29,5 @@ type Config struct { // Signer is the signer instance that backs the signer RPC server. The // job of the signer RPC server is simply to proxy valid requests to // the active signer instance. - Signer lnwallet.Signer + Signer input.Signer } diff --git a/lnrpc/signrpc/signer_server.go b/lnrpc/signrpc/signer_server.go index 9274c645..04ada861 100644 --- a/lnrpc/signrpc/signer_server.go +++ b/lnrpc/signrpc/signer_server.go @@ -13,9 +13,10 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lnwallet" + "google.golang.org/grpc" "gopkg.in/macaroon-bakery.v2/bakery" ) @@ -206,7 +207,7 @@ func (s *Server) SignOutputRaw(ctx context.Context, in *SignReq) (*SignResp, err // With the transaction deserialized, we'll now convert sign descs so // we can feed it into the actual signer. - signDescs := make([]*lnwallet.SignDescriptor, 0, len(in.SignDescs)) + signDescs := make([]*input.SignDescriptor, 0, len(in.SignDescs)) for _, signDesc := range in.SignDescs { keyDesc := signDesc.KeyDesc @@ -278,7 +279,7 @@ func (s *Server) SignOutputRaw(ctx context.Context, in *SignReq) (*SignResp, err // Finally, with verification and parsing complete, we can // construct the final sign descriptor to generate the proper // signature for this input. - signDescs = append(signDescs, &lnwallet.SignDescriptor{ + signDescs = append(signDescs, &input.SignDescriptor{ KeyDesc: keychain.KeyDescriptor{ KeyLocator: keyLoc, PubKey: targetPubKey, @@ -353,13 +354,13 @@ func (s *Server) ComputeInputScript(ctx context.Context, sigHashCache := txscript.NewTxSigHashes(&txToSign) - signDescs := make([]*lnwallet.SignDescriptor, 0, len(in.SignDescs)) + signDescs := make([]*input.SignDescriptor, 0, len(in.SignDescs)) for _, signDesc := range in.SignDescs { // For this method, the only fields that we care about are the // hash type, and the information concerning the output as we // only know how to provide full witnesses for outputs that we // solely control. - signDescs = append(signDescs, &lnwallet.SignDescriptor{ + signDescs = append(signDescs, &input.SignDescriptor{ Output: &wire.TxOut{ Value: signDesc.Output.Value, PkScript: signDesc.Output.PkScript, diff --git a/lnwallet/btcwallet/signer.go b/lnwallet/btcwallet/signer.go index f4530856..d09e4a38 100644 --- a/lnwallet/btcwallet/signer.go +++ b/lnwallet/btcwallet/signer.go @@ -10,6 +10,7 @@ import ( base "github.com/btcsuite/btcwallet/wallet" "github.com/btcsuite/btcwallet/walletdb" "github.com/go-errors/errors" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwallet" ) @@ -132,18 +133,18 @@ func (b *BtcWallet) fetchPrivKey(keyDesc *keychain.KeyDescriptor) (*btcec.Privat // maybeTweakPrivKey examines the single and double tweak parameters on the // passed sign descriptor and may perform a mapping on the passed private key // in order to utilize the tweaks, if populated. -func maybeTweakPrivKey(signDesc *lnwallet.SignDescriptor, +func maybeTweakPrivKey(signDesc *input.SignDescriptor, privKey *btcec.PrivateKey) (*btcec.PrivateKey, error) { var retPriv *btcec.PrivateKey switch { case signDesc.SingleTweak != nil: - retPriv = lnwallet.TweakPrivKey(privKey, + retPriv = input.TweakPrivKey(privKey, signDesc.SingleTweak) case signDesc.DoubleTweak != nil: - retPriv = lnwallet.DeriveRevocationPrivKey(privKey, + retPriv = input.DeriveRevocationPrivKey(privKey, signDesc.DoubleTweak) default: @@ -158,7 +159,7 @@ func maybeTweakPrivKey(signDesc *lnwallet.SignDescriptor, // // This is a part of the WalletController interface. func (b *BtcWallet) SignOutputRaw(tx *wire.MsgTx, - signDesc *lnwallet.SignDescriptor) ([]byte, error) { + signDesc *input.SignDescriptor) ([]byte, error) { witnessScript := signDesc.WitnessScript @@ -199,7 +200,7 @@ func (b *BtcWallet) SignOutputRaw(tx *wire.MsgTx, // // This is a part of the WalletController interface. func (b *BtcWallet) ComputeInputScript(tx *wire.MsgTx, - signDesc *lnwallet.SignDescriptor) (*lnwallet.InputScript, error) { + signDesc *input.SignDescriptor) (*input.Script, error) { outputScript := signDesc.Output.PkScript walletAddr, err := b.fetchOutputAddr(outputScript) @@ -214,7 +215,7 @@ func (b *BtcWallet) ComputeInputScript(tx *wire.MsgTx, } var witnessProgram []byte - inputScript := &lnwallet.InputScript{} + inputScript := &input.Script{} switch { @@ -282,7 +283,7 @@ func (b *BtcWallet) ComputeInputScript(tx *wire.MsgTx, // A compile time check to ensure that BtcWallet implements the Signer // interface. -var _ lnwallet.Signer = (*BtcWallet)(nil) +var _ input.Signer = (*BtcWallet)(nil) // SignMessage attempts to sign a target message with the private key that // corresponds to the passed public key. If the target private key is unable to diff --git a/lnwallet/channel.go b/lnwallet/channel.go index 9ed768e1..244f923c 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -9,17 +9,18 @@ import ( "sync" "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/davecgh/go-spew/spew" - "github.com/lightningnetwork/lnd/chainntnfs" - "github.com/lightningnetwork/lnd/channeldb" - "github.com/lightningnetwork/lnd/lnwire" - "github.com/btcsuite/btcd/btcec" + "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil/txsort" + "github.com/davecgh/go-spew/spew" + + "github.com/lightningnetwork/lnd/chainntnfs" + "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/input" + "github.com/lightningnetwork/lnd/lnwire" ) var zeroHash chainhash.Hash @@ -967,16 +968,16 @@ func deriveCommitmentKeys(commitPoint *btcec.PublicKey, isOurCommit bool, keyRing := &CommitmentKeyRing{ CommitPoint: commitPoint, - LocalCommitKeyTweak: SingleTweakBytes( + LocalCommitKeyTweak: input.SingleTweakBytes( commitPoint, localChanCfg.PaymentBasePoint.PubKey, ), - LocalHtlcKeyTweak: SingleTweakBytes( + LocalHtlcKeyTweak: input.SingleTweakBytes( commitPoint, localChanCfg.HtlcBasePoint.PubKey, ), - LocalHtlcKey: TweakPubKey( + LocalHtlcKey: input.TweakPubKey( localChanCfg.HtlcBasePoint.PubKey, commitPoint, ), - RemoteHtlcKey: TweakPubKey( + RemoteHtlcKey: input.TweakPubKey( remoteChanCfg.HtlcBasePoint.PubKey, commitPoint, ), } @@ -1003,9 +1004,9 @@ func deriveCommitmentKeys(commitPoint *btcec.PublicKey, isOurCommit bool, // With the base points assigned, we can now derive the actual keys // using the base point, and the current commitment tweak. - keyRing.DelayKey = TweakPubKey(delayBasePoint, commitPoint) - keyRing.NoDelayKey = TweakPubKey(noDelayBasePoint, commitPoint) - keyRing.RevocationKey = DeriveRevocationPubkey( + keyRing.DelayKey = input.TweakPubKey(delayBasePoint, commitPoint) + keyRing.NoDelayKey = input.TweakPubKey(noDelayBasePoint, commitPoint) + keyRing.RevocationKey = input.DeriveRevocationPubkey( revocationBasePoint, commitPoint, ) @@ -1285,11 +1286,11 @@ type LightningChannel struct { // Signer is the main signer instances that will be responsible for // signing any HTLC and commitment transaction generated by the state // machine. - Signer Signer + Signer input.Signer // signDesc is the primary sign descriptor that is capable of signing // the commitment transaction that spends the multi-sig output. - signDesc *SignDescriptor + signDesc *input.SignDescriptor channelEvents chainntnfs.ChainNotifier @@ -1363,7 +1364,7 @@ type LightningChannel struct { // settled channel state. Throughout state transitions, then channel will // automatically persist pertinent state to the database in an efficient // manner. -func NewLightningChannel(signer Signer, pCache PreimageCache, +func NewLightningChannel(signer input.Signer, pCache PreimageCache, state *channeldb.OpenChannel, sigPool *SigPool) (*LightningChannel, error) { @@ -1423,16 +1424,16 @@ func (lc *LightningChannel) createSignDesc() error { localKey := lc.localChanCfg.MultiSigKey.PubKey.SerializeCompressed() remoteKey := lc.remoteChanCfg.MultiSigKey.PubKey.SerializeCompressed() - multiSigScript, err := GenMultiSigScript(localKey, remoteKey) + multiSigScript, err := input.GenMultiSigScript(localKey, remoteKey) if err != nil { return err } - fundingPkScript, err := WitnessScriptHash(multiSigScript) + fundingPkScript, err := input.WitnessScriptHash(multiSigScript) if err != nil { return err } - lc.signDesc = &SignDescriptor{ + lc.signDesc = &input.SignDescriptor{ KeyDesc: lc.localChanCfg.MultiSigKey, WitnessScript: multiSigScript, Output: &wire.TxOut{ @@ -1616,7 +1617,7 @@ func (lc *LightningChannel) restoreCommitState( if err != nil { return err } - localCommitPoint := ComputeCommitmentPoint(ourRevPreImage[:]) + localCommitPoint := input.ComputeCommitmentPoint(ourRevPreImage[:]) remoteCommitPoint := lc.channelState.RemoteCurrentRevocation // With the revocation state reconstructed, we can now convert the disk @@ -1839,7 +1840,7 @@ type HtlcRetribution struct { // SignDesc is a design descriptor capable of generating the necessary // signatures to satisfy the revocation clause of the HTLC's public key // script. - SignDesc SignDescriptor + SignDesc input.SignDescriptor // OutPoint is the target outpoint of this HTLC pointing to the // breached commitment transaction. @@ -1895,7 +1896,7 @@ type BreachRetribution struct { // // NOTE: A nil value indicates that the local output is considered dust // according to the remote party's dust limit. - LocalOutputSignDesc *SignDescriptor + LocalOutputSignDesc *input.SignDescriptor // LocalOutpoint is the outpoint of the output paying to us (the local // party) within the breach transaction. @@ -1908,7 +1909,7 @@ type BreachRetribution struct { // // NOTE: A nil value indicates that the local output is considered dust // according to the remote party's dust limit. - RemoteOutputSignDesc *SignDescriptor + RemoteOutputSignDesc *input.SignDescriptor // RemoteOutpoint is the outpoint of the output paying to the remote // party within the breach transaction. @@ -1963,17 +1964,17 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, // number so we can have the proper witness script to sign and include // within the final witness. remoteDelay := uint32(chanState.RemoteChanCfg.CsvDelay) - remotePkScript, err := CommitScriptToSelf( + remotePkScript, err := input.CommitScriptToSelf( remoteDelay, keyRing.DelayKey, keyRing.RevocationKey, ) if err != nil { return nil, err } - remoteWitnessHash, err := WitnessScriptHash(remotePkScript) + remoteWitnessHash, err := input.WitnessScriptHash(remotePkScript) if err != nil { return nil, err } - localPkScript, err := CommitScriptUnencumbered(keyRing.NoDelayKey) + localPkScript, err := input.CommitScriptUnencumbered(keyRing.NoDelayKey) if err != nil { return nil, err } @@ -1999,8 +2000,8 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, // commitment outputs. If either is considered dust using the remote // party's dust limit, the respective sign descriptor will be nil. var ( - localSignDesc *SignDescriptor - remoteSignDesc *SignDescriptor + localSignDesc *input.SignDescriptor + remoteSignDesc *input.SignDescriptor ) // Compute the local and remote balances in satoshis. @@ -2010,7 +2011,7 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, // If the local balance exceeds the remote party's dust limit, // instantiate the local sign descriptor. if localAmt >= chanState.RemoteChanCfg.DustLimit { - localSignDesc = &SignDescriptor{ + localSignDesc = &input.SignDescriptor{ SingleTweak: keyRing.LocalCommitKeyTweak, KeyDesc: chanState.LocalChanCfg.PaymentBasePoint, WitnessScript: localPkScript, @@ -2025,7 +2026,7 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, // Similarly, if the remote balance exceeds the remote party's dust // limit, assemble the remote sign descriptor. if remoteAmt >= chanState.RemoteChanCfg.DustLimit { - remoteSignDesc = &SignDescriptor{ + remoteSignDesc = &input.SignDescriptor{ KeyDesc: chanState.LocalChanCfg.RevocationBasePoint, DoubleTweak: commitmentSecret, WitnessScript: remotePkScript, @@ -2061,7 +2062,7 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, // as we'll need it if we're revoking an HTLC output on the // remote commitment transaction, and *they* go to the second // level. - secondLevelWitnessScript, err := secondLevelHtlcScript( + secondLevelWitnessScript, err := input.SecondLevelHtlcScript( keyRing.RevocationKey, keyRing.DelayKey, remoteDelay, ) if err != nil { @@ -2072,7 +2073,7 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, // the sender of the HTLC (relative to us). So we'll // re-generate the sender HTLC script. if htlc.Incoming { - htlcWitnessScript, err = senderHTLCScript( + htlcWitnessScript, err = input.SenderHTLCScript( keyRing.RemoteHtlcKey, keyRing.LocalHtlcKey, keyRing.RevocationKey, htlc.RHash[:], ) @@ -2084,7 +2085,7 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, // Otherwise, is this was an outgoing HTLC that we // sent, then from the PoV of the remote commitment // state, they're the receiver of this HTLC. - htlcWitnessScript, err = receiverHTLCScript( + htlcWitnessScript, err = input.ReceiverHTLCScript( htlc.RefundTimeout, keyRing.LocalHtlcKey, keyRing.RemoteHtlcKey, keyRing.RevocationKey, htlc.RHash[:], @@ -2094,13 +2095,13 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, } } - htlcPkScript, err := WitnessScriptHash(htlcWitnessScript) + htlcPkScript, err := input.WitnessScriptHash(htlcWitnessScript) if err != nil { return nil, err } htlcRetributions = append(htlcRetributions, HtlcRetribution{ - SignDesc: SignDescriptor{ + SignDesc: input.SignDescriptor{ KeyDesc: chanState.LocalChanCfg.RevocationBasePoint, DoubleTweak: commitmentSecret, WitnessScript: htlcWitnessScript, @@ -2141,13 +2142,13 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, // htlcTimeoutFee returns the fee in satoshis required for an HTLC timeout // transaction based on the current fee rate. func htlcTimeoutFee(feePerKw SatPerKWeight) btcutil.Amount { - return feePerKw.FeeForWeight(HtlcTimeoutWeight) + return feePerKw.FeeForWeight(input.HtlcTimeoutWeight) } // htlcSuccessFee returns the fee in satoshis required for an HTLC success // transaction based on the current fee rate. func htlcSuccessFee(feePerKw SatPerKWeight) btcutil.Amount { - return feePerKw.FeeForWeight(HtlcSuccessWeight) + return feePerKw.FeeForWeight(input.HtlcSuccessWeight) } // htlcIsDust determines if an HTLC output is dust or not depending on two @@ -2344,7 +2345,7 @@ func (lc *LightningChannel) createCommitmentTx(c *commitment, // on its total weight. Once we have the total weight, we'll multiply // by the current fee-per-kw, then divide by 1000 to get the proper // fee. - totalCommitWeight := CommitWeight + (HtlcWeight * numHTLCs) + totalCommitWeight := input.CommitWeight + (input.HtlcWeight * numHTLCs) // With the weight known, we can now calculate the commitment fee, // ensuring that we account for any dust outputs trimmed above. @@ -2793,7 +2794,7 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing, // 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. - sigJob.SignDesc = SignDescriptor{ + sigJob.SignDesc = input.SignDescriptor{ KeyDesc: localChanCfg.HtlcBasePoint, SingleTweak: keyRing.LocalHtlcKeyTweak, WitnessScript: htlc.theirWitnessScript, @@ -2844,7 +2845,7 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing, // 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. - sigJob.SignDesc = SignDescriptor{ + sigJob.SignDesc = input.SignDescriptor{ KeyDesc: localChanCfg.HtlcBasePoint, SingleTweak: keyRing.LocalHtlcKeyTweak, WitnessScript: htlc.theirWitnessScript, @@ -3539,7 +3540,7 @@ func ChanSyncMsg(c *channeldb.OpenChannel) (*lnwire.ChannelReestablish, error) { NextLocalCommitHeight: nextLocalCommitHeight, RemoteCommitTailHeight: remoteChainTipHeight, LastRemoteCommitSecret: lastCommitSecret, - LocalUnrevokedCommitPoint: ComputeCommitmentPoint( + LocalUnrevokedCommitPoint: input.ComputeCommitmentPoint( currentCommitSecret[:], ), }, nil @@ -3607,7 +3608,7 @@ func (lc *LightningChannel) computeView(view *htlcView, remoteChain bool, continue } - totalHtlcWeight += HtlcWeight + totalHtlcWeight += input.HtlcWeight } for _, htlc := range filteredHTLCView.theirUpdates { if htlcIsDust(!remoteChain, !remoteChain, feePerKw, @@ -3615,10 +3616,10 @@ func (lc *LightningChannel) computeView(view *htlcView, remoteChain bool, continue } - totalHtlcWeight += HtlcWeight + totalHtlcWeight += input.HtlcWeight } - totalCommitWeight := CommitWeight + totalHtlcWeight + totalCommitWeight := input.CommitWeight + totalHtlcWeight return ourBalance, theirBalance, totalCommitWeight, filteredHTLCView } @@ -4011,7 +4012,7 @@ func (lc *LightningChannel) ReceiveNewCommitment(commitSig lnwire.Sig, if err != nil { return err } - commitPoint := ComputeCommitmentPoint(commitSecret[:]) + commitPoint := input.ComputeCommitmentPoint(commitSecret[:]) keyRing := deriveCommitmentKeys(commitPoint, true, lc.localChanCfg, lc.remoteChanCfg) @@ -4238,7 +4239,7 @@ func (lc *LightningChannel) ReceiveRevocation(revMsg *lnwire.RevokeAndAck) ( // revealed secret to derive a revocation key with our revocation base // point, then it matches the current revocation of the remote party. currentCommitPoint := lc.channelState.RemoteCurrentRevocation - derivedCommitPoint := ComputeCommitmentPoint(revMsg.Revocation[:]) + derivedCommitPoint := input.ComputeCommitmentPoint(revMsg.Revocation[:]) if !derivedCommitPoint.IsEqual(currentCommitPoint) { return nil, nil, nil, fmt.Errorf("revocation key mismatch") } @@ -4476,7 +4477,7 @@ func (lc *LightningChannel) NextRevocationKey() (*btcec.PublicKey, error) { return nil, err } - return ComputeCommitmentPoint(revocation[:]), nil + return input.ComputeCommitmentPoint(revocation[:]), nil } // InitNextRevocation inserts the passed commitment point as the _next_ @@ -4852,7 +4853,7 @@ func genHtlcScript(isIncoming, ourCommit bool, timeout uint32, rHash [32]byte, // transaction. So we need to use the receiver's version of HTLC the // script. case isIncoming && ourCommit: - witnessScript, err = receiverHTLCScript(timeout, + witnessScript, err = input.ReceiverHTLCScript(timeout, keyRing.RemoteHtlcKey, keyRing.LocalHtlcKey, keyRing.RevocationKey, rHash[:]) @@ -4860,21 +4861,21 @@ func genHtlcScript(isIncoming, ourCommit bool, timeout uint32, rHash [32]byte, // being added to their commitment transaction, so we use the sender's // version of the HTLC script. case isIncoming && !ourCommit: - witnessScript, err = senderHTLCScript(keyRing.RemoteHtlcKey, + witnessScript, err = input.SenderHTLCScript(keyRing.RemoteHtlcKey, keyRing.LocalHtlcKey, keyRing.RevocationKey, rHash[:]) // We're sending an HTLC which is being added to our commitment // transaction. Therefore, we need to use the sender's version of the // HTLC script. case !isIncoming && ourCommit: - witnessScript, err = senderHTLCScript(keyRing.LocalHtlcKey, + witnessScript, err = input.SenderHTLCScript(keyRing.LocalHtlcKey, keyRing.RemoteHtlcKey, keyRing.RevocationKey, rHash[:]) // Finally, we're paying the remote party via an HTLC, which is being // added to their commitment transaction. Therefore, we use the // receiver's version of the HTLC script. case !isIncoming && !ourCommit: - witnessScript, err = receiverHTLCScript(timeout, keyRing.LocalHtlcKey, + witnessScript, err = input.ReceiverHTLCScript(timeout, keyRing.LocalHtlcKey, keyRing.RemoteHtlcKey, keyRing.RevocationKey, rHash[:]) } if err != nil { @@ -4883,7 +4884,7 @@ func genHtlcScript(isIncoming, ourCommit bool, timeout uint32, rHash [32]byte, // Now that we have the redeem scripts, create the P2WSH public key // script for the output itself. - htlcP2WSH, err := WitnessScriptHash(witnessScript) + htlcP2WSH, err := input.WitnessScriptHash(witnessScript) if err != nil { return nil, nil, err } @@ -4952,7 +4953,7 @@ func (lc *LightningChannel) getSignedCommitTx() (*wire.MsgTx, error) { ourKey := lc.localChanCfg.MultiSigKey.PubKey.SerializeCompressed() theirKey := lc.remoteChanCfg.MultiSigKey.PubKey.SerializeCompressed() - commitTx.TxIn[0].Witness = SpendMultiSig( + commitTx.TxIn[0].Witness = input.SpendMultiSig( lc.signDesc.WitnessScript, ourKey, ourSig, theirKey, theirSig, ) @@ -4970,7 +4971,7 @@ type CommitOutputResolution struct { // SelfOutputSignDesc is a fully populated sign descriptor capable of // generating a valid signature to sweep the output paying to us. - SelfOutputSignDesc SignDescriptor + SelfOutputSignDesc input.SignDescriptor // MaturityDelay is the relative time-lock, in blocks for all outputs // that pay to the local party within the broadcast commitment @@ -5026,7 +5027,7 @@ type UnilateralCloseSummary struct { // happen in case we have lost state) it should be set to an empty struct, in // which case we will attempt to sweep the non-HTLC output using the passed // commitPoint. -func NewUnilateralCloseSummary(chanState *channeldb.OpenChannel, signer Signer, +func NewUnilateralCloseSummary(chanState *channeldb.OpenChannel, signer input.Signer, pCache PreimageCache, commitSpend *chainntnfs.SpendDetail, remoteCommit channeldb.ChannelCommitment, commitPoint *btcec.PublicKey) (*UnilateralCloseSummary, error) { @@ -5054,7 +5055,7 @@ func NewUnilateralCloseSummary(chanState *channeldb.OpenChannel, signer Signer, // Before we can generate the proper sign descriptor, we'll need to // locate the output index of our non-delayed output on the commitment // transaction. - selfP2WKH, err := CommitScriptUnencumbered(keyRing.NoDelayKey) + selfP2WKH, err := input.CommitScriptUnencumbered(keyRing.NoDelayKey) if err != nil { return nil, fmt.Errorf("unable to create self commit script: %v", err) } @@ -5083,7 +5084,7 @@ func NewUnilateralCloseSummary(chanState *channeldb.OpenChannel, signer Signer, localPayBase := chanState.LocalChanCfg.PaymentBasePoint commitResolution = &CommitOutputResolution{ SelfOutPoint: *selfPoint, - SelfOutputSignDesc: SignDescriptor{ + SelfOutputSignDesc: input.SignDescriptor{ KeyDesc: localPayBase, SingleTweak: keyRing.LocalCommitKeyTweak, WitnessScript: selfP2WKH, @@ -5170,7 +5171,7 @@ type IncomingHtlcResolution struct { // SweepSignDesc is a sign descriptor that has been populated with the // necessary items required to spend the sole output of the above // transaction. - SweepSignDesc SignDescriptor + SweepSignDesc input.SignDescriptor } // OutgoingHtlcResolution houses the information necessary to sweep any @@ -5210,7 +5211,7 @@ type OutgoingHtlcResolution struct { // SweepSignDesc is a sign descriptor that has been populated with the // necessary items required to spend the sole output of the above // transaction. - SweepSignDesc SignDescriptor + SweepSignDesc input.SignDescriptor } // HtlcResolutions contains the items necessary to sweep HTLC's on chain @@ -5230,7 +5231,7 @@ type HtlcResolutions struct { // newOutgoingHtlcResolution generates a new HTLC resolution capable of // allowing the caller to sweep an outgoing HTLC present on either their, or // the remote party's commitment transaction. -func newOutgoingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig, +func newOutgoingHtlcResolution(signer input.Signer, localChanCfg *channeldb.ChannelConfig, commitHash chainhash.Hash, htlc *channeldb.HTLC, keyRing *CommitmentKeyRing, feePerKw SatPerKWeight, dustLimit btcutil.Amount, csvDelay uint32, localCommit bool, ) (*OutgoingHtlcResolution, error) { @@ -5246,14 +5247,14 @@ func newOutgoingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon if !localCommit { // First, we'll re-generate the script used to send the HTLC to // the remote party within their commitment transaction. - htlcReceiverScript, err := receiverHTLCScript(htlc.RefundTimeout, + htlcReceiverScript, err := input.ReceiverHTLCScript(htlc.RefundTimeout, keyRing.LocalHtlcKey, keyRing.RemoteHtlcKey, keyRing.RevocationKey, htlc.RHash[:], ) if err != nil { return nil, err } - htlcScriptHash, err := WitnessScriptHash(htlcReceiverScript) + htlcScriptHash, err := input.WitnessScriptHash(htlcReceiverScript) if err != nil { return nil, err } @@ -5263,7 +5264,7 @@ func newOutgoingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon return &OutgoingHtlcResolution{ Expiry: htlc.RefundTimeout, ClaimOutpoint: op, - SweepSignDesc: SignDescriptor{ + SweepSignDesc: input.SignDescriptor{ KeyDesc: localChanCfg.HtlcBasePoint, SingleTweak: keyRing.LocalHtlcKeyTweak, WitnessScript: htlcReceiverScript, @@ -5298,12 +5299,12 @@ func newOutgoingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon // With the transaction created, we can generate a sign descriptor // that's capable of generating the signature required to spend the // HTLC output using the timeout transaction. - htlcCreationScript, err := senderHTLCScript(keyRing.LocalHtlcKey, + htlcCreationScript, err := input.SenderHTLCScript(keyRing.LocalHtlcKey, keyRing.RemoteHtlcKey, keyRing.RevocationKey, htlc.RHash[:]) if err != nil { return nil, err } - timeoutSignDesc := SignDescriptor{ + timeoutSignDesc := input.SignDescriptor{ KeyDesc: localChanCfg.HtlcBasePoint, SingleTweak: keyRing.LocalHtlcKeyTweak, WitnessScript: htlcCreationScript, @@ -5317,7 +5318,7 @@ func newOutgoingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon // With the sign desc created, we can now construct the full witness // for the timeout transaction, and populate it as well. - timeoutWitness, err := senderHtlcSpendTimeout( + timeoutWitness, err := input.SenderHtlcSpendTimeout( htlc.Signature, signer, &timeoutSignDesc, timeoutTx, ) if err != nil { @@ -5328,18 +5329,18 @@ func newOutgoingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon // Finally, we'll generate the script output that the timeout // transaction creates so we can generate the signDesc required to // complete the claim process after a delay period. - htlcSweepScript, err := secondLevelHtlcScript( + htlcSweepScript, err := input.SecondLevelHtlcScript( keyRing.RevocationKey, keyRing.DelayKey, csvDelay, ) if err != nil { return nil, err } - htlcScriptHash, err := WitnessScriptHash(htlcSweepScript) + htlcScriptHash, err := input.WitnessScriptHash(htlcSweepScript) if err != nil { return nil, err } - localDelayTweak := SingleTweakBytes( + localDelayTweak := input.SingleTweakBytes( keyRing.CommitPoint, localChanCfg.DelayBasePoint.PubKey, ) return &OutgoingHtlcResolution{ @@ -5350,7 +5351,7 @@ func newOutgoingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon Hash: timeoutTx.TxHash(), Index: 0, }, - SweepSignDesc: SignDescriptor{ + SweepSignDesc: input.SignDescriptor{ KeyDesc: localChanCfg.DelayBasePoint, SingleTweak: localDelayTweak, WitnessScript: htlcSweepScript, @@ -5370,7 +5371,7 @@ func newOutgoingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon // they can just sweep the output immediately with knowledge of the pre-image. // // TODO(roasbeef) consolidate code with above func -func newIncomingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig, +func newIncomingHtlcResolution(signer input.Signer, localChanCfg *channeldb.ChannelConfig, commitHash chainhash.Hash, htlc *channeldb.HTLC, keyRing *CommitmentKeyRing, feePerKw SatPerKWeight, dustLimit btcutil.Amount, csvDelay uint32, localCommit bool, preimage [32]byte) (*IncomingHtlcResolution, error) { @@ -5385,14 +5386,14 @@ func newIncomingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon if !localCommit { // First, we'll re-generate the script the remote party used to // send the HTLC to us in their commitment transaction. - htlcSenderScript, err := senderHTLCScript( + htlcSenderScript, err := input.SenderHTLCScript( keyRing.RemoteHtlcKey, keyRing.LocalHtlcKey, keyRing.RevocationKey, htlc.RHash[:], ) if err != nil { return nil, err } - htlcScriptHash, err := WitnessScriptHash(htlcSenderScript) + htlcScriptHash, err := input.WitnessScriptHash(htlcSenderScript) if err != nil { return nil, err } @@ -5403,7 +5404,7 @@ func newIncomingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon Preimage: preimage, ClaimOutpoint: op, CsvDelay: csvDelay, - SweepSignDesc: SignDescriptor{ + SweepSignDesc: input.SignDescriptor{ KeyDesc: localChanCfg.HtlcBasePoint, SingleTweak: keyRing.LocalHtlcKeyTweak, WitnessScript: htlcSenderScript, @@ -5432,14 +5433,14 @@ func newIncomingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon // Once we've created the second-level transaction, we'll generate the // SignDesc needed spend the HTLC output using the success transaction. - htlcCreationScript, err := receiverHTLCScript(htlc.RefundTimeout, + htlcCreationScript, err := input.ReceiverHTLCScript(htlc.RefundTimeout, keyRing.RemoteHtlcKey, keyRing.LocalHtlcKey, keyRing.RevocationKey, htlc.RHash[:], ) if err != nil { return nil, err } - successSignDesc := SignDescriptor{ + successSignDesc := input.SignDescriptor{ KeyDesc: localChanCfg.HtlcBasePoint, SingleTweak: keyRing.LocalHtlcKeyTweak, WitnessScript: htlcCreationScript, @@ -5453,7 +5454,7 @@ func newIncomingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon // Next, we'll construct the full witness needed to satisfy the input // of the success transaction. - successWitness, err := receiverHtlcSpendRedeem( + successWitness, err := input.ReceiverHtlcSpendRedeem( htlc.Signature, preimage[:], signer, &successSignDesc, successTx, ) if err != nil { @@ -5464,18 +5465,18 @@ func newIncomingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon // Finally, we'll generate the script that the second-level transaction // creates so we can generate the proper signDesc to sweep it after the // CSV delay has passed. - htlcSweepScript, err := secondLevelHtlcScript( + htlcSweepScript, err := input.SecondLevelHtlcScript( keyRing.RevocationKey, keyRing.DelayKey, csvDelay, ) if err != nil { return nil, err } - htlcScriptHash, err := WitnessScriptHash(htlcSweepScript) + htlcScriptHash, err := input.WitnessScriptHash(htlcSweepScript) if err != nil { return nil, err } - localDelayTweak := SingleTweakBytes( + localDelayTweak := input.SingleTweakBytes( keyRing.CommitPoint, localChanCfg.DelayBasePoint.PubKey, ) return &IncomingHtlcResolution{ @@ -5486,7 +5487,7 @@ func newIncomingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon Hash: successTx.TxHash(), Index: 0, }, - SweepSignDesc: SignDescriptor{ + SweepSignDesc: input.SignDescriptor{ KeyDesc: localChanCfg.DelayBasePoint, SingleTweak: localDelayTweak, WitnessScript: htlcSweepScript, @@ -5527,7 +5528,7 @@ func (r *OutgoingHtlcResolution) HtlcPoint() wire.OutPoint { // the local key used when generating the HTLC scrips. This function is to be // used in two cases: force close, or a unilateral close. func extractHtlcResolutions(feePerKw SatPerKWeight, ourCommit bool, - signer Signer, htlcs []channeldb.HTLC, keyRing *CommitmentKeyRing, + signer input.Signer, htlcs []channeldb.HTLC, keyRing *CommitmentKeyRing, localChanCfg, remoteChanCfg *channeldb.ChannelConfig, commitHash chainhash.Hash, pCache PreimageCache) (*HtlcResolutions, error) { @@ -5672,7 +5673,7 @@ func (lc *LightningChannel) ForceClose() (*LocalForceCloseSummary, error) { // NewLocalForceCloseSummary generates a LocalForceCloseSummary from the given // channel state. The passed commitTx must be a fully signed commitment // transaction corresponding to localCommit. -func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel, signer Signer, +func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel, signer input.Signer, pCache PreimageCache, commitTx *wire.MsgTx, localCommit channeldb.ChannelCommitment) (*LocalForceCloseSummary, error) { @@ -5687,15 +5688,15 @@ func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel, signer Signer, if err != nil { return nil, err } - commitPoint := ComputeCommitmentPoint(revocation[:]) + commitPoint := input.ComputeCommitmentPoint(revocation[:]) keyRing := deriveCommitmentKeys(commitPoint, true, &chanState.LocalChanCfg, &chanState.RemoteChanCfg) - selfScript, err := CommitScriptToSelf(csvTimeout, keyRing.DelayKey, + selfScript, err := input.CommitScriptToSelf(csvTimeout, keyRing.DelayKey, keyRing.RevocationKey) if err != nil { return nil, err } - payToUsScriptHash, err := WitnessScriptHash(selfScript) + payToUsScriptHash, err := input.WitnessScriptHash(selfScript) if err != nil { return nil, err } @@ -5725,7 +5726,7 @@ func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel, signer Signer, // nil. var commitResolution *CommitOutputResolution if len(delayScript) != 0 { - singleTweak := SingleTweakBytes( + singleTweak := input.SingleTweakBytes( commitPoint, chanState.LocalChanCfg.DelayBasePoint.PubKey, ) localBalance := localCommit.LocalBalance @@ -5734,7 +5735,7 @@ func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel, signer Signer, Hash: commitTx.TxHash(), Index: delayIndex, }, - SelfOutputSignDesc: SignDescriptor{ + SelfOutputSignDesc: input.SignDescriptor{ KeyDesc: chanState.LocalChanCfg.DelayBasePoint, SingleTweak: singleTweak, WitnessScript: selfScript, @@ -5896,7 +5897,7 @@ func (lc *LightningChannel) CompleteCooperativeClose(localSig, remoteSig []byte, // pubkeys+sigs on the stack. ourKey := lc.localChanCfg.MultiSigKey.PubKey.SerializeCompressed() theirKey := lc.remoteChanCfg.MultiSigKey.PubKey.SerializeCompressed() - witness := SpendMultiSig(lc.signDesc.WitnessScript, ourKey, + witness := input.SpendMultiSig(lc.signDesc.WitnessScript, ourKey, localSig, theirKey, remoteSig) closeTx.TxIn[0].Witness = witness @@ -6101,7 +6102,7 @@ func (lc *LightningChannel) generateRevocation(height uint64) (*lnwire.RevokeAnd return nil, err } - revocationMsg.NextRevocationKey = ComputeCommitmentPoint(nextCommitSecret[:]) + revocationMsg.NextRevocationKey = input.ComputeCommitmentPoint(nextCommitSecret[:]) revocationMsg.ChanID = lnwire.NewChanIDFromOutPoint( &lc.channelState.FundingOutpoint) @@ -6122,19 +6123,19 @@ func CreateCommitTx(fundingOutput wire.TxIn, // output after a relative block delay, or the remote node can claim // the funds with the revocation key if we broadcast a revoked // commitment transaction. - ourRedeemScript, err := CommitScriptToSelf(csvTimeout, keyRing.DelayKey, + ourRedeemScript, err := input.CommitScriptToSelf(csvTimeout, keyRing.DelayKey, keyRing.RevocationKey) if err != nil { return nil, err } - payToUsScriptHash, err := WitnessScriptHash(ourRedeemScript) + payToUsScriptHash, err := input.WitnessScriptHash(ourRedeemScript) if err != nil { return nil, err } // Next, we create the script paying to them. This is just a regular // P2WPKH output, without any added CSV delay. - theirWitnessKeyHash, err := CommitScriptUnencumbered(keyRing.NoDelayKey) + theirWitnessKeyHash, err := input.CommitScriptUnencumbered(keyRing.NoDelayKey) if err != nil { return nil, err } @@ -6203,7 +6204,7 @@ func CreateCooperativeCloseTx(fundingTxIn wire.TxIn, // CalcFee returns the commitment fee to use for the given // fee rate (fee-per-kw). func (lc *LightningChannel) CalcFee(feeRate SatPerKWeight) btcutil.Amount { - return feeRate.FeeForWeight(CommitWeight) + return feeRate.FeeForWeight(input.CommitWeight) } // RemoteNextRevocation returns the channelState's RemoteNextRevocation. diff --git a/lnwallet/channel_test.go b/lnwallet/channel_test.go index f9e4821a..92fae95e 100644 --- a/lnwallet/channel_test.go +++ b/lnwallet/channel_test.go @@ -18,6 +18,7 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwire" ) @@ -403,7 +404,7 @@ func TestCheckCommitTxSize(t *testing.T) { } actualCost := blockchain.GetTransactionWeight(btcutil.NewTx(commitTx)) - estimatedCost := estimateCommitTxWeight(count, false) + estimatedCost := input.EstimateCommitTxWeight(count, false) diff := int(estimatedCost - actualCost) if 0 > diff || BaseCommitmentTxSizeEstimationError < diff { @@ -624,7 +625,7 @@ func TestForceClose(t *testing.T) { // Factoring in the fee rate, Alice's amount should properly reflect // that we've added two additional HTLC to the commitment transaction. - totalCommitWeight := CommitWeight + (HtlcWeight * 2) + totalCommitWeight := input.CommitWeight + (input.HtlcWeight * 2) feePerKw := SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw) commitFee := feePerKw.FeeForWeight(totalCommitWeight) expectedAmount := (aliceChannel.Capacity / 2) - htlcAmount.ToSatoshis() - commitFee @@ -680,7 +681,7 @@ func TestForceClose(t *testing.T) { Value: htlcResolution.SweepSignDesc.Output.Value, }) htlcResolution.SweepSignDesc.InputIndex = 0 - sweepTx.TxIn[0].Witness, err = htlcSpendSuccess(aliceChannel.Signer, + sweepTx.TxIn[0].Witness, err = input.HtlcSpendSuccess(aliceChannel.Signer, &htlcResolution.SweepSignDesc, sweepTx, uint32(aliceChannel.channelState.LocalChanCfg.CsvDelay)) if err != nil { @@ -741,7 +742,7 @@ func TestForceClose(t *testing.T) { Value: inHtlcResolution.SweepSignDesc.Output.Value, }) inHtlcResolution.SweepSignDesc.InputIndex = 0 - sweepTx.TxIn[0].Witness, err = htlcSpendSuccess(aliceChannel.Signer, + sweepTx.TxIn[0].Witness, err = input.HtlcSpendSuccess(aliceChannel.Signer, &inHtlcResolution.SweepSignDesc, sweepTx, uint32(aliceChannel.channelState.LocalChanCfg.CsvDelay)) if err != nil { @@ -4789,7 +4790,7 @@ func TestChannelUnilateralCloseHtlcResolution(t *testing.T) { // With the transaction constructed, we'll generate a witness that // should be valid for it, and verify using an instance of Script. - sweepTx.TxIn[0].Witness, err = receiverHtlcSpendTimeout( + sweepTx.TxIn[0].Witness, err = input.ReceiverHtlcSpendTimeout( aliceChannel.Signer, &outHtlcResolution.SweepSignDesc, sweepTx, int32(outHtlcResolution.Expiry), ) @@ -4823,7 +4824,7 @@ func TestChannelUnilateralCloseHtlcResolution(t *testing.T) { inHtlcResolution.SweepSignDesc.SigHashes = txscript.NewTxSigHashes( sweepTx, ) - sweepTx.TxIn[0].Witness, err = SenderHtlcSpendRedeem( + sweepTx.TxIn[0].Witness, err = input.SenderHtlcSpendRedeem( aliceChannel.Signer, &inHtlcResolution.SweepSignDesc, sweepTx, preimageBob[:], ) @@ -4954,7 +4955,7 @@ func TestChannelUnilateralClosePendingCommit(t *testing.T) { Value: aliceSignDesc.Output.Value, }) aliceSignDesc.SigHashes = txscript.NewTxSigHashes(sweepTx) - sweepTx.TxIn[0].Witness, err = CommitSpendNoDelay( + sweepTx.TxIn[0].Witness, err = input.CommitSpendNoDelay( aliceChannel.Signer, &aliceSignDesc, sweepTx, ) if err != nil { diff --git a/lnwallet/config.go b/lnwallet/config.go index 350adace..e86a8cbe 100644 --- a/lnwallet/config.go +++ b/lnwallet/config.go @@ -4,6 +4,7 @@ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" ) @@ -37,7 +38,7 @@ type Config struct { // used to generate signature for all inputs to potential funding // transactions, as well as for spends from the funding transaction to // update the commitment state. - Signer Signer + Signer input.Signer // FeeEstimator is the implementation that the wallet will use for the // calculation of on-chain transaction fees. diff --git a/lnwallet/interface.go b/lnwallet/interface.go index efe8b619..1fe245d6 100644 --- a/lnwallet/interface.go +++ b/lnwallet/interface.go @@ -253,30 +253,6 @@ type BlockChainIO interface { GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error) } -// Signer represents an abstract object capable of generating raw signatures as -// well as full complete input scripts given a valid SignDescriptor and -// transaction. This interface fully abstracts away signing paving the way for -// Signer implementations such as hardware wallets, hardware tokens, HSM's, or -// simply a regular wallet. -type Signer interface { - // SignOutputRaw generates a signature for the passed transaction - // according to the data within the passed SignDescriptor. - // - // NOTE: The resulting signature should be void of a sighash byte. - SignOutputRaw(tx *wire.MsgTx, signDesc *SignDescriptor) ([]byte, error) - - // ComputeInputScript generates a complete InputIndex for the passed - // transaction with the signature as defined within the passed - // SignDescriptor. This method should be capable of generating the - // proper input script for both regular p2wkh output and p2wkh outputs - // nested within a regular p2sh output. - // - // NOTE: This method will ignore any tweak parameters set within the - // passed SignDescriptor as it assumes a set of typical script - // templates (p2wkh, np2wkh, etc). - ComputeInputScript(tx *wire.MsgTx, signDesc *SignDescriptor) (*InputScript, error) -} - // MessageSigner represents an abstract object capable of signing arbitrary // messages. The capabilities of this interface are used to sign announcements // to the network, or just arbitrary messages that leverage the wallet's keys diff --git a/lnwallet/interface_test.go b/lnwallet/interface_test.go index 4549a266..7d5ad904 100644 --- a/lnwallet/interface_test.go +++ b/lnwallet/interface_test.go @@ -35,6 +35,7 @@ import ( "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/chainntnfs/btcdnotify" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet/btcwallet" @@ -353,7 +354,7 @@ func loadTestCredits(miner *rpctest.Harness, w *lnwallet.LightningWallet, func createTestWallet(tempTestDir string, miningNode *rpctest.Harness, netParams *chaincfg.Params, notifier chainntnfs.ChainNotifier, wc lnwallet.WalletController, keyRing keychain.SecretKeyRing, - signer lnwallet.Signer, bio lnwallet.BlockChainIO) (*lnwallet.LightningWallet, error) { + signer input.Signer, bio lnwallet.BlockChainIO) (*lnwallet.LightningWallet, error) { dbDir := filepath.Join(tempTestDir, "cdb") cdb, err := channeldb.Open(dbDir) @@ -434,7 +435,7 @@ func testDualFundingReservationWorkflow(miner *rpctest.Harness, ChanReserve: fundingAmount / 100, MaxPendingAmount: lnwire.NewMSatFromSatoshis(fundingAmount), MinHTLC: 1, - MaxAcceptedHtlcs: lnwallet.MaxHTLCNumber / 2, + MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, CsvDelay: csvDelay, } err = aliceChanReservation.CommitConstraints(channelConstraints) @@ -866,7 +867,7 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness, ChanReserve: fundingAmt / 100, MaxPendingAmount: lnwire.NewMSatFromSatoshis(fundingAmt), MinHTLC: 1, - MaxAcceptedHtlcs: lnwallet.MaxHTLCNumber / 2, + MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, CsvDelay: csvDelay, } err = aliceChanReservation.CommitConstraints(channelConstraints) @@ -1528,7 +1529,7 @@ func testPublishTransaction(r *rpctest.Harness, // Now we can populate the sign descriptor which we'll use to // generate the signature. - signDesc := &lnwallet.SignDescriptor{ + signDesc := &input.SignDescriptor{ KeyDesc: keychain.KeyDescriptor{ PubKey: pubKey.PubKey, }, @@ -1783,10 +1784,10 @@ func testSignOutputUsingTweaks(r *rpctest.Harness, commitSecret, commitPoint := btcec.PrivKeyFromBytes(btcec.S256(), commitPreimage) - revocationKey := lnwallet.DeriveRevocationPubkey(pubKey.PubKey, commitPoint) - commitTweak := lnwallet.SingleTweakBytes(commitPoint, pubKey.PubKey) + revocationKey := input.DeriveRevocationPubkey(pubKey.PubKey, commitPoint) + commitTweak := input.SingleTweakBytes(commitPoint, pubKey.PubKey) - tweakedPub := lnwallet.TweakPubKey(pubKey.PubKey, commitPoint) + tweakedPub := input.TweakPubKey(pubKey.PubKey, commitPoint) // As we'd like to test both single and double tweaks, we'll repeat // the same set up twice. The first will use a regular single tweak, @@ -1856,7 +1857,7 @@ func testSignOutputUsingTweaks(r *rpctest.Harness, // private tweak value as the key in the script is derived // based on this tweak value and the key we originally // generated above. - signDesc := &lnwallet.SignDescriptor{ + signDesc := &input.SignDescriptor{ KeyDesc: keychain.KeyDescriptor{ PubKey: baseKey.PubKey, }, @@ -2392,8 +2393,8 @@ func runTests(t *testing.T, walletDriver *lnwallet.WalletDriver, var ( bio lnwallet.BlockChainIO - aliceSigner lnwallet.Signer - bobSigner lnwallet.Signer + aliceSigner input.Signer + bobSigner input.Signer aliceKeyRing keychain.SecretKeyRing bobKeyRing keychain.SecretKeyRing diff --git a/lnwallet/parameters.go b/lnwallet/parameters.go index 306eedf2..5cc6caf8 100644 --- a/lnwallet/parameters.go +++ b/lnwallet/parameters.go @@ -3,10 +3,11 @@ package lnwallet import ( "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwallet/wallet/txrules" + "github.com/lightningnetwork/lnd/input" ) // DefaultDustLimit is used to calculate the dust HTLC amount which will be // send to other node during funding process. func DefaultDustLimit() btcutil.Amount { - return txrules.GetDustThreshold(P2WSHSize, txrules.DefaultRelayFeePerKb) + return txrules.GetDustThreshold(input.P2WSHSize, txrules.DefaultRelayFeePerKb) } diff --git a/lnwallet/reservation.go b/lnwallet/reservation.go index a32acfa2..1cfa1c26 100644 --- a/lnwallet/reservation.go +++ b/lnwallet/reservation.go @@ -9,6 +9,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwire" ) @@ -49,18 +50,6 @@ func (c *ChannelContribution) toChanConfig() channeldb.ChannelConfig { return *c.ChannelConfig } -// InputScript represents any script inputs required to redeem a previous -// output. This struct is used rather than just a witness, or scripSig in order -// to accommodate nested p2sh which utilizes both types of input scripts. -type InputScript struct { - // Witness is the full witness stack required to unlock this output. - Witness wire.TxWitness - - // SigScript will only be populated if this is an input script sweeping - // a nested p2sh output. - SigScript []byte -} - // ChannelReservation represents an intent to open a lightning payment channel // with a counterparty. The funding processes from reservation to channel opening // is a 3-step process. In order to allow for full concurrency during the @@ -102,8 +91,8 @@ type ChannelReservation struct { // In order of sorted inputs. Sorting is done in accordance // to BIP-69: https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki. - ourFundingInputScripts []*InputScript - theirFundingInputScripts []*InputScript + ourFundingInputScripts []*input.Script + theirFundingInputScripts []*input.Script // Our signature for their version of the commitment transaction. ourCommitmentSig []byte @@ -149,7 +138,7 @@ func NewChannelReservation(capacity, fundingAmt btcutil.Amount, initiator bool ) - commitFee := commitFeePerKw.FeeForWeight(CommitWeight) + commitFee := commitFeePerKw.FeeForWeight(input.CommitWeight) fundingMSat := lnwire.NewMSatFromSatoshis(fundingAmt) capacityMSat := lnwire.NewMSatFromSatoshis(capacity) feeMSat := lnwire.NewMSatFromSatoshis(commitFee) @@ -320,9 +309,9 @@ func (r *ChannelReservation) CommitConstraints(c *channeldb.ChannelConstraints) // Fail if maxHtlcs is above the maximum allowed number of 483. This // number is specified in BOLT-02. - if c.MaxAcceptedHtlcs > uint16(MaxHTLCNumber/2) { + if c.MaxAcceptedHtlcs > uint16(input.MaxHTLCNumber/2) { return ErrMaxHtlcNumTooLarge( - c.MaxAcceptedHtlcs, uint16(MaxHTLCNumber/2), + c.MaxAcceptedHtlcs, uint16(input.MaxHTLCNumber/2), ) } @@ -424,7 +413,7 @@ func (r *ChannelReservation) TheirContribution() *ChannelContribution { // // NOTE: These signatures will only be populated after a call to // .ProcessContribution() -func (r *ChannelReservation) OurSignatures() ([]*InputScript, []byte) { +func (r *ChannelReservation) OurSignatures() ([]*input.Script, []byte) { r.RLock() defer r.RUnlock() return r.ourFundingInputScripts, r.ourCommitmentSig @@ -443,7 +432,7 @@ func (r *ChannelReservation) OurSignatures() ([]*InputScript, []byte) { // block until the funding transaction obtains the configured number of // confirmations. Once the method unblocks, a LightningChannel instance is // returned, marking the channel available for updates. -func (r *ChannelReservation) CompleteReservation(fundingInputScripts []*InputScript, +func (r *ChannelReservation) CompleteReservation(fundingInputScripts []*input.Script, commitmentSig []byte) (*channeldb.OpenChannel, error) { // TODO(roasbeef): add flag for watch or not? @@ -494,7 +483,7 @@ func (r *ChannelReservation) CompleteReservationSingle(fundingPoint *wire.OutPoi // // NOTE: These attributes will be unpopulated before a call to // .CompleteReservation(). -func (r *ChannelReservation) TheirSignatures() ([]*InputScript, []byte) { +func (r *ChannelReservation) TheirSignatures() ([]*input.Script, []byte) { r.RLock() defer r.RUnlock() return r.theirFundingInputScripts, r.theirCommitmentSig diff --git a/lnwallet/sigpool.go b/lnwallet/sigpool.go index c30688a7..be22491e 100644 --- a/lnwallet/sigpool.go +++ b/lnwallet/sigpool.go @@ -7,6 +7,7 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/wire" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwire" ) @@ -76,7 +77,7 @@ type SignJob struct { // SignDesc is intended to be a full populated SignDescriptor which // encodes the necessary material (keys, witness script, etc) required // to generate a valid signature for the specified input. - SignDesc SignDescriptor + SignDesc input.SignDescriptor // Tx is the transaction to be signed. This is required to generate the // proper sighash for the input to be signed. @@ -127,7 +128,7 @@ type SigPool struct { started uint32 // To be used atomically. stopped uint32 // To be used atomically. - signer Signer + signer input.Signer verifyJobs chan VerifyJob signJobs chan SignJob @@ -141,7 +142,7 @@ type SigPool struct { // NewSigPool creates a new signature pool with the specified number of // workers. The recommended parameter for the number of works is the number of // physical CPU cores available on the target machine. -func NewSigPool(numWorkers int, signer Signer) *SigPool { +func NewSigPool(numWorkers int, signer input.Signer) *SigPool { return &SigPool{ signer: signer, numWorkers: numWorkers, diff --git a/lnwallet/size_test.go b/lnwallet/size_test.go index e99588f1..36dac258 100644 --- a/lnwallet/size_test.go +++ b/lnwallet/size_test.go @@ -8,7 +8,8 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" - "github.com/lightningnetwork/lnd/lnwallet" + + "github.com/lightningnetwork/lnd/input" ) // TestTxWeightEstimator tests that transaction weight estimates are calculated @@ -106,7 +107,7 @@ func TestTxWeightEstimator(t *testing.T) { } for i, test := range testCases { - var weightEstimate lnwallet.TxWeightEstimator + var weightEstimate input.TxWeightEstimator tx := wire.NewMsgTx(1) for j := 0; j < test.numP2PKHInputs; j++ { diff --git a/lnwallet/test_utils.go b/lnwallet/test_utils.go index dd57e311..e273a6a5 100644 --- a/lnwallet/test_utils.go +++ b/lnwallet/test_utils.go @@ -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 diff --git a/lnwallet/transactions.go b/lnwallet/transactions.go index bbbe2128..7803f752 100644 --- a/lnwallet/transactions.go +++ b/lnwallet/transactions.go @@ -7,6 +7,7 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" + "github.com/lightningnetwork/lnd/input" ) const ( @@ -60,12 +61,12 @@ func createHtlcSuccessTx(htlcOutput wire.OutPoint, htlcAmt btcutil.Amount, // Next, we'll generate the script used as the output for all second // level HTLC which forces a covenant w.r.t what can be done with all // HTLC outputs. - witnessScript, err := secondLevelHtlcScript(revocationKey, delayKey, + witnessScript, err := input.SecondLevelHtlcScript(revocationKey, delayKey, csvDelay) if err != nil { return nil, err } - pkScript, err := WitnessScriptHash(witnessScript) + pkScript, err := input.WitnessScriptHash(witnessScript) if err != nil { return nil, err } @@ -115,12 +116,12 @@ func createHtlcTimeoutTx(htlcOutput wire.OutPoint, htlcAmt btcutil.Amount, // Next, we'll generate the script used as the output for all second // level HTLC which forces a covenant w.r.t what can be done with all // HTLC outputs. - witnessScript, err := secondLevelHtlcScript(revocationKey, delayKey, + witnessScript, err := input.SecondLevelHtlcScript(revocationKey, delayKey, csvDelay) if err != nil { return nil, err } - pkScript, err := WitnessScriptHash(witnessScript) + pkScript, err := input.WitnessScriptHash(witnessScript) if err != nil { return nil, err } diff --git a/lnwallet/transactions_test.go b/lnwallet/transactions_test.go index f592ca8e..dd38d5f9 100644 --- a/lnwallet/transactions_test.go +++ b/lnwallet/transactions_test.go @@ -15,6 +15,7 @@ import ( "github.com/btcsuite/btcutil" "github.com/davecgh/go-spew/spew" "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" @@ -380,7 +381,7 @@ func TestCommitmentAndHTLCTransactions(t *testing.T) { ChannelConstraints: channeldb.ChannelConstraints{ DustLimit: tc.dustLimit, MaxPendingAmount: lnwire.NewMSatFromSatoshis(tc.fundingAmount), - MaxAcceptedHtlcs: MaxHTLCNumber, + MaxAcceptedHtlcs: input.MaxHTLCNumber, CsvDelay: tc.localCsvDelay, }, MultiSigKey: keychain.KeyDescriptor{ @@ -410,11 +411,11 @@ func TestCommitmentAndHTLCTransactions(t *testing.T) { Capacity: tc.fundingAmount, RevocationProducer: shachain.NewRevocationProducer(zeroHash), } - signer := &mockSigner{ - privkeys: []*btcec.PrivateKey{ + signer := &input.MockSigner{ + Privkeys: []*btcec.PrivateKey{ tc.localFundingPrivKey, tc.localPaymentPrivKey, }, - netParams: tc.netParams, + NetParams: tc.netParams, } // Construct a LightningChannel manually because we don't have nor need all @@ -433,7 +434,7 @@ func TestCommitmentAndHTLCTransactions(t *testing.T) { // The commitmentPoint is technically hidden in the spec, but we need it to // generate the correct tweak. - tweak := SingleTweakBytes(tc.commitmentPoint, tc.localPaymentBasePoint) + tweak := input.SingleTweakBytes(tc.commitmentPoint, tc.localPaymentBasePoint) keys := &CommitmentKeyRing{ CommitPoint: tc.commitmentPoint, LocalCommitKeyTweak: tweak, @@ -1043,16 +1044,16 @@ func TestCommitmentSpendValidation(t *testing.T) { revocationPreimage := testHdSeed.CloneBytes() commitSecret, commitPoint := btcec.PrivKeyFromBytes(btcec.S256(), revocationPreimage) - revokePubKey := DeriveRevocationPubkey(bobKeyPub, commitPoint) + revokePubKey := input.DeriveRevocationPubkey(bobKeyPub, commitPoint) - aliceDelayKey := TweakPubKey(aliceKeyPub, commitPoint) - bobPayKey := TweakPubKey(bobKeyPub, commitPoint) + aliceDelayKey := input.TweakPubKey(aliceKeyPub, commitPoint) + bobPayKey := input.TweakPubKey(bobKeyPub, commitPoint) - aliceCommitTweak := SingleTweakBytes(commitPoint, aliceKeyPub) - bobCommitTweak := SingleTweakBytes(commitPoint, bobKeyPub) + aliceCommitTweak := input.SingleTweakBytes(commitPoint, aliceKeyPub) + bobCommitTweak := input.SingleTweakBytes(commitPoint, bobKeyPub) - aliceSelfOutputSigner := &mockSigner{ - privkeys: []*btcec.PrivateKey{aliceKeyPriv}, + aliceSelfOutputSigner := &input.MockSigner{ + Privkeys: []*btcec.PrivateKey{aliceKeyPriv}, } // With all the test data set up, we create the commitment transaction. @@ -1078,7 +1079,7 @@ func TestCommitmentSpendValidation(t *testing.T) { // We're testing an uncooperative close, output sweep, so construct a // transaction which sweeps the funds to a random address. - targetOutput, err := CommitScriptUnencumbered(aliceKeyPub) + targetOutput, err := input.CommitScriptUnencumbered(aliceKeyPub) if err != nil { t.Fatalf("unable to create target output: %v", err) } @@ -1093,13 +1094,13 @@ func TestCommitmentSpendValidation(t *testing.T) { }) // First, we'll test spending with Alice's key after the timeout. - delayScript, err := CommitScriptToSelf(csvTimeout, aliceDelayKey, + delayScript, err := input.CommitScriptToSelf(csvTimeout, aliceDelayKey, revokePubKey) if err != nil { t.Fatalf("unable to generate alice delay script: %v", err) } - sweepTx.TxIn[0].Sequence = lockTimeToSequence(false, csvTimeout) - signDesc := &SignDescriptor{ + sweepTx.TxIn[0].Sequence = input.LockTimeToSequence(false, csvTimeout) + signDesc := &input.SignDescriptor{ WitnessScript: delayScript, KeyDesc: keychain.KeyDescriptor{ PubKey: aliceKeyPub, @@ -1112,7 +1113,7 @@ func TestCommitmentSpendValidation(t *testing.T) { HashType: txscript.SigHashAll, InputIndex: 0, } - aliceWitnessSpend, err := CommitSpendTimeout(aliceSelfOutputSigner, + aliceWitnessSpend, err := input.CommitSpendTimeout(aliceSelfOutputSigner, signDesc, sweepTx) if err != nil { t.Fatalf("unable to generate delay commit spend witness: %v", err) @@ -1128,12 +1129,12 @@ func TestCommitmentSpendValidation(t *testing.T) { t.Fatalf("spend from delay output is invalid: %v", err) } - bobSigner := &mockSigner{privkeys: []*btcec.PrivateKey{bobKeyPriv}} + bobSigner := &input.MockSigner{Privkeys: []*btcec.PrivateKey{bobKeyPriv}} // Next, we'll test bob spending with the derived revocation key to // simulate the scenario when Alice broadcasts this commitment // transaction after it's been revoked. - signDesc = &SignDescriptor{ + signDesc = &input.SignDescriptor{ KeyDesc: keychain.KeyDescriptor{ PubKey: bobKeyPub, }, @@ -1146,7 +1147,7 @@ func TestCommitmentSpendValidation(t *testing.T) { HashType: txscript.SigHashAll, InputIndex: 0, } - bobWitnessSpend, err := CommitSpendRevoke(bobSigner, signDesc, + bobWitnessSpend, err := input.CommitSpendRevoke(bobSigner, signDesc, sweepTx) if err != nil { t.Fatalf("unable to generate revocation witness: %v", err) @@ -1174,11 +1175,11 @@ func TestCommitmentSpendValidation(t *testing.T) { // Finally, we test bob sweeping his output as normal in the case that // Alice broadcasts this commitment transaction. - bobScriptP2WKH, err := CommitScriptUnencumbered(bobPayKey) + bobScriptP2WKH, err := input.CommitScriptUnencumbered(bobPayKey) if err != nil { t.Fatalf("unable to create bob p2wkh script: %v", err) } - signDesc = &SignDescriptor{ + signDesc = &input.SignDescriptor{ KeyDesc: keychain.KeyDescriptor{ PubKey: bobKeyPub, }, @@ -1192,7 +1193,7 @@ func TestCommitmentSpendValidation(t *testing.T) { HashType: txscript.SigHashAll, InputIndex: 0, } - bobRegularSpend, err := CommitSpendNoDelay(bobSigner, signDesc, + bobRegularSpend, err := input.CommitSpendNoDelay(bobSigner, signDesc, sweepTx) if err != nil { t.Fatalf("unable to create bob regular spend: %v", err) diff --git a/lnwallet/wallet.go b/lnwallet/wallet.go index 2dabf056..ed39a995 100644 --- a/lnwallet/wallet.go +++ b/lnwallet/wallet.go @@ -19,6 +19,7 @@ import ( "github.com/btcsuite/btcutil/txsort" "github.com/davecgh/go-spew/spew" "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" @@ -167,7 +168,7 @@ type addCounterPartySigsMsg struct { // Should be order of sorted inputs that are theirs. Sorting is done // in accordance to BIP-69: // https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki. - theirFundingInputScripts []*InputScript + theirFundingInputScripts []*input.Script // This should be 1/2 of the signatures needed to successfully spend our // version of the commitment transaction. @@ -562,7 +563,7 @@ func (l *LightningWallet) handleFundingReserveRequest(req *InitFundingReserveMsg req.resp <- nil return } - reservation.ourContribution.FirstCommitmentPoint = ComputeCommitmentPoint( + reservation.ourContribution.FirstCommitmentPoint = input.ComputeCommitmentPoint( firstPreimage[:], ) @@ -712,7 +713,7 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) { // Finally, add the 2-of-2 multi-sig output which will set up the lightning // channel. channelCapacity := int64(pendingReservation.partialState.Capacity) - witnessScript, multiSigOut, err := GenFundingPkScript( + witnessScript, multiSigOut, err := input.GenFundingPkScript( ourKey.PubKey.SerializeCompressed(), theirKey.PubKey.SerializeCompressed(), channelCapacity, ) @@ -729,9 +730,9 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) { // Next, sign all inputs that are ours, collecting the signatures in // order of the inputs. - pendingReservation.ourFundingInputScripts = make([]*InputScript, 0, + pendingReservation.ourFundingInputScripts = make([]*input.Script, 0, len(ourContribution.Inputs)) - signDesc := SignDescriptor{ + signDesc := input.SignDescriptor{ HashType: txscript.SigHashAll, SigHashes: txscript.NewTxSigHashes(fundingTx), } @@ -767,7 +768,7 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) { // since the outputs are canonically sorted. If this is a single funder // workflow, then we'll also need to send this to the remote node. fundingTxID := fundingTx.TxHash() - _, multiSigIndex := FindScriptOutputIndex(fundingTx, multiSigOut.PkScript) + _, multiSigIndex := input.FindScriptOutputIndex(fundingTx, multiSigOut.PkScript) fundingOutpoint := wire.NewOutPoint(&fundingTxID, multiSigIndex) pendingReservation.partialState.FundingOutpoint = *fundingOutpoint @@ -858,7 +859,7 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) { // Generate a signature for their version of the initial commitment // transaction. - signDesc = SignDescriptor{ + signDesc = input.SignDescriptor{ WitnessScript: witnessScript, KeyDesc: ourKey, Output: multiSigOut, @@ -966,7 +967,7 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs // // TODO(roasbeef): when dual funder pass actual // height-hint - pkScript, err := WitnessScriptHash( + pkScript, err := input.WitnessScriptHash( txin.Witness[len(txin.Witness)-1], ) if err != nil { @@ -1013,7 +1014,7 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs // Re-generate both the witnessScript and p2sh output. We sign the // witnessScript script, but include the p2sh output as the subscript // for verification. - witnessScript, _, err := GenFundingPkScript( + witnessScript, _, err := input.GenFundingPkScript( ourKey.PubKey.SerializeCompressed(), theirKey.PubKey.SerializeCompressed(), int64(res.partialState.Capacity), @@ -1165,7 +1166,7 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) { hashCache := txscript.NewTxSigHashes(ourCommitTx) theirKey := pendingReservation.theirContribution.MultiSigKey ourKey := pendingReservation.ourContribution.MultiSigKey - witnessScript, _, err := GenFundingPkScript( + witnessScript, _, err := input.GenFundingPkScript( ourKey.PubKey.SerializeCompressed(), theirKey.PubKey.SerializeCompressed(), channelValue, ) @@ -1201,13 +1202,13 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) { // With their signature for our version of the commitment transactions // verified, we can now generate a signature for their version, // allowing the funding transaction to be safely broadcast. - p2wsh, err := WitnessScriptHash(witnessScript) + p2wsh, err := input.WitnessScriptHash(witnessScript) if err != nil { req.err <- err req.completeChan <- nil return } - signDesc := SignDescriptor{ + signDesc := input.SignDescriptor{ WitnessScript: witnessScript, KeyDesc: ourKey, Output: &wire.TxOut{ @@ -1401,7 +1402,7 @@ func coinSelect(feeRate SatPerKWeight, amt btcutil.Amount, return nil, 0, err } - var weightEstimate TxWeightEstimator + var weightEstimate input.TxWeightEstimator for _, utxo := range selectedUtxos { switch utxo.AddressType { diff --git a/macaroons/constraints_test.go b/macaroons/constraints_test.go index b5333b03..0d15aff1 100644 --- a/macaroons/constraints_test.go +++ b/macaroons/constraints_test.go @@ -1,11 +1,12 @@ package macaroons_test import ( - "github.com/lightningnetwork/lnd/macaroons" - "gopkg.in/macaroon.v2" "strings" "testing" "time" + + "github.com/lightningnetwork/lnd/macaroons" + macaroon "gopkg.in/macaroon.v2" ) var ( diff --git a/mock.go b/mock.go index b323dcc7..2cbac0c5 100644 --- a/mock.go +++ b/mock.go @@ -12,7 +12,9 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" + "github.com/lightningnetwork/lnd/chainntnfs" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwallet" ) @@ -25,7 +27,7 @@ type mockSigner struct { } func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx, - signDesc *lnwallet.SignDescriptor) ([]byte, error) { + signDesc *input.SignDescriptor) ([]byte, error) { amt := signDesc.Output.Value witnessScript := signDesc.WitnessScript privKey := m.key @@ -36,10 +38,10 @@ func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx, switch { case signDesc.SingleTweak != nil: - privKey = lnwallet.TweakPrivKey(privKey, + privKey = input.TweakPrivKey(privKey, signDesc.SingleTweak) case signDesc.DoubleTweak != nil: - privKey = lnwallet.DeriveRevocationPrivKey(privKey, + privKey = input.DeriveRevocationPrivKey(privKey, signDesc.DoubleTweak) } @@ -54,7 +56,7 @@ func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx, } func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx, - signDesc *lnwallet.SignDescriptor) (*lnwallet.InputScript, error) { + signDesc *input.SignDescriptor) (*input.Script, error) { // TODO(roasbeef): expose tweaked signer from lnwallet so don't need to // duplicate this code? @@ -63,10 +65,10 @@ func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx, switch { case signDesc.SingleTweak != nil: - privKey = lnwallet.TweakPrivKey(privKey, + privKey = input.TweakPrivKey(privKey, signDesc.SingleTweak) case signDesc.DoubleTweak != nil: - privKey = lnwallet.DeriveRevocationPrivKey(privKey, + privKey = input.DeriveRevocationPrivKey(privKey, signDesc.DoubleTweak) } @@ -77,7 +79,7 @@ func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx, return nil, err } - return &lnwallet.InputScript{ + return &input.Script{ Witness: witnessScript, }, nil } diff --git a/routing/notifications_test.go b/routing/notifications_test.go index 7f8aa8fa..c87813e0 100644 --- a/routing/notifications_test.go +++ b/routing/notifications_test.go @@ -16,6 +16,7 @@ import ( "github.com/btcsuite/btcutil" "github.com/go-errors/errors" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/chainview" @@ -87,7 +88,7 @@ func createChannelEdge(ctx *testCtx, bitcoinKey1, bitcoinKey2 []byte, *lnwire.ShortChannelID, error) { fundingTx := wire.NewMsgTx(2) - _, tx, err := lnwallet.GenFundingPkScript( + _, tx, err := input.GenFundingPkScript( bitcoinKey1, bitcoinKey2, int64(chanValue), diff --git a/routing/pathfind.go b/routing/pathfind.go index 7fcad67d..678342f9 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -10,6 +10,7 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/coreos/bbolt" + "github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/lnwire" diff --git a/routing/router.go b/routing/router.go index e752b065..e7db6f57 100644 --- a/routing/router.go +++ b/routing/router.go @@ -16,9 +16,11 @@ import ( "github.com/coreos/bbolt" "github.com/davecgh/go-spew/spew" "github.com/go-errors/errors" + "github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/htlcswitch" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/multimutex" @@ -1034,13 +1036,13 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error { // Recreate witness output to be sure that declared in channel // edge bitcoin keys and channel value corresponds to the // reality. - witnessScript, err := lnwallet.GenMultiSigScript( + witnessScript, err := input.GenMultiSigScript( msg.BitcoinKey1Bytes[:], msg.BitcoinKey2Bytes[:], ) if err != nil { return err } - fundingPkScript, err := lnwallet.WitnessScriptHash(witnessScript) + fundingPkScript, err := input.WitnessScriptHash(witnessScript) if err != nil { return err } diff --git a/routing/router_test.go b/routing/router_test.go index 2ccaf4da..e39ed313 100644 --- a/routing/router_test.go +++ b/routing/router_test.go @@ -9,14 +9,14 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/wire" - "github.com/lightningnetwork/lnd/channeldb" - "github.com/lightningnetwork/lnd/htlcswitch" - "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/wire" "github.com/davecgh/go-spew/spew" + "github.com/lightningnetwork/lightning-onion" + "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/lnwire" ) diff --git a/rpcserver.go b/rpcserver.go index 46be68e8..5c8bfa85 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -31,6 +31,7 @@ import ( "github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/htlcswitch" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/invoices" "github.com/lightningnetwork/lnd/lncfg" "github.com/lightningnetwork/lnd/lnrpc" @@ -1991,7 +1992,7 @@ func (r *rpcServer) PendingChannels(ctx context.Context, localCommitment := pendingChan.LocalCommitment utx := btcutil.NewTx(localCommitment.CommitTx) commitBaseWeight := blockchain.GetTransactionWeight(utx) - commitWeight := commitBaseWeight + lnwallet.WitnessCommitmentTxWeight + commitWeight := commitBaseWeight + input.WitnessCommitmentTxWeight resp.PendingOpenChannels[i] = &lnrpc.PendingChannelsResponse_PendingOpenChannel{ Channel: &lnrpc.PendingChannelsResponse_PendingChannel{ @@ -2320,7 +2321,7 @@ func (r *rpcServer) ListChannels(ctx context.Context, localCommit := dbChannel.LocalCommitment utx := btcutil.NewTx(localCommit.CommitTx) commitBaseWeight := blockchain.GetTransactionWeight(utx) - commitWeight := commitBaseWeight + lnwallet.WitnessCommitmentTxWeight + commitWeight := commitBaseWeight + input.WitnessCommitmentTxWeight localBalance := localCommit.LocalBalance remoteBalance := localCommit.RemoteBalance diff --git a/server.go b/server.go index 5b21875f..70a8fa44 100644 --- a/server.go +++ b/server.go @@ -24,13 +24,14 @@ import ( "github.com/btcsuite/btcutil" "github.com/coreos/bbolt" "github.com/go-errors/errors" - "github.com/lightningnetwork/lightning-onion" + sphinx "github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lnd/autopilot" "github.com/lightningnetwork/lnd/brontide" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/contractcourt" "github.com/lightningnetwork/lnd/discovery" "github.com/lightningnetwork/lnd/htlcswitch" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/invoices" "github.com/lightningnetwork/lnd/lncfg" "github.com/lightningnetwork/lnd/lnpeer" @@ -913,7 +914,7 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl, RequiredRemoteMaxHTLCs: func(chanAmt btcutil.Amount) uint16 { // By default, we'll permit them to utilize the full // channel bandwidth. - return uint16(lnwallet.MaxHTLCNumber / 2) + return uint16(input.MaxHTLCNumber / 2) }, ZombieSweeperInterval: 1 * time.Minute, ReservationTimeout: 10 * time.Minute, diff --git a/sweep/sweeper.go b/sweep/sweeper.go index 61cb1a22..8ac4aafb 100644 --- a/sweep/sweeper.go +++ b/sweep/sweeper.go @@ -12,6 +12,7 @@ import ( "github.com/btcsuite/btcutil" "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/chainntnfs" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" ) @@ -39,7 +40,7 @@ type pendingInput struct { // input is the original struct that contains the input and sign // descriptor. - input Input + input input.Input // ntfnRegCancel is populated with a function that cancels the chain // notifier spend registration. @@ -111,7 +112,7 @@ type UtxoSweeperConfig struct { // Signer is used by the sweeper to generate valid witnesses at the // time the incubated outputs need to be spent. - Signer lnwallet.Signer + Signer input.Signer // SweepTxConfTarget assigns a confirmation target for sweep txes on // which the fee calculation will be based. @@ -148,7 +149,7 @@ type Result struct { // sweepInputMessage structs are used in the internal channel between the // SweepInput call and the sweeper main loop. type sweepInputMessage struct { - input Input + input input.Input resultChan chan Result } @@ -256,7 +257,7 @@ func (s *UtxoSweeper) Stop() error { // NOTE: Extreme care needs to be taken that input isn't changed externally. // Because it is an interface and we don't know what is exactly behind it, we // cannot make a local copy in sweeper. -func (s *UtxoSweeper) SweepInput(input Input) (chan Result, error) { +func (s *UtxoSweeper) SweepInput(input input.Input) (chan Result, error) { if input == nil || input.OutPoint() == nil || input.SignDesc() == nil { return nil, errors.New("nil input received") } @@ -550,7 +551,7 @@ func (s *UtxoSweeper) getInputLists(currentHeight int32, // contain inputs that failed before. Therefore we also add sets // consisting of only new inputs to the list, to make sure that new // inputs are given a good, isolated chance of being published. - var newInputs, retryInputs []Input + var newInputs, retryInputs []input.Input for _, input := range s.pendingInputs { // Skip inputs that have a minimum publish height that is not // yet reached. @@ -750,7 +751,7 @@ func (s *UtxoSweeper) waitForSpend(outpoint wire.OutPoint, // - Make handling re-orgs easier. // - Thwart future possible fee sniping attempts. // - Make us blend in with the bitcoind wallet. -func (s *UtxoSweeper) CreateSweepTx(inputs []Input, feePref FeePreference, +func (s *UtxoSweeper) CreateSweepTx(inputs []input.Input, feePref FeePreference, currentBlockHeight uint32) (*wire.MsgTx, error) { feePerKw, err := DetermineFeePerKw(s.cfg.FeeEstimator, feePref) diff --git a/sweep/sweeper_test.go b/sweep/sweeper_test.go index abce18b5..2023a684 100644 --- a/sweep/sweeper_test.go +++ b/sweep/sweeper_test.go @@ -12,8 +12,8 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/build" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" - "github.com/lightningnetwork/lnd/lnwallet" ) var ( @@ -38,7 +38,7 @@ type sweeperTestContext struct { } var ( - spendableInputs []*BaseInput + spendableInputs []*input.BaseInput testInputCount int testPubKey, _ = btcec.ParsePubKey([]byte{ @@ -53,17 +53,17 @@ var ( }, btcec.S256()) ) -func createTestInput(value int64, witnessType lnwallet.WitnessType) BaseInput { +func createTestInput(value int64, witnessType input.WitnessType) input.BaseInput { hash := chainhash.Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, byte(testInputCount)} - input := MakeBaseInput( + input := input.MakeBaseInput( &wire.OutPoint{ Hash: hash, }, witnessType, - &lnwallet.SignDescriptor{ + &input.SignDescriptor{ Output: &wire.TxOut{ Value: value, }, @@ -83,7 +83,7 @@ func init() { // Create a set of test spendable inputs. for i := 0; i < 5; i++ { input := createTestInput(int64(10000+i*500), - lnwallet.CommitmentTimeLock) + input.CommitmentTimeLock) spendableInputs = append(spendableInputs, &input) } @@ -303,7 +303,7 @@ func TestDust(t *testing.T) { // Create an input so that the output after paying fees is still // positive (400 sat), but less than the dust limit (537 sat) for the // sweep tx output script (P2WPKH). - dustInput := createTestInput(5260, lnwallet.CommitmentTimeLock) + dustInput := createTestInput(5260, input.CommitmentTimeLock) _, err := ctx.sweeper.SweepInput(&dustInput) if err != nil { @@ -314,7 +314,7 @@ func TestDust(t *testing.T) { // that the sweep output will not be relayed and not generate the tx. // Sweep another input that brings the tx output above the dust limit. - largeInput := createTestInput(100000, lnwallet.CommitmentTimeLock) + largeInput := createTestInput(100000, input.CommitmentTimeLock) _, err = ctx.sweeper.SweepInput(&largeInput) if err != nil { @@ -344,7 +344,7 @@ func TestNegativeInput(t *testing.T) { // Sweep an input large enough to cover fees, so in any case the tx // output will be above the dust limit. - largeInput := createTestInput(100000, lnwallet.CommitmentNoDelay) + largeInput := createTestInput(100000, input.CommitmentNoDelay) largeInputResult, err := ctx.sweeper.SweepInput(&largeInput) if err != nil { t.Fatal(err) @@ -353,7 +353,7 @@ func TestNegativeInput(t *testing.T) { // Sweep an additional input with a negative net yield. The weight of // the HtlcAcceptedRemoteSuccess input type adds more in fees than its // value at the current fee level. - negInput := createTestInput(2900, lnwallet.HtlcOfferedRemoteTimeout) + negInput := createTestInput(2900, input.HtlcOfferedRemoteTimeout) negInputResult, err := ctx.sweeper.SweepInput(&negInput) if err != nil { t.Fatal(err) @@ -361,7 +361,7 @@ func TestNegativeInput(t *testing.T) { // Sweep a third input that has a smaller output than the previous one, // but yields positively because of its lower weight. - positiveInput := createTestInput(2800, lnwallet.CommitmentNoDelay) + positiveInput := createTestInput(2800, input.CommitmentNoDelay) positiveInputResult, err := ctx.sweeper.SweepInput(&positiveInput) if err != nil { t.Fatal(err) @@ -390,7 +390,7 @@ func TestNegativeInput(t *testing.T) { ctx.estimator.updateFees(1000, 1000) // Create another large input - secondLargeInput := createTestInput(100000, lnwallet.CommitmentNoDelay) + secondLargeInput := createTestInput(100000, input.CommitmentNoDelay) secondLargeInputResult, err := ctx.sweeper.SweepInput(&secondLargeInput) if err != nil { t.Fatal(err) diff --git a/sweep/test_utils.go b/sweep/test_utils.go index d9ef157c..bf71d602 100644 --- a/sweep/test_utils.go +++ b/sweep/test_utils.go @@ -9,7 +9,7 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/chainntnfs" - "github.com/lightningnetwork/lnd/lnwallet" + "github.com/lightningnetwork/lnd/input" ) var ( @@ -21,15 +21,15 @@ type mockSigner struct { } func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx, - signDesc *lnwallet.SignDescriptor) ([]byte, error) { + signDesc *input.SignDescriptor) ([]byte, error) { return []byte{}, nil } func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx, - signDesc *lnwallet.SignDescriptor) (*lnwallet.InputScript, error) { + signDesc *input.SignDescriptor) (*input.Script, error) { - return &lnwallet.InputScript{}, nil + return &input.Script{}, nil } // MockNotifier simulates the chain notifier for test purposes. This type is diff --git a/sweep/txgenerator.go b/sweep/txgenerator.go index 3cf60d6b..26a4503e 100644 --- a/sweep/txgenerator.go +++ b/sweep/txgenerator.go @@ -9,6 +9,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwallet/wallet/txrules" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" ) @@ -21,21 +22,21 @@ var ( // inputSet is a set of inputs that can be used as the basis to generate a tx // on. -type inputSet []Input +type inputSet []input.Input // generateInputPartitionings goes through all given inputs and constructs sets // of inputs that can be used to generate a sensible transaction. Each set // contains up to the configured maximum number of inputs. Negative yield // inputs are skipped. No input sets with a total value after fees below the // dust limit are returned. -func generateInputPartitionings(sweepableInputs []Input, +func generateInputPartitionings(sweepableInputs []input.Input, relayFeePerKW, feePerKW lnwallet.SatPerKWeight, maxInputsPerTx int) ([]inputSet, error) { // Calculate dust limit based on the P2WPKH output script of the sweep // txes. dustLimit := txrules.GetDustThreshold( - lnwallet.P2WPKHSize, + input.P2WPKHSize, btcutil.Amount(relayFeePerKW.FeePerKVByte()), ) @@ -113,10 +114,10 @@ func generateInputPartitionings(sweepableInputs []Input, // up the utxo set even if it costs us some fees up front. In the spirit of // minimizing any negative externalities we cause for the Bitcoin system as a // whole. -func getPositiveYieldInputs(sweepableInputs []Input, maxInputs int, +func getPositiveYieldInputs(sweepableInputs []input.Input, maxInputs int, feePerKW lnwallet.SatPerKWeight) (int, btcutil.Amount) { - var weightEstimate lnwallet.TxWeightEstimator + var weightEstimate input.TxWeightEstimator // Add the sweep tx output to the weight estimate. weightEstimate.AddP2WKHOutput() @@ -166,9 +167,9 @@ func getPositiveYieldInputs(sweepableInputs []Input, maxInputs int, } // createSweepTx builds a signed tx spending the inputs to a the output script. -func createSweepTx(inputs []Input, outputPkScript []byte, +func createSweepTx(inputs []input.Input, outputPkScript []byte, currentBlockHeight uint32, feePerKw lnwallet.SatPerKWeight, - signer lnwallet.Signer) (*wire.MsgTx, error) { + signer input.Signer) (*wire.MsgTx, error) { inputs, txWeight, csvCount, cltvCount := getWeightEstimate(inputs) @@ -222,7 +223,7 @@ func createSweepTx(inputs []Input, outputPkScript []byte, // With all the inputs in place, use each output's unique input script // function to generate the final witness required for spending. - addInputScript := func(idx int, tso Input) error { + addInputScript := func(idx int, tso input.Input) error { inputScript, err := tso.CraftInputScript( signer, sweepTx, hashCache, idx, ) @@ -254,62 +255,62 @@ func createSweepTx(inputs []Input, outputPkScript []byte, // the given input if it would be included in a tx. We also return if the // output itself is a nested p2sh output, if so then we need to take into // account the extra sigScript data size. -func getInputWitnessSizeUpperBound(input Input) (int, bool, error) { - switch input.WitnessType() { +func getInputWitnessSizeUpperBound(inp input.Input) (int, bool, error) { + switch inp.WitnessType() { // Outputs on a remote commitment transaction that pay directly to us. - case lnwallet.WitnessKeyHash: + case input.WitnessKeyHash: fallthrough - case lnwallet.CommitmentNoDelay: - return lnwallet.P2WKHWitnessSize, false, nil + case input.CommitmentNoDelay: + return input.P2WKHWitnessSize, false, nil // Outputs on a past commitment transaction that pay directly // to us. - case lnwallet.CommitmentTimeLock: - return lnwallet.ToLocalTimeoutWitnessSize, false, nil + case input.CommitmentTimeLock: + return input.ToLocalTimeoutWitnessSize, false, nil // Outgoing second layer HTLC's that have confirmed within the // chain, and the output they produced is now mature enough to // sweep. - case lnwallet.HtlcOfferedTimeoutSecondLevel: - return lnwallet.ToLocalTimeoutWitnessSize, false, nil + case input.HtlcOfferedTimeoutSecondLevel: + return input.ToLocalTimeoutWitnessSize, false, nil // Incoming second layer HTLC's that have confirmed within the // chain, and the output they produced is now mature enough to // sweep. - case lnwallet.HtlcAcceptedSuccessSecondLevel: - return lnwallet.ToLocalTimeoutWitnessSize, false, nil + case input.HtlcAcceptedSuccessSecondLevel: + return input.ToLocalTimeoutWitnessSize, false, nil // An HTLC on the commitment transaction of the remote party, // that has had its absolute timelock expire. - case lnwallet.HtlcOfferedRemoteTimeout: - return lnwallet.AcceptedHtlcTimeoutWitnessSize, false, nil + case input.HtlcOfferedRemoteTimeout: + return input.AcceptedHtlcTimeoutWitnessSize, false, nil // An HTLC on the commitment transaction of the remote party, // that can be swept with the preimage. - case lnwallet.HtlcAcceptedRemoteSuccess: - return lnwallet.OfferedHtlcSuccessWitnessSize, false, nil + case input.HtlcAcceptedRemoteSuccess: + return input.OfferedHtlcSuccessWitnessSize, false, nil // A nested P2SH input that has a p2wkh witness script. We'll mark this // as nested P2SH so the caller can estimate the weight properly // including the sigScript. - case lnwallet.NestedWitnessKeyHash: - return lnwallet.P2WKHWitnessSize, true, nil + case input.NestedWitnessKeyHash: + return input.P2WKHWitnessSize, true, nil } return 0, false, fmt.Errorf("unexpected witness type: %v", - input.WitnessType()) + inp.WitnessType()) } // getWeightEstimate returns a weight estimate for the given inputs. // Additionally, it returns counts for the number of csv and cltv inputs. -func getWeightEstimate(inputs []Input) ([]Input, int64, int, int) { +func getWeightEstimate(inputs []input.Input) ([]input.Input, int64, int, int) { // We initialize a weight estimator so we can accurately asses the // amount of fees we need to pay for this sweep transaction. // // TODO(roasbeef): can be more intelligent about buffering outputs to // be more efficient on-chain. - var weightEstimate lnwallet.TxWeightEstimator + var weightEstimate input.TxWeightEstimator // Our sweep transaction will pay to a single segwit p2wkh address, // ensure it contributes to our weight estimate. @@ -319,16 +320,16 @@ func getWeightEstimate(inputs []Input) ([]Input, int64, int, int) { // weight of its witness, and add it to the proper set of spendable // outputs. var ( - sweepInputs []Input + sweepInputs []input.Input csvCount, cltvCount int ) for i := range inputs { - input := inputs[i] + inp := inputs[i] // For fee estimation purposes, we'll now attempt to obtain an // upper bound on the weight this input will add when fully // populated. - size, isNestedP2SH, err := getInputWitnessSizeUpperBound(input) + size, isNestedP2SH, err := getInputWitnessSizeUpperBound(inp) if err != nil { log.Warn(err) @@ -345,15 +346,15 @@ func getWeightEstimate(inputs []Input) ([]Input, int64, int, int) { weightEstimate.AddWitnessInput(size) } - switch input.WitnessType() { - case lnwallet.CommitmentTimeLock, - lnwallet.HtlcOfferedTimeoutSecondLevel, - lnwallet.HtlcAcceptedSuccessSecondLevel: + switch inp.WitnessType() { + case input.CommitmentTimeLock, + input.HtlcOfferedTimeoutSecondLevel, + input.HtlcAcceptedSuccessSecondLevel: csvCount++ - case lnwallet.HtlcOfferedRemoteTimeout: + case input.HtlcOfferedRemoteTimeout: cltvCount++ } - sweepInputs = append(sweepInputs, input) + sweepInputs = append(sweepInputs, inp) } txWeight := int64(weightEstimate.Weight()) diff --git a/sweep/walletsweep.go b/sweep/walletsweep.go index 1cfe9059..1abb6c48 100644 --- a/sweep/walletsweep.go +++ b/sweep/walletsweep.go @@ -7,6 +7,7 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" ) @@ -152,7 +153,7 @@ func CraftSweepAllTx(feeRate lnwallet.SatPerKWeight, blockHeight uint32, deliveryAddr btcutil.Address, coinSelectLocker CoinSelectionLocker, utxoSource UtxoSource, outpointLocker OutpointLocker, feeEstimator lnwallet.FeeEstimator, - signer lnwallet.Signer) (*WalletSweepPackage, error) { + signer input.Signer) (*WalletSweepPackage, error) { // TODO(roasbeef): turn off ATPL as well when available? @@ -206,7 +207,7 @@ func CraftSweepAllTx(feeRate lnwallet.SatPerKWeight, blockHeight uint32, // Now that we've locked all the potential outputs to sweep, we'll // assemble an input for each of them, so we can hand it off to the // sweeper to generate and sign a transaction for us. - var inputsToSweep []Input + var inputsToSweep []input.Input for _, output := range allOutputs { // We'll consult the utxoSource for information concerning this // outpoint, we'll need to properly populate a signDescriptor @@ -222,7 +223,7 @@ func CraftSweepAllTx(feeRate lnwallet.SatPerKWeight, blockHeight uint32, // we only need to populate the output value and output script. // The rest of the items will be populated internally within // the sweeper via the witness generation function. - signDesc := &lnwallet.SignDescriptor{ + signDesc := &input.SignDescriptor{ Output: outputInfo, HashType: txscript.SigHashAll, } @@ -232,18 +233,18 @@ func CraftSweepAllTx(feeRate lnwallet.SatPerKWeight, blockHeight uint32, // Based on the output type, we'll map it to the proper witness // type so we can generate the set of input scripts needed to // sweep the output. - var witnessType lnwallet.WitnessType + var witnessType input.WitnessType switch { // If this is a p2wkh output, then we'll assume it's a witness // key hash witness type. case txscript.IsPayToWitnessPubKeyHash(pkScript): - witnessType = lnwallet.WitnessKeyHash + witnessType = input.WitnessKeyHash // If this is a p2sh output, then as since it's under control // of the wallet, we'll assume it's a nested p2sh output. case txscript.IsPayToScriptHash(pkScript): - witnessType = lnwallet.NestedWitnessKeyHash + witnessType = input.NestedWitnessKeyHash // All other output types we count as unknown and will fail to // sweep. @@ -257,7 +258,7 @@ func CraftSweepAllTx(feeRate lnwallet.SatPerKWeight, blockHeight uint32, // Now that we've constructed the items required, we'll make an // input which can be passed to the sweeper for ultimate // sweeping. - input := MakeBaseInput(&output.OutPoint, witnessType, signDesc, 0) + input := input.MakeBaseInput(&output.OutPoint, witnessType, signDesc, 0) inputsToSweep = append(inputsToSweep, &input) } diff --git a/test_utils.go b/test_utils.go index e9ae411c..82f239cb 100644 --- a/test_utils.go +++ b/test_utils.go @@ -18,6 +18,7 @@ import ( "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/contractcourt" "github.com/lightningnetwork/lnd/htlcswitch" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" @@ -170,7 +171,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, if err != nil { return nil, nil, nil, nil, err } - bobCommitPoint := lnwallet.ComputeCommitmentPoint(bobFirstRevoke[:]) + bobCommitPoint := input.ComputeCommitmentPoint(bobFirstRevoke[:]) aliceRoot, err := chainhash.NewHash(aliceKeyPriv.Serialize()) if err != nil { @@ -181,7 +182,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, if err != nil { return nil, nil, nil, nil, err } - aliceCommitPoint := lnwallet.ComputeCommitmentPoint(aliceFirstRevoke[:]) + aliceCommitPoint := input.ComputeCommitmentPoint(aliceFirstRevoke[:]) aliceCommitTx, bobCommitTx, err := lnwallet.CreateCommitmentTxns(channelBal, channelBal, &aliceCfg, &bobCfg, aliceCommitPoint, bobCommitPoint, @@ -214,7 +215,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, LocalBalance: lnwire.NewMSatFromSatoshis(channelBal), RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal), FeePerKw: btcutil.Amount(feePerKw), - CommitFee: feePerKw.FeeForWeight(lnwallet.CommitWeight), + CommitFee: feePerKw.FeeForWeight(input.CommitWeight), CommitTx: aliceCommitTx, CommitSig: bytes.Repeat([]byte{1}, 71), } @@ -223,7 +224,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, LocalBalance: lnwire.NewMSatFromSatoshis(channelBal), RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal), FeePerKw: btcutil.Amount(feePerKw), - CommitFee: feePerKw.FeeForWeight(lnwallet.CommitWeight), + CommitFee: feePerKw.FeeForWeight(input.CommitWeight), CommitTx: bobCommitTx, CommitSig: bytes.Repeat([]byte{1}, 71), } diff --git a/utxonursery.go b/utxonursery.go index f12f5388..20e0f0c2 100644 --- a/utxonursery.go +++ b/utxonursery.go @@ -8,8 +8,6 @@ import ( "sync" "sync/atomic" - "github.com/lightningnetwork/lnd/sweep" - "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" @@ -17,7 +15,9 @@ import ( "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" + "github.com/lightningnetwork/lnd/sweep" ) // SUMMARY OF OUTPUT STATES @@ -196,7 +196,7 @@ type NurseryConfig struct { Store NurseryStore // Sweep sweeps an input back to the wallet. - SweepInput func(input sweep.Input) (chan sweep.Result, error) + SweepInput func(input input.Input) (chan sweep.Result, error) } // utxoNursery is a system dedicated to incubating time-locked outputs created @@ -368,7 +368,7 @@ func (u *utxoNursery) IncubateOutputs(chanPoint wire.OutPoint, &commitResolution.SelfOutPoint, &chanPoint, commitResolution.MaturityDelay, - lnwallet.CommitmentTimeLock, + input.CommitmentTimeLock, &commitResolution.SelfOutputSignDesc, 0, ) @@ -389,7 +389,7 @@ func (u *utxoNursery) IncubateOutputs(chanPoint wire.OutPoint, for _, htlcRes := range incomingHtlcs { htlcOutput := makeKidOutput( &htlcRes.ClaimOutpoint, &chanPoint, htlcRes.CsvDelay, - lnwallet.HtlcAcceptedSuccessSecondLevel, + input.HtlcAcceptedSuccessSecondLevel, &htlcRes.SweepSignDesc, 0, ) @@ -421,7 +421,7 @@ func (u *utxoNursery) IncubateOutputs(chanPoint wire.OutPoint, // indicate this is actually a CLTV output. htlcOutput := makeKidOutput( &htlcRes.ClaimOutpoint, &chanPoint, 0, - lnwallet.HtlcOfferedRemoteTimeout, + input.HtlcOfferedRemoteTimeout, &htlcRes.SweepSignDesc, htlcRes.Expiry, ) kidOutputs = append(kidOutputs, htlcOutput) @@ -533,13 +533,13 @@ func (u *utxoNursery) NurseryReport( // Preschool outputs are awaiting the // confirmation of the commitment transaction. switch kid.WitnessType() { - case lnwallet.CommitmentTimeLock: + case input.CommitmentTimeLock: report.AddLimboCommitment(&kid) // An HTLC output on our commitment transaction // where the second-layer transaction hasn't // yet confirmed. - case lnwallet.HtlcAcceptedSuccessSecondLevel: + case input.HtlcAcceptedSuccessSecondLevel: report.AddLimboStage1SuccessHtlc(&kid) } @@ -549,13 +549,13 @@ func (u *utxoNursery) NurseryReport( // We can distinguish them via their witness // types. switch kid.WitnessType() { - case lnwallet.CommitmentTimeLock: + case input.CommitmentTimeLock: // The commitment transaction has been // confirmed, and we are waiting the CSV // delay to expire. report.AddLimboCommitment(&kid) - case lnwallet.HtlcOfferedRemoteTimeout: + case input.HtlcOfferedRemoteTimeout: // This is an HTLC output on the // commitment transaction of the remote // party. The CLTV timelock has @@ -563,9 +563,9 @@ func (u *utxoNursery) NurseryReport( // it. report.AddLimboDirectHtlc(&kid) - case lnwallet.HtlcAcceptedSuccessSecondLevel: + case input.HtlcAcceptedSuccessSecondLevel: fallthrough - case lnwallet.HtlcOfferedTimeoutSecondLevel: + case input.HtlcOfferedTimeoutSecondLevel: // The htlc timeout or success // transaction has confirmed, and the // CSV delay has begun ticking. @@ -578,17 +578,17 @@ func (u *utxoNursery) NurseryReport( // will contribute towards the recovered // balance. switch kid.WitnessType() { - case lnwallet.CommitmentTimeLock: + case input.CommitmentTimeLock: // The commitment output was // successfully swept back into a // regular p2wkh output. report.AddRecoveredCommitment(&kid) - case lnwallet.HtlcAcceptedSuccessSecondLevel: + case input.HtlcAcceptedSuccessSecondLevel: fallthrough - case lnwallet.HtlcOfferedTimeoutSecondLevel: + case input.HtlcOfferedTimeoutSecondLevel: fallthrough - case lnwallet.HtlcOfferedRemoteTimeout: + case input.HtlcOfferedRemoteTimeout: // This htlc output successfully // resides in a p2wkh output belonging // to the user. @@ -1301,7 +1301,7 @@ func makeBabyOutput(chanPoint *wire.OutPoint, htlcOutpoint := htlcResolution.ClaimOutpoint blocksToMaturity := htlcResolution.CsvDelay - witnessType := lnwallet.HtlcOfferedTimeoutSecondLevel + witnessType := input.HtlcOfferedTimeoutSecondLevel kid := makeKidOutput( &htlcOutpoint, chanPoint, blocksToMaturity, witnessType, @@ -1380,15 +1380,15 @@ type kidOutput struct { } func makeKidOutput(outpoint, originChanPoint *wire.OutPoint, - blocksToMaturity uint32, witnessType lnwallet.WitnessType, - signDescriptor *lnwallet.SignDescriptor, + blocksToMaturity uint32, witnessType input.WitnessType, + signDescriptor *input.SignDescriptor, absoluteMaturity uint32) kidOutput { // This is an HTLC either if it's an incoming HTLC on our commitment // transaction, or is an outgoing HTLC on the commitment transaction of // the remote peer. - isHtlc := (witnessType == lnwallet.HtlcAcceptedSuccessSecondLevel || - witnessType == lnwallet.HtlcOfferedRemoteTimeout) + isHtlc := (witnessType == input.HtlcAcceptedSuccessSecondLevel || + witnessType == input.HtlcOfferedRemoteTimeout) // heightHint can be safely set to zero here, because after this // function returns, nursery will set a proper confirmation height in @@ -1464,7 +1464,7 @@ func (k *kidOutput) Encode(w io.Writer) error { return err } - return lnwallet.WriteSignDescriptor(w, k.SignDesc()) + return input.WriteSignDescriptor(w, k.SignDesc()) } // Decode takes a byte array representation of a kidOutput and converts it to an @@ -1509,9 +1509,9 @@ func (k *kidOutput) Decode(r io.Reader) error { if _, err := r.Read(scratch[:2]); err != nil { return err } - k.witnessType = lnwallet.WitnessType(byteOrder.Uint16(scratch[:2])) + k.witnessType = input.WitnessType(byteOrder.Uint16(scratch[:2])) - return lnwallet.ReadSignDescriptor(r, &k.signDesc) + return input.ReadSignDescriptor(r, &k.signDesc) } // TODO(bvu): copied from channeldb, remove repetition @@ -1551,4 +1551,4 @@ func readOutpoint(r io.Reader, o *wire.OutPoint) error { // Compile-time constraint to ensure kidOutput implements the // Input interface. -var _ sweep.Input = (*kidOutput)(nil) +var _ input.Input = (*kidOutput)(nil) diff --git a/utxonursery_test.go b/utxonursery_test.go index 2f8629b5..4da0a239 100644 --- a/utxonursery_test.go +++ b/utxonursery_test.go @@ -5,8 +5,6 @@ package main import ( "bytes" "fmt" - "github.com/lightningnetwork/lnd/channeldb" - "github.com/lightningnetwork/lnd/sweep" "io/ioutil" "math" "os" @@ -21,7 +19,10 @@ import ( "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/lnwallet" + "github.com/lightningnetwork/lnd/sweep" ) var ( @@ -108,7 +109,7 @@ var ( }, } - signDescriptors = []lnwallet.SignDescriptor{ + signDescriptors = []input.SignDescriptor{ { SingleTweak: []byte{ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, @@ -206,7 +207,7 @@ var ( breachedOutput: breachedOutput{ amt: btcutil.Amount(13e7), outpoint: outPoints[1], - witnessType: lnwallet.CommitmentTimeLock, + witnessType: input.CommitmentTimeLock, confHeight: uint32(1000), }, originChanPoint: outPoints[0], @@ -217,7 +218,7 @@ var ( breachedOutput: breachedOutput{ amt: btcutil.Amount(24e7), outpoint: outPoints[2], - witnessType: lnwallet.CommitmentTimeLock, + witnessType: input.CommitmentTimeLock, confHeight: uint32(1000), }, originChanPoint: outPoints[0], @@ -228,7 +229,7 @@ var ( breachedOutput: breachedOutput{ amt: btcutil.Amount(2e5), outpoint: outPoints[3], - witnessType: lnwallet.CommitmentTimeLock, + witnessType: input.CommitmentTimeLock, confHeight: uint32(500), }, originChanPoint: outPoints[0], @@ -239,7 +240,7 @@ var ( breachedOutput: breachedOutput{ amt: btcutil.Amount(10e6), outpoint: outPoints[4], - witnessType: lnwallet.CommitmentTimeLock, + witnessType: input.CommitmentTimeLock, confHeight: uint32(500), }, originChanPoint: outPoints[0], @@ -597,7 +598,7 @@ func createOutgoingRes(onLocalCommitment bool) *lnwallet.OutgoingHtlcResolution outgoingRes := lnwallet.OutgoingHtlcResolution{ Expiry: 125, - SweepSignDesc: lnwallet.SignDescriptor{ + SweepSignDesc: input.SignDescriptor{ Output: &wire.TxOut{ Value: 10000, }, @@ -630,7 +631,7 @@ func createCommitmentRes() *lnwallet.CommitOutputResolution { // Set up a commitment output resolution to hand off to nursery. commitRes := lnwallet.CommitOutputResolution{ SelfOutPoint: wire.OutPoint{}, - SelfOutputSignDesc: lnwallet.SignDescriptor{ + SelfOutputSignDesc: input.SignDescriptor{ Output: &wire.TxOut{ Value: 10000, }, @@ -1027,15 +1028,15 @@ type nurseryMockSigner struct { } func (m *nurseryMockSigner) SignOutputRaw(tx *wire.MsgTx, - signDesc *lnwallet.SignDescriptor) ([]byte, error) { + signDesc *input.SignDescriptor) ([]byte, error) { return []byte{}, nil } func (m *nurseryMockSigner) ComputeInputScript(tx *wire.MsgTx, - signDesc *lnwallet.SignDescriptor) (*lnwallet.InputScript, error) { + signDesc *input.SignDescriptor) (*input.Script, error) { - return &lnwallet.InputScript{}, nil + return &input.Script{}, nil } type mockSweeper struct { @@ -1044,18 +1045,18 @@ type mockSweeper struct { resultChans map[wire.OutPoint]chan sweep.Result t *testing.T - sweepChan chan sweep.Input + sweepChan chan input.Input } func newMockSweeper(t *testing.T) *mockSweeper { return &mockSweeper{ resultChans: make(map[wire.OutPoint]chan sweep.Result), - sweepChan: make(chan sweep.Input, 1), + sweepChan: make(chan input.Input, 1), t: t, } } -func (s *mockSweeper) sweepInput(input sweep.Input) (chan sweep.Result, error) { +func (s *mockSweeper) sweepInput(input input.Input) (chan sweep.Result, error) { utxnLog.Debugf("mockSweeper sweepInput called for %v", *input.OutPoint()) select { diff --git a/watchtower/blob/justice_kit.go b/watchtower/blob/justice_kit.go index 952d812a..46abaa00 100644 --- a/watchtower/blob/justice_kit.go +++ b/watchtower/blob/justice_kit.go @@ -12,7 +12,7 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/txscript" - "github.com/lightningnetwork/lnd/lnwallet" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwire" ) @@ -163,7 +163,7 @@ func (b *JusticeKit) CommitToLocalWitnessScript() ([]byte, error) { return nil, err } - return lnwallet.CommitScriptToSelf( + return input.CommitScriptToSelf( b.CSVDelay, localDelayedPubKey, revocationPubKey, ) } diff --git a/watchtower/blob/justice_kit_test.go b/watchtower/blob/justice_kit_test.go index 922290b5..977289e0 100644 --- a/watchtower/blob/justice_kit_test.go +++ b/watchtower/blob/justice_kit_test.go @@ -10,7 +10,7 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/txscript" - "github.com/lightningnetwork/lnd/lnwallet" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/watchtower/blob" ) @@ -356,7 +356,7 @@ func TestJusticeKitToLocalWitnessConstruction(t *testing.T) { // Compute the expected to-local script, which is a function of the CSV // delay, revocation pubkey and delay pubkey. - expToLocalScript, err := lnwallet.CommitScriptToSelf( + expToLocalScript, err := input.CommitScriptToSelf( csvDelay, delayPrivKey.PubKey(), revPrivKey.PubKey(), ) if err != nil { diff --git a/watchtower/lookout/justice_descriptor.go b/watchtower/lookout/justice_descriptor.go index 9eca67409..1de21c19 100644 --- a/watchtower/lookout/justice_descriptor.go +++ b/watchtower/lookout/justice_descriptor.go @@ -8,7 +8,7 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" - "github.com/lightningnetwork/lnd/lnwallet" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/watchtower/blob" "github.com/lightningnetwork/lnd/watchtower/wtdb" ) @@ -60,7 +60,7 @@ func (p *JusticeDescriptor) commitToLocalInput() (*breachedInput, error) { // Compute the witness script hash, which will be used to locate the // input on the breaching commitment transaction. - toLocalWitnessHash, err := lnwallet.WitnessScriptHash(toLocalScript) + toLocalWitnessHash, err := input.WitnessScriptHash(toLocalScript) if err != nil { return nil, err } @@ -112,7 +112,7 @@ func (p *JusticeDescriptor) commitToRemoteInput() (*breachedInput, error) { // Compute the witness script hash from the to-remote pubkey, which will // be used to locate the input on the breach commitment transaction. - toRemoteScriptHash, err := lnwallet.CommitScriptUnencumbered( + toRemoteScriptHash, err := input.CommitScriptUnencumbered( toRemotePubKey, ) if err != nil { @@ -226,7 +226,7 @@ func (p *JusticeDescriptor) assembleJusticeTxn(txWeight int64, func (p *JusticeDescriptor) CreateJusticeTxn() (*wire.MsgTx, error) { var ( sweepInputs = make([]*breachedInput, 0, 2) - weightEstimate lnwallet.TxWeightEstimator + weightEstimate input.TxWeightEstimator ) // Add our reward address to the weight estimate. @@ -235,10 +235,10 @@ func (p *JusticeDescriptor) CreateJusticeTxn() (*wire.MsgTx, error) { // Add the sweep address's contribution, depending on whether it is a // p2wkh or p2wsh output. switch len(p.JusticeKit.SweepAddress) { - case lnwallet.P2WPKHSize: + case input.P2WPKHSize: weightEstimate.AddP2WKHOutput() - case lnwallet.P2WSHSize: + case input.P2WSHSize: weightEstimate.AddP2WSHOutput() default: @@ -251,7 +251,7 @@ func (p *JusticeDescriptor) CreateJusticeTxn() (*wire.MsgTx, error) { if err != nil { return nil, err } - weightEstimate.AddWitnessInput(lnwallet.ToLocalPenaltyWitnessSize) + weightEstimate.AddWitnessInput(input.ToLocalPenaltyWitnessSize) sweepInputs = append(sweepInputs, toLocalInput) // If the justice kit specifies that we have to sweep the to-remote @@ -262,7 +262,7 @@ func (p *JusticeDescriptor) CreateJusticeTxn() (*wire.MsgTx, error) { if err != nil { return nil, err } - weightEstimate.AddWitnessInput(lnwallet.P2WKHWitnessSize) + weightEstimate.AddWitnessInput(input.P2WKHWitnessSize) sweepInputs = append(sweepInputs, toRemoteInput) } @@ -281,7 +281,7 @@ func (p *JusticeDescriptor) CreateJusticeTxn() (*wire.MsgTx, error) { func findTxOutByPkScript(txn *wire.MsgTx, pkScript []byte) (uint32, *wire.TxOut, error) { - found, index := lnwallet.FindScriptOutputIndex(txn, pkScript) + found, index := input.FindScriptOutputIndex(txn, pkScript) if !found { return 0, nil, ErrOutputNotFound } diff --git a/watchtower/lookout/justice_descriptor_test.go b/watchtower/lookout/justice_descriptor_test.go index 1fe215cc..9502193d 100644 --- a/watchtower/lookout/justice_descriptor_test.go +++ b/watchtower/lookout/justice_descriptor_test.go @@ -13,8 +13,8 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" "github.com/davecgh/go-spew/spew" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" - "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/watchtower/blob" "github.com/lightningnetwork/lnd/watchtower/lookout" @@ -59,7 +59,7 @@ func newMockSigner() *mockSigner { } func (s *mockSigner) SignOutputRaw(tx *wire.MsgTx, - signDesc *lnwallet.SignDescriptor) ([]byte, error) { + signDesc *input.SignDescriptor) ([]byte, error) { witnessScript := signDesc.WitnessScript amt := signDesc.Output.Value @@ -81,7 +81,7 @@ func (s *mockSigner) SignOutputRaw(tx *wire.MsgTx, } func (s *mockSigner) ComputeInputScript(tx *wire.MsgTx, - signDesc *lnwallet.SignDescriptor) (*lnwallet.InputScript, error) { + signDesc *input.SignDescriptor) (*input.Script, error) { return nil, nil } @@ -122,7 +122,7 @@ func TestJusticeDescriptor(t *testing.T) { ) // Construct the to-local witness script. - toLocalScript, err := lnwallet.CommitScriptToSelf( + toLocalScript, err := input.CommitScriptToSelf( csvDelay, toLocalPK, revPK, ) if err != nil { @@ -130,13 +130,13 @@ func TestJusticeDescriptor(t *testing.T) { } // Compute the to-local witness script hash. - toLocalScriptHash, err := lnwallet.WitnessScriptHash(toLocalScript) + toLocalScriptHash, err := input.WitnessScriptHash(toLocalScript) if err != nil { t.Fatalf("unable to create to-local witness script hash: %v", err) } // Compute the to-remote witness script hash. - toRemoteScriptHash, err := lnwallet.CommitScriptUnencumbered(toRemotePK) + toRemoteScriptHash, err := input.CommitScriptUnencumbered(toRemotePK) if err != nil { t.Fatalf("unable to create to-remote script: %v", err) } @@ -160,11 +160,11 @@ func TestJusticeDescriptor(t *testing.T) { breachTxID := breachTxn.TxHash() // Compute the weight estimate for our justice transaction. - var weightEstimate lnwallet.TxWeightEstimator + var weightEstimate input.TxWeightEstimator weightEstimate.AddP2WKHOutput() weightEstimate.AddP2WKHOutput() - weightEstimate.AddWitnessInput(lnwallet.ToLocalPenaltyWitnessSize) - weightEstimate.AddWitnessInput(lnwallet.P2WKHWitnessSize) + weightEstimate.AddWitnessInput(input.ToLocalPenaltyWitnessSize) + weightEstimate.AddWitnessInput(input.P2WKHWitnessSize) txWeight := weightEstimate.Weight() // Create a session info so that simulate agreement of the sweep @@ -235,7 +235,7 @@ func TestJusticeDescriptor(t *testing.T) { hashCache := txscript.NewTxSigHashes(justiceTxn) // Create the sign descriptor used to sign for the to-local input. - toLocalSignDesc := &lnwallet.SignDescriptor{ + toLocalSignDesc := &input.SignDescriptor{ KeyDesc: keychain.KeyDescriptor{ KeyLocator: revKeyLoc, }, @@ -247,7 +247,7 @@ func TestJusticeDescriptor(t *testing.T) { } // Create the sign descriptor used to sign for the to-remote input. - toRemoteSignDesc := &lnwallet.SignDescriptor{ + toRemoteSignDesc := &input.SignDescriptor{ KeyDesc: keychain.KeyDescriptor{ KeyLocator: toRemoteKeyLoc, PubKey: toRemotePK, @@ -274,7 +274,7 @@ func TestJusticeDescriptor(t *testing.T) { // Compute the witness for the to-remote input. The first element is a // DER-encoded signature under the to-remote pubkey. The sighash flag is // also present, so we trim it. - toRemoteWitness, err := lnwallet.CommitSpendNoDelay( + toRemoteWitness, err := input.CommitSpendNoDelay( signer, toRemoteSignDesc, justiceTxn, ) if err != nil {