lnwallet: update channelState interaction to respect new db commitment format

This commit is contained in:
Olaoluwa Osuntokun 2017-11-09 23:06:10 -08:00
parent b50a94aeab
commit ded7c11bfe
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21

@ -52,6 +52,11 @@ var (
// ErrInsufficientBalance is returned when a proposed HTLC would // ErrInsufficientBalance is returned when a proposed HTLC would
// exceed the available balance. // exceed the available balance.
ErrInsufficientBalance = fmt.Errorf("insufficient local balance") ErrInsufficientBalance = fmt.Errorf("insufficient local balance")
// ErrCannotSyncCommitChains is returned if, upon receiving a ChanSync
// message, the state machine deems that is unable to properly
// synchronize states with the remote peer.
ErrCannotSyncCommitChains = fmt.Errorf("unable to sync commit chains")
) )
// channelState is an enum like type which represents the current state of a // channelState is an enum like type which represents the current state of a
@ -1657,6 +1662,11 @@ type BreachRetribution struct {
// commitment transaction. // commitment transaction.
BreachTransaction *wire.MsgTx BreachTransaction *wire.MsgTx
// ChainHash is the chain that the contract beach was identified
// within. This is also the resident chain of the contract (the chain
// the contract was created on).
ChainHash chainhash.Hash
// RevokedStateNum is the revoked state number which was broadcast. // RevokedStateNum is the revoked state number which was broadcast.
RevokedStateNum uint64 RevokedStateNum uint64
@ -1667,6 +1677,7 @@ type BreachRetribution struct {
// LocalOutputSignDesc is a SignDescriptor which is capable of // LocalOutputSignDesc is a SignDescriptor which is capable of
// generating the signature necessary to sweep the output within the // generating the signature necessary to sweep the output within the
// BreachTransaction that pays directly us. // BreachTransaction that pays directly us.
//
// NOTE: A nil value indicates that the local output is considered dust // NOTE: A nil value indicates that the local output is considered dust
// according to the remote party's dust limit. // according to the remote party's dust limit.
LocalOutputSignDesc *SignDescriptor LocalOutputSignDesc *SignDescriptor
@ -1679,6 +1690,7 @@ type BreachRetribution struct {
// generating the signature required to claim the funds as described // generating the signature required to claim the funds as described
// within the revocation clause of the remote party's commitment // within the revocation clause of the remote party's commitment
// output. // output.
//
// NOTE: A nil value indicates that the local output is considered dust // NOTE: A nil value indicates that the local output is considered dust
// according to the remote party's dust limit. // according to the remote party's dust limit.
RemoteOutputSignDesc *SignDescriptor RemoteOutputSignDesc *SignDescriptor
@ -1854,6 +1866,7 @@ func newBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
// BreachRetribution struct which houses all the data necessary to // BreachRetribution struct which houses all the data necessary to
// swiftly bring justice to the cheating remote party. // swiftly bring justice to the cheating remote party.
return &BreachRetribution{ return &BreachRetribution{
ChainHash: chanState.ChainHash,
BreachTransaction: broadcastCommitment, BreachTransaction: broadcastCommitment,
RevokedStateNum: stateNum, RevokedStateNum: stateNum,
PendingHTLCs: revokedSnapshot.Htlcs, PendingHTLCs: revokedSnapshot.Htlcs,
@ -1965,6 +1978,7 @@ func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEven
// * and time-locked balance, NEED TO??? // * and time-locked balance, NEED TO???
closeSummary := channeldb.ChannelCloseSummary{ closeSummary := channeldb.ChannelCloseSummary{
ChanPoint: lc.channelState.FundingOutpoint, ChanPoint: lc.channelState.FundingOutpoint,
ChainHash: lc.channelState.ChainHash,
ClosingTXID: *commitSpend.SpenderTxHash, ClosingTXID: *commitSpend.SpenderTxHash,
RemotePub: lc.channelState.IdentityPub, RemotePub: lc.channelState.IdentityPub,
Capacity: lc.Capacity, Capacity: lc.Capacity,
@ -3890,12 +3904,11 @@ func (lc *LightningChannel) ShortChanID() lnwire.ShortChannelID {
return lc.channelState.ShortChanID return lc.channelState.ShortChanID
} }
// genHtlcScript generates the proper P2WSH public key scripts for the // genHtlcScript generates the proper P2WSH public key scripts for the HTLC
// HTLC output modified by two-bits denoting if this is an incoming HTLC, and // output modified by two-bits denoting if this is an incoming HTLC, and if the
// if the HTLC is being applied to their commitment transaction or ours. // HTLC is being applied to their commitment transaction or ours.
func (lc *LightningChannel) genHtlcScript(isIncoming, ourCommit bool, func genHtlcScript(isIncoming, ourCommit bool, timeout uint32, rHash [32]byte,
timeout uint32, rHash [32]byte, keyRing *commitmentKeyRing, keyRing *commitmentKeyRing) ([]byte, []byte, error) {
) ([]byte, []byte, error) {
var ( var (
witnessScript []byte witnessScript []byte
@ -3956,13 +3969,13 @@ func (lc *LightningChannel) genHtlcScript(isIncoming, ourCommit bool,
// PaymentDescriptor that generated it, the generated script is stored within // PaymentDescriptor that generated it, the generated script is stored within
// the descriptor itself. // the descriptor itself.
func (lc *LightningChannel) addHTLC(commitTx *wire.MsgTx, ourCommit bool, func (lc *LightningChannel) addHTLC(commitTx *wire.MsgTx, ourCommit bool,
isIncoming bool, paymentDesc *PaymentDescriptor, keyRing *commitmentKeyRing, isIncoming bool, paymentDesc *PaymentDescriptor,
) error { keyRing *commitmentKeyRing) error {
timeout := paymentDesc.Timeout timeout := paymentDesc.Timeout
rHash := paymentDesc.RHash rHash := paymentDesc.RHash
p2wsh, witnessScript, err := lc.genHtlcScript(isIncoming, ourCommit, p2wsh, witnessScript, err := genHtlcScript(isIncoming, ourCommit,
timeout, rHash, keyRing) timeout, rHash, keyRing)
if err != nil { if err != nil {
return err return err
@ -3985,18 +3998,19 @@ func (lc *LightningChannel) addHTLC(commitTx *wire.MsgTx, ourCommit bool,
return nil return nil
} }
// getSignedCommitTx function take the latest commitment transaction and populate // getSignedCommitTx function take the latest commitment transaction and
// it with witness data. // populate it with witness data.
func (lc *LightningChannel) getSignedCommitTx() (*wire.MsgTx, error) { func (lc *LightningChannel) getSignedCommitTx() (*wire.MsgTx, error) {
// Fetch the current commitment transaction, along with their signature // Fetch the current commitment transaction, along with their signature
// for the transaction. // for the transaction.
commitTx := lc.channelState.CommitTx localCommit := lc.channelState.LocalCommitment
theirSig := append(lc.channelState.CommitSig, byte(txscript.SigHashAll)) commitTx := localCommit.CommitTx
theirSig := append(localCommit.CommitSig, byte(txscript.SigHashAll))
// With this, we then generate the full witness so the caller can // With this, we then generate the full witness so the caller can
// broadcast a fully signed transaction. // broadcast a fully signed transaction.
lc.signDesc.SigHashes = txscript.NewTxSigHashes(&commitTx) lc.signDesc.SigHashes = txscript.NewTxSigHashes(commitTx)
ourSigRaw, err := lc.signer.SignOutputRaw(&commitTx, lc.signDesc) ourSigRaw, err := lc.signer.SignOutputRaw(commitTx, lc.signDesc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -4008,10 +4022,12 @@ func (lc *LightningChannel) getSignedCommitTx() (*wire.MsgTx, error) {
ourKey := lc.localChanCfg.MultiSigKey.SerializeCompressed() ourKey := lc.localChanCfg.MultiSigKey.SerializeCompressed()
theirKey := lc.remoteChanCfg.MultiSigKey.SerializeCompressed() theirKey := lc.remoteChanCfg.MultiSigKey.SerializeCompressed()
commitTx.TxIn[0].Witness = SpendMultiSig(lc.FundingWitnessScript, ourKey, commitTx.TxIn[0].Witness = SpendMultiSig(
ourSig, theirKey, theirSig) lc.FundingWitnessScript, ourKey,
ourSig, theirKey, theirSig,
)
return &commitTx, nil return commitTx, nil
} }
// UnilateralCloseSummary describes the details of a detected unilateral // UnilateralCloseSummary describes the details of a detected unilateral
@ -4169,7 +4185,7 @@ func newHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig,
// the local key used when generating the HTLC scrips. This function is to be // the local key used when generating the HTLC scrips. This function is to be
// used in two cases: force close, or a unilateral close. // used in two cases: force close, or a unilateral close.
func extractHtlcResolutions(feePerKw btcutil.Amount, ourCommit bool, func extractHtlcResolutions(feePerKw btcutil.Amount, ourCommit bool,
signer Signer, htlcs []*channeldb.HTLC, keyRing *commitmentKeyRing, signer Signer, htlcs []channeldb.HTLC, keyRing *commitmentKeyRing,
localChanCfg, remoteChanCfg *channeldb.ChannelConfig, localChanCfg, remoteChanCfg *channeldb.ChannelConfig,
commitHash chainhash.Hash) ([]OutgoingHtlcResolution, error) { commitHash chainhash.Hash) ([]OutgoingHtlcResolution, error) {
@ -4198,7 +4214,7 @@ func extractHtlcResolutions(feePerKw btcutil.Amount, ourCommit bool,
} }
ohr, err := newHtlcResolution( ohr, err := newHtlcResolution(
signer, localChanCfg, commitHash, htlc, keyRing, signer, localChanCfg, commitHash, &htlc, keyRing,
feePerKw, dustLimit, uint32(csvDelay), feePerKw, dustLimit, uint32(csvDelay),
) )
if err != nil { if err != nil {
@ -4313,6 +4329,8 @@ func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error) {
break break
} }
localCommitment := lc.channelState.LocalCommitment
// With the necessary information gathered above, create a new sign // With the necessary information gathered above, create a new sign
// descriptor which is capable of generating the signature the caller // descriptor which is capable of generating the signature the caller
// needs to sweep this output. The hash cache, and input index are not // needs to sweep this output. The hash cache, and input index are not
@ -4322,13 +4340,14 @@ func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error) {
if len(delayScript) != 0 { if len(delayScript) != 0 {
singleTweak := SingleTweakBytes(commitPoint, singleTweak := SingleTweakBytes(commitPoint,
lc.localChanCfg.DelayBasePoint) lc.localChanCfg.DelayBasePoint)
localBalance := localCommitment.LocalBalance
selfSignDesc = &SignDescriptor{ selfSignDesc = &SignDescriptor{
PubKey: lc.localChanCfg.DelayBasePoint, PubKey: lc.localChanCfg.DelayBasePoint,
SingleTweak: singleTweak, SingleTweak: singleTweak,
WitnessScript: selfScript, WitnessScript: selfScript,
Output: &wire.TxOut{ Output: &wire.TxOut{
PkScript: delayScript, PkScript: delayScript,
Value: int64(lc.channelState.LocalBalance.ToSatoshis()), Value: int64(localBalance.ToSatoshis()),
}, },
HashType: txscript.SigHashAll, HashType: txscript.SigHashAll,
} }
@ -4339,7 +4358,7 @@ func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error) {
// outgoing HTLC's that we'll need to claim as well. // outgoing HTLC's that we'll need to claim as well.
txHash := commitTx.TxHash() txHash := commitTx.TxHash()
htlcResolutions, err := extractHtlcResolutions( htlcResolutions, err := extractHtlcResolutions(
lc.channelState.FeePerKw, true, lc.signer, lc.channelState.Htlcs, localCommitment.FeePerKw, true, lc.signer, localCommitment.Htlcs,
keyRing, lc.localChanCfg, lc.remoteChanCfg, txHash) keyRing, lc.localChanCfg, lc.remoteChanCfg, txHash)
if err != nil { if err != nil {
return nil, err return nil, err
@ -4389,8 +4408,9 @@ func (lc *LightningChannel) CreateCloseProposal(proposedFee uint64,
// Subtract the proposed fee from the appropriate balance, taking care // Subtract the proposed fee from the appropriate balance, taking care
// not to persist the adjusted balance, as the feeRate may change // not to persist the adjusted balance, as the feeRate may change
// during the channel closing process. // during the channel closing process.
ourBalance := lc.channelState.LocalBalance.ToSatoshis() localCommit := lc.channelState.LocalCommitment
theirBalance := lc.channelState.RemoteBalance.ToSatoshis() ourBalance := localCommit.LocalBalance.ToSatoshis()
theirBalance := localCommit.RemoteBalance.ToSatoshis()
if lc.channelState.IsInitiator { if lc.channelState.IsInitiator {
ourBalance = ourBalance - btcutil.Amount(proposedFee) ourBalance = ourBalance - btcutil.Amount(proposedFee)
@ -4450,8 +4470,9 @@ func (lc *LightningChannel) CompleteCooperativeClose(localSig, remoteSig,
// Subtract the proposed fee from the appropriate balance, taking care // Subtract the proposed fee from the appropriate balance, taking care
// not to persist the adjusted balance, as the feeRate may change // not to persist the adjusted balance, as the feeRate may change
// during the channel closing process. // during the channel closing process.
ourBalance := lc.channelState.LocalBalance.ToSatoshis() localCommit := lc.channelState.LocalCommitment
theirBalance := lc.channelState.RemoteBalance.ToSatoshis() ourBalance := localCommit.LocalBalance.ToSatoshis()
theirBalance := localCommit.RemoteBalance.ToSatoshis()
if lc.channelState.IsInitiator { if lc.channelState.IsInitiator {
ourBalance = ourBalance - btcutil.Amount(proposedFee) ourBalance = ourBalance - btcutil.Amount(proposedFee)
@ -4557,8 +4578,7 @@ func (lc *LightningChannel) ReceiveUpdateFee(feePerKw btcutil.Amount) error {
return nil return nil
} }
// generateRevocation generate lnwire revocation message by the given height // generateRevocation generates the revocation message for a given height.
// and revocation edge.
func (lc *LightningChannel) generateRevocation(height uint64) (*lnwire.RevokeAndAck, func (lc *LightningChannel) generateRevocation(height uint64) (*lnwire.RevokeAndAck,
error) { error) {
@ -4603,9 +4623,9 @@ func (lc *LightningChannel) generateRevocation(height uint64) (*lnwire.RevokeAnd
// to the "owner" of the commitment transaction which can be spent after a // to the "owner" of the commitment transaction which can be spent after a
// relative block delay or revocation event, and the other paying the // relative block delay or revocation event, and the other paying the
// counterparty within the channel, which can be spent immediately. // counterparty within the channel, which can be spent immediately.
func CreateCommitTx(fundingOutput *wire.TxIn, keyRing *commitmentKeyRing, func CreateCommitTx(fundingOutput *wire.TxIn,
csvTimeout uint32, amountToSelf, amountToThem, dustLimit btcutil.Amount, keyRing *commitmentKeyRing, csvTimeout uint32,
) (*wire.MsgTx, error) { amountToSelf, amountToThem, dustLimit btcutil.Amount) (*wire.MsgTx, error) {
// First, we create the script for the delayed "pay-to-self" output. // First, we create the script for the delayed "pay-to-self" output.
// This output has 2 main redemption clauses: either we can redeem the // This output has 2 main redemption clauses: either we can redeem the
@ -4693,7 +4713,7 @@ func CreateCooperativeCloseTx(fundingTxIn *wire.TxIn,
// CalcFee returns the commitment fee to use for the given // CalcFee returns the commitment fee to use for the given
// fee rate (fee-per-kw). // fee rate (fee-per-kw).
func (lc *LightningChannel) CalcFee(feeRate uint64) uint64 { func (lc *LightningChannel) CalcFee(feeRate uint64) uint64 {
return (feeRate * uint64(commitWeight)) / 1000 return (feeRate * uint64(CommitWeight)) / 1000
} }
// RemoteNextRevocation returns the channelState's RemoteNextRevocation. // RemoteNextRevocation returns the channelState's RemoteNextRevocation.