lnwallet: pass chan cfgs to CreateCommitTx

Instead of passing delays and dustlimits separately, we pass the correct
channel config to CreateCommitTx from the POV of the local party that
owns the commit tx.

To make it more clear which commitment we are actually creating, we
rename variables to denote local and remote, to prepare for the case
when both outputs might be delayed.
This commit is contained in:
Johan T. Halseth 2020-01-06 11:42:03 +01:00
parent 1a4f81ed90
commit fff9dbe6f3
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26
3 changed files with 70 additions and 43 deletions

View File

@ -2428,23 +2428,27 @@ func (lc *LightningChannel) createCommitmentTx(c *commitment,
}
var (
delay uint32
delayBalance, p2wkhBalance btcutil.Amount
commitTx *wire.MsgTx
err error
)
if c.isOurs {
delay = uint32(lc.channelState.LocalChanCfg.CsvDelay)
delayBalance = ourBalance.ToSatoshis()
p2wkhBalance = theirBalance.ToSatoshis()
} else {
delay = uint32(lc.channelState.RemoteChanCfg.CsvDelay)
delayBalance = theirBalance.ToSatoshis()
p2wkhBalance = ourBalance.ToSatoshis()
}
// Generate a new commitment transaction with all the latest
// unsettled/un-timed out HTLCs.
commitTx, err := CreateCommitTx(lc.fundingTxIn(), keyRing, delay,
delayBalance, p2wkhBalance, c.dustLimit)
// Depending on whether the transaction is ours or not, we call
// CreateCommitTx with parameters mathcing the perspective, to generate
// a new commitment transaction with all the latest unsettled/un-timed
// out HTLCs.
if c.isOurs {
commitTx, err = CreateCommitTx(
lc.fundingTxIn(), keyRing, &lc.channelState.LocalChanCfg,
&lc.channelState.RemoteChanCfg, ourBalance.ToSatoshis(),
theirBalance.ToSatoshis(),
)
} else {
commitTx, err = CreateCommitTx(
lc.fundingTxIn(), keyRing, &lc.channelState.RemoteChanCfg,
&lc.channelState.LocalChanCfg, theirBalance.ToSatoshis(),
ourBalance.ToSatoshis(),
)
}
if err != nil {
return err
}
@ -6216,32 +6220,39 @@ func (lc *LightningChannel) generateRevocation(height uint64) (*lnwire.RevokeAnd
}
// CreateCommitTx creates a commitment transaction, spending from specified
// funding output. The commitment transaction contains two outputs: one paying
// to the "owner" of the commitment transaction which can be spent after a
// relative block delay or revocation event, and the other paying the
// counterparty within the channel, which can be spent immediately.
func CreateCommitTx(fundingOutput wire.TxIn,
keyRing *CommitmentKeyRing, csvTimeout uint32,
amountToSelf, amountToThem, dustLimit btcutil.Amount) (*wire.MsgTx, error) {
// funding output. The commitment transaction contains two outputs: one local
// output paying to the "owner" of the commitment transaction which can be
// spent after a relative block delay or revocation event, and a remote output
// paying the counterparty within the channel, which can be spent immediately
// or after a delay depending on the commitment type..
func CreateCommitTx(fundingOutput wire.TxIn, keyRing *CommitmentKeyRing,
localChanCfg, remoteChanCfg *channeldb.ChannelConfig,
amountToLocal, amountToRemote btcutil.Amount) (*wire.MsgTx, error) {
// First, we create the script for the delayed "pay-to-self" output.
// This output has 2 main redemption clauses: either we can redeem the
// 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 := input.CommitScriptToSelf(csvTimeout, keyRing.DelayKey,
keyRing.RevocationKey)
toLocalRedeemScript, err := input.CommitScriptToSelf(
uint32(localChanCfg.CsvDelay), keyRing.DelayKey,
keyRing.RevocationKey,
)
if err != nil {
return nil, err
}
payToUsScriptHash, err := input.WitnessScriptHash(ourRedeemScript)
toLocalScriptHash, err := input.WitnessScriptHash(
toLocalRedeemScript,
)
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 := input.CommitScriptUnencumbered(keyRing.NoDelayKey)
// Next, we create the script paying to the remote. This is just a
// regular P2WPKH output, without any added CSV delay.
toRemoteWitnessKeyHash, err := input.CommitScriptUnencumbered(
keyRing.NoDelayKey,
)
if err != nil {
return nil, err
}
@ -6253,16 +6264,16 @@ func CreateCommitTx(fundingOutput wire.TxIn,
commitTx.AddTxIn(&fundingOutput)
// Avoid creating dust outputs within the commitment transaction.
if amountToSelf >= dustLimit {
if amountToLocal >= localChanCfg.DustLimit {
commitTx.AddTxOut(&wire.TxOut{
PkScript: payToUsScriptHash,
Value: int64(amountToSelf),
PkScript: toLocalScriptHash,
Value: int64(amountToLocal),
})
}
if amountToThem >= dustLimit {
if amountToRemote >= localChanCfg.DustLimit {
commitTx.AddTxOut(&wire.TxOut{
PkScript: theirWitnessKeyHash,
Value: int64(amountToThem),
PkScript: toRemoteWitnessKeyHash,
Value: int64(amountToRemote),
})
}

View File

@ -1015,7 +1015,7 @@ func testSpendValidation(t *testing.T, tweakless bool) {
fakeFundingTxIn := wire.NewTxIn(fundingOut, nil, nil)
const channelBalance = btcutil.Amount(1 * 10e8)
const csvTimeout = uint32(5)
const csvTimeout = 5
// We also set up set some resources for the commitment transaction.
// Each side currently has 1 BTC within the channel, with a total
@ -1050,6 +1050,20 @@ func testSpendValidation(t *testing.T, tweakless bool) {
Privkeys: []*btcec.PrivateKey{aliceKeyPriv},
}
aliceChanCfg := &channeldb.ChannelConfig{
ChannelConstraints: channeldb.ChannelConstraints{
DustLimit: DefaultDustLimit(),
CsvDelay: csvTimeout,
},
}
bobChanCfg := &channeldb.ChannelConfig{
ChannelConstraints: channeldb.ChannelConstraints{
DustLimit: DefaultDustLimit(),
CsvDelay: csvTimeout,
},
}
// With all the test data set up, we create the commitment transaction.
// We only focus on a single party's transactions, as the scripts are
// identical with the roles reversed.
@ -1063,8 +1077,8 @@ func testSpendValidation(t *testing.T, tweakless bool) {
NoDelayKey: bobPayKey,
}
commitmentTx, err := CreateCommitTx(
*fakeFundingTxIn, keyRing, csvTimeout, channelBalance,
channelBalance, DefaultDustLimit(),
*fakeFundingTxIn, keyRing, aliceChanCfg, bobChanCfg,
channelBalance, channelBalance,
)
if err != nil {
t.Fatalf("unable to create commitment transaction: %v", nil)

View File

@ -784,9 +784,10 @@ func CreateCommitmentTxns(localBalance, remoteBalance btcutil.Amount,
theirChanCfg,
)
ourCommitTx, err := CreateCommitTx(fundingTxIn, localCommitmentKeys,
uint32(ourChanCfg.CsvDelay), localBalance, remoteBalance,
ourChanCfg.DustLimit)
ourCommitTx, err := CreateCommitTx(
fundingTxIn, localCommitmentKeys, ourChanCfg, theirChanCfg,
localBalance, remoteBalance,
)
if err != nil {
return nil, nil, err
}
@ -796,9 +797,10 @@ func CreateCommitmentTxns(localBalance, remoteBalance btcutil.Amount,
return nil, nil, err
}
theirCommitTx, err := CreateCommitTx(fundingTxIn, remoteCommitmentKeys,
uint32(theirChanCfg.CsvDelay), remoteBalance, localBalance,
theirChanCfg.DustLimit)
theirCommitTx, err := CreateCommitTx(
fundingTxIn, remoteCommitmentKeys, theirChanCfg, ourChanCfg,
remoteBalance, localBalance,
)
if err != nil {
return nil, nil, err
}