move channel state struct to channeldb.go
* All fields are now publicly exported
This commit is contained in:
parent
868ac0aca0
commit
07646d05db
@ -1,12 +1,9 @@
|
||||
package lnwallet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"li.lan/labs/plasma/chainntfs"
|
||||
"li.lan/labs/plasma/revocation"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
@ -21,80 +18,6 @@ const (
|
||||
MaxPendingPayments = 10
|
||||
)
|
||||
|
||||
type nodeId [32]byte
|
||||
|
||||
// OpenChannelState...
|
||||
// TODO(roasbeef): script gen methods on this?
|
||||
type OpenChannelState struct {
|
||||
// Hash? or Their current pubKey?
|
||||
// TODO(roasbeef): switch to Tadge's LNId
|
||||
theirLNID nodeId
|
||||
|
||||
minFeePerKb btcutil.Amount
|
||||
// Our reserve. Assume symmetric reserve amounts. Only needed if the
|
||||
// funding type is CLTV.
|
||||
reserveAmount btcutil.Amount
|
||||
|
||||
// Keys for both sides to be used for the commitment transactions.
|
||||
ourCommitKey *btcec.PrivateKey // TODO(roasbeef): again unencrypted
|
||||
theirCommitKey *btcec.PublicKey
|
||||
|
||||
// Tracking total channel capacity, and the amount of funds allocated
|
||||
// to each side.
|
||||
capacity btcutil.Amount
|
||||
ourBalance btcutil.Amount
|
||||
theirBalance btcutil.Amount
|
||||
|
||||
// Commitment transactions for both sides (they're asymmetric). Also
|
||||
// their signature which lets us spend our version of the commitment
|
||||
// transaction.
|
||||
theirCommitTx *wire.MsgTx
|
||||
ourCommitTx *wire.MsgTx
|
||||
theirCommitSig []byte
|
||||
|
||||
// The final funding transaction. Kept wallet-related records.
|
||||
fundingTx *wire.MsgTx
|
||||
|
||||
// TODO(roasbeef): instead store a btcutil.Address here? Otherwise key
|
||||
// is stored unencrypted! Use manager.Encrypt() when storing.
|
||||
multiSigKey *btcec.PrivateKey
|
||||
// TODO(roasbeef): encrypt also, or store in waddrmanager?
|
||||
fundingRedeemScript []byte
|
||||
|
||||
// Current revocation for their commitment transaction. However, since
|
||||
// this is the hash, and not the pre-image, we can't yet verify that
|
||||
// it's actually in the chain.
|
||||
theirCurrentRevocation [wire.HashSize]byte
|
||||
theirShaChain *revocation.HyperShaChain
|
||||
ourShaChain *revocation.HyperShaChain
|
||||
|
||||
// Final delivery address
|
||||
ourDeliveryAddress btcutil.Address
|
||||
theirDeliveryAddress btcutil.Address
|
||||
|
||||
// In blocks
|
||||
htlcTimeout uint32
|
||||
csvDelay uint32
|
||||
|
||||
// TODO(roasbeef): track fees, other stats?
|
||||
numUpdates uint64
|
||||
totalSatoshisSent uint64
|
||||
totalSatoshisReceived uint64
|
||||
creationTime time.Time
|
||||
}
|
||||
|
||||
func (o *OpenChannelState) Encode(b bytes.Buffer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *OpenChannelState) Decode(b bytes.Buffer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newOpenChannelState(ID [32]byte) *OpenChannelState {
|
||||
return &OpenChannelState{theirLNID: ID}
|
||||
}
|
||||
|
||||
// LightningChannel...
|
||||
// TODO(roasbeef): future peer struct should embed this struct
|
||||
type LightningChannel struct {
|
||||
|
76
lnwallet/channeldb.go
Normal file
76
lnwallet/channeldb.go
Normal file
@ -0,0 +1,76 @@
|
||||
package lnwallet
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"li.lan/labs/plasma/shachain"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/btcsuite/btcwallet/waddrmgr"
|
||||
"github.com/btcsuite/btcwallet/walletdb"
|
||||
)
|
||||
// OpenChannelState...
|
||||
// TODO(roasbeef): trim...
|
||||
type OpenChannelState struct {
|
||||
// Hash? or Their current pubKey?
|
||||
// TODO(roasbeef): switch to Tadge's LNId
|
||||
TheirLNID [wire.HashSize]byte
|
||||
|
||||
// The ID of a channel is the txid of the funding transaction.
|
||||
ChanID [wire.HashSize]byte
|
||||
|
||||
MinFeePerKb btcutil.Amount
|
||||
// Our reserve. Assume symmetric reserve amounts. Only needed if the
|
||||
// funding type is CLTV.
|
||||
//ReserveAmount btcutil.Amount
|
||||
|
||||
// Keys for both sides to be used for the commitment transactions.
|
||||
OurCommitKey *btcec.PrivateKey
|
||||
TheirCommitKey *btcec.PublicKey
|
||||
|
||||
// Tracking total channel capacity, and the amount of funds allocated
|
||||
// to each side.
|
||||
Capacity btcutil.Amount
|
||||
OurBalance btcutil.Amount
|
||||
TheirBalance btcutil.Amount
|
||||
|
||||
// Commitment transactions for both sides (they're asymmetric). Also
|
||||
// their signature which lets us spend our version of the commitment
|
||||
// transaction.
|
||||
TheirCommitTx *wire.MsgTx
|
||||
OurCommitTx *wire.MsgTx
|
||||
TheirCommitSig []byte
|
||||
|
||||
// The final funding transaction. Kept wallet-related records.
|
||||
FundingTx *wire.MsgTx
|
||||
|
||||
// TODO(roasbeef): instead store a btcutil.Address here? Otherwise key
|
||||
// is stored unencrypted! Use manager.Encrypt() when storing.
|
||||
MultiSigKey *btcec.PrivateKey
|
||||
// TODO(roasbeef): encrypt also, or store in waddrmanager?
|
||||
FundingRedeemScript []byte
|
||||
|
||||
// Current revocation for their commitment transaction. However, since
|
||||
// this is the hash, and not the pre-image, we can't yet verify that
|
||||
// it's actually in the chain.
|
||||
TheirCurrentRevocation [wire.HashSize]byte
|
||||
TheirShaChain *shachain.HyperShaChain
|
||||
OurShaChain *shachain.HyperShaChain
|
||||
|
||||
// Final delivery address
|
||||
OurDeliveryAddress btcutil.Address
|
||||
TheirDeliveryAddress btcutil.Address
|
||||
|
||||
// In blocks
|
||||
CsvDelay uint32
|
||||
|
||||
// TODO(roasbeef): track fees, other stats?
|
||||
NumUpdates uint64
|
||||
TotalSatoshisSent uint64
|
||||
TotalSatoshisReceived uint64
|
||||
CreationTime time.Time
|
||||
}
|
@ -92,8 +92,8 @@ func newChannelReservation(t FundingType, fundingAmt btcutil.Amount,
|
||||
},
|
||||
partialState: &OpenChannelState{
|
||||
// TODO(roasbeef): assumes balanced symmetric channels.
|
||||
capacity: fundingAmt * 2,
|
||||
minFeePerKb: minFeeRate,
|
||||
Capacity: fundingAmt * 2,
|
||||
MinFeePerKb: minFeeRate,
|
||||
},
|
||||
reservationID: id,
|
||||
wallet: wallet,
|
||||
@ -153,14 +153,14 @@ func (r *ChannelReservation) CompleteReservation(fundingSigs [][]byte, commitmen
|
||||
func (r *ChannelReservation) TheirSignatures() ([][]byte, []byte) {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.theirFundingSigs, r.partialState.theirCommitSig
|
||||
return r.theirFundingSigs, r.partialState.TheirCommitSig
|
||||
}
|
||||
|
||||
// FinalFundingTransaction...
|
||||
func (r *ChannelReservation) FinalFundingTx() *wire.MsgTx {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.partialState.fundingTx
|
||||
return r.partialState.FundingTx
|
||||
}
|
||||
|
||||
// RequestFundingReserveCancellation...
|
||||
|
@ -417,9 +417,9 @@ func (l *LightningWallet) handleFundingReserveRequest(req *initFundingReserveMsg
|
||||
req.resp <- nil
|
||||
return
|
||||
}
|
||||
reservation.partialState.multiSigKey = multiSigKey
|
||||
reservation.partialState.MultiSigKey = multiSigKey
|
||||
ourContribution.MultiSigKey = multiSigKey.PubKey()
|
||||
reservation.partialState.ourCommitKey = commitKey
|
||||
reservation.partialState.OurCommitKey = commitKey
|
||||
ourContribution.CommitKey = commitKey.PubKey()
|
||||
|
||||
// Generate a fresh address to be used in the case of a cooperative
|
||||
@ -433,7 +433,7 @@ func (l *LightningWallet) handleFundingReserveRequest(req *initFundingReserveMsg
|
||||
req.resp <- nil
|
||||
return
|
||||
}
|
||||
reservation.partialState.ourDeliveryAddress = addrs[0].Address()
|
||||
reservation.partialState.OurDeliveryAddress = addrs[0].Address()
|
||||
ourContribution.DeliveryAddress = addrs[0].Address()
|
||||
|
||||
// Create a new shaChain for verifiable transaction revocations.
|
||||
@ -443,7 +443,7 @@ func (l *LightningWallet) handleFundingReserveRequest(req *initFundingReserveMsg
|
||||
req.resp <- nil
|
||||
return
|
||||
}
|
||||
reservation.partialState.ourShaChain = shaChain
|
||||
reservation.partialState.OurShaChain = shaChain
|
||||
ourContribution.RevocationHash = shaChain.CurrentRevocationHash()
|
||||
|
||||
// Funding reservation request succesfully handled. The funding inputs
|
||||
@ -503,8 +503,8 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
|
||||
|
||||
// Create a blank, fresh transaction. Soon to be a complete funding
|
||||
// transaction which will allow opening a lightning channel.
|
||||
pendingReservation.partialState.fundingTx = wire.NewMsgTx()
|
||||
fundingTx := pendingReservation.partialState.fundingTx
|
||||
pendingReservation.partialState.FundingTx = wire.NewMsgTx()
|
||||
fundingTx := pendingReservation.partialState.FundingTx
|
||||
|
||||
pendingReservation.theirContribution = req.contribution
|
||||
theirContribution := req.contribution
|
||||
@ -534,10 +534,10 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
|
||||
|
||||
// Finally, add the 2-of-2 multi-sig output which will set up the lightning
|
||||
// channel.
|
||||
ourKey := pendingReservation.partialState.multiSigKey
|
||||
ourKey := pendingReservation.partialState.MultiSigKey
|
||||
theirKey := theirContribution.MultiSigKey
|
||||
|
||||
channelCapacity := int64(pendingReservation.partialState.capacity)
|
||||
channelCapacity := int64(pendingReservation.partialState.Capacity)
|
||||
redeemScript, multiSigOut, err := fundMultiSigOut(ourKey.PubKey().SerializeCompressed(),
|
||||
theirKey.SerializeCompressed(), channelCapacity)
|
||||
if err != nil {
|
||||
@ -550,7 +550,7 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
|
||||
// Sort the transaction. Since both side agree to a cannonical
|
||||
// ordering, by sorting we no longer need to send the entire
|
||||
// transaction. Only signatures will be exchanged.
|
||||
txsort.InPlaceSort(pendingReservation.partialState.fundingTx)
|
||||
txsort.InPlaceSort(pendingReservation.partialState.FundingTx)
|
||||
|
||||
// Now that the transaction has been cannonically sorted, compute the
|
||||
// normalized transation ID before we attach our signatures.
|
||||
@ -589,7 +589,7 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
|
||||
return
|
||||
}
|
||||
|
||||
sigscript, err := txscript.SignatureScript(pendingReservation.partialState.fundingTx, i,
|
||||
sigscript, err := txscript.SignatureScript(pendingReservation.partialState.FundingTx, i,
|
||||
prevOut.PkScript, txscript.SigHashAll, privkey,
|
||||
ai.Compressed())
|
||||
if err != nil {
|
||||
@ -597,7 +597,7 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
|
||||
return
|
||||
}
|
||||
|
||||
pendingReservation.partialState.fundingTx.TxIn[i].SignatureScript = sigscript
|
||||
fundingTx.TxIn[i].SignatureScript = sigscript
|
||||
pendingReservation.ourFundingSigs = append(pendingReservation.ourFundingSigs, sigscript)
|
||||
}
|
||||
|
||||
@ -610,15 +610,14 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
|
||||
// Grab the hash of the current pre-image in our chain, this is needed
|
||||
// for out commitment tx.
|
||||
// TODO(roasbeef): grab partial state above to avoid long attr chain
|
||||
ourCurrentRevokeHash := pendingReservation.partialState.ourShaChain.CurrentRevocationHash()
|
||||
ourCurrentRevokeHash := pendingReservation.partialState.OurShaChain.CurrentRevocationHash()
|
||||
ourContribution.RevocationHash = ourCurrentRevokeHash
|
||||
|
||||
// Create the txIn to our commitment transaction. In the process, we
|
||||
// need to locate the index of the multi-sig output on the funding tx
|
||||
// since the outputs are cannonically sorted.
|
||||
fundingNTxid := pendingReservation.partialState.fundingTx.TxSha() // NOTE: assumes testnet-L
|
||||
_, multiSigIndex := findScriptOutputIndex(pendingReservation.partialState.fundingTx,
|
||||
multiSigOut.PkScript)
|
||||
fundingNTxid := fundingTx.TxSha() // NOTE: assumes testnet-L
|
||||
_, multiSigIndex := findScriptOutputIndex(fundingTx, multiSigOut.PkScript)
|
||||
fundingTxIn := wire.NewTxIn(wire.NewOutPoint(&fundingNTxid, multiSigIndex), nil)
|
||||
|
||||
// With the funding tx complete, create both commitment transactions.
|
||||
@ -639,9 +638,9 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
|
||||
return
|
||||
}
|
||||
|
||||
pendingReservation.partialState.theirCommitKey = theirCommitKey
|
||||
pendingReservation.partialState.theirCommitTx = theirCommitTx
|
||||
pendingReservation.partialState.ourCommitTx = ourCommitTx
|
||||
pendingReservation.partialState.TheirCommitKey = theirCommitKey
|
||||
pendingReservation.partialState.TheirCommitTx = theirCommitTx
|
||||
pendingReservation.partialState.OurCommitTx = ourCommitTx
|
||||
|
||||
// Generate a signature for their version of the initial commitment
|
||||
// transaction.
|
||||
@ -651,7 +650,7 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
|
||||
req.err <- err
|
||||
return
|
||||
}
|
||||
pendingReservation.partialState.theirCommitSig = sigTheirCommit
|
||||
pendingReservation.partialState.TheirCommitSig = sigTheirCommit
|
||||
pendingReservation.ourCommitmentSig = sigTheirCommit
|
||||
|
||||
req.err <- nil
|
||||
@ -674,7 +673,7 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
|
||||
// Now we can complete the funding transaction by adding their
|
||||
// signatures to their inputs.
|
||||
pendingReservation.theirFundingSigs = msg.theirFundingSigs
|
||||
fundingTx := pendingReservation.partialState.fundingTx
|
||||
fundingTx := pendingReservation.partialState.FundingTx
|
||||
for i, txin := range fundingTx.TxIn {
|
||||
if txin.SignatureScript == nil {
|
||||
txin.SignatureScript = pendingReservation.theirFundingSigs[i]
|
||||
@ -712,7 +711,7 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
|
||||
|
||||
// At this point, wen calso record and verify their isgnature for our
|
||||
// commitment transaction.
|
||||
pendingReservation.partialState.theirCommitSig = msg.theirCommitmentSig
|
||||
pendingReservation.partialState.TheirCommitSig = msg.theirCommitmentSig
|
||||
|
||||
// TODO(roasbeef): verify
|
||||
//commitSig := msg.theirCommitmentSig
|
||||
@ -740,7 +739,7 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
|
||||
// Create a new sub-bucket within the open channel bucket
|
||||
// specifically for this channel.
|
||||
// TODO(roasbeef): should def be indexed by LNID, cuz mal etc.
|
||||
txID := pendingReservation.partialState.fundingTx.TxSha()
|
||||
txID := fundingTx.TxSha()
|
||||
chanBucket, err := openChanBucket.CreateBucketIfNotExists(txID.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -360,7 +360,7 @@ func testBasicWalletReservationWorkFlow(lnwallet *LightningWallet, t *testing.T)
|
||||
t.Fatalf("commitment sig not found")
|
||||
}
|
||||
// Additionally, the funding tx should have been populated.
|
||||
if chanReservation.partialState.fundingTx == nil {
|
||||
if chanReservation.partialState.FundingTx == nil {
|
||||
t.Fatalf("funding transaction never created!")
|
||||
}
|
||||
// Their funds should also be filled in.
|
||||
@ -388,7 +388,7 @@ func testBasicWalletReservationWorkFlow(lnwallet *LightningWallet, t *testing.T)
|
||||
|
||||
// Alice responds with her output, change addr, multi-sig key and signatures.
|
||||
// Bob then responds with his signatures.
|
||||
bobsSigs, err := bobNode.signFundingTx(chanReservation.partialState.fundingTx)
|
||||
bobsSigs, err := bobNode.signFundingTx(chanReservation.partialState.FundingTx)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to sign inputs for bob: %v", err)
|
||||
}
|
||||
@ -414,7 +414,7 @@ func testBasicWalletReservationWorkFlow(lnwallet *LightningWallet, t *testing.T)
|
||||
|
||||
// The sub-bucket for this channel, keyed by the txid of the
|
||||
// funding transaction
|
||||
txid := chanReservation.partialState.fundingTx.TxSha()
|
||||
txid := chanReservation.partialState.FundingTx.TxSha()
|
||||
bobChanBucket := openChanBucket.Bucket(txid[:])
|
||||
if bobChanBucket == nil {
|
||||
t.Fatalf("bucket for the alice-bob channe should exist, " +
|
||||
@ -427,7 +427,7 @@ func testBasicWalletReservationWorkFlow(lnwallet *LightningWallet, t *testing.T)
|
||||
|
||||
// The hash of the stored tx should be indentical to our funding tx.
|
||||
storedTxId := storedTx.TxSha()
|
||||
actualTxId := chanReservation.partialState.fundingTx.TxSha()
|
||||
actualTxId := chanReservation.partialState.FundingTx.TxSha()
|
||||
if !bytes.Equal(storedTxId.Bytes(), actualTxId.Bytes()) {
|
||||
t.Fatalf("stored funding tx doesn't match actual")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user