channeldb: modify schema to multiple-channels-per-peer
This commit overhauls the current schema for storing active channels in order to support tracking+updating multiple open channels for a particular peer. Channels are now uniquely identified by an output (txid:index) rather than an arbitrary hash value. As a result, the funding transaction is no longer stored, as only the txin is required to lookup the original transaction, and to sign for new commitment states. A new bucket, nested within the bucket for a node’s Lightning ID has been created. This new bucket acts as an index to the active channels for a particular peer by storing all the active channel points as keys within the bucket. This bucket can then be scanned in a linear fashion, or queried randomly in order to retrieve channel information. The split between top-level, and channel-level keys remains the same. The primary modification comes in using the channel ID (the funding outpoint) as the key suffix for all top-level and channel-level keys.
This commit is contained in:
parent
43c84c2ce5
commit
c2818a549b
@ -2,17 +2,16 @@ package channeldb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"io"
|
||||||
"fmt"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/boltdb/bolt"
|
"github.com/boltdb/bolt"
|
||||||
|
"github.com/lightningnetwork/lnd/elkrem"
|
||||||
"github.com/roasbeef/btcd/btcec"
|
"github.com/roasbeef/btcd/btcec"
|
||||||
"github.com/roasbeef/btcd/wire"
|
"github.com/roasbeef/btcd/wire"
|
||||||
"github.com/roasbeef/btcwallet/walletdb"
|
|
||||||
"github.com/lightningnetwork/lnd/elkrem"
|
|
||||||
"github.com/roasbeef/btcutil"
|
"github.com/roasbeef/btcutil"
|
||||||
|
"github.com/roasbeef/btcwallet/walletdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -25,6 +24,15 @@ var (
|
|||||||
// to gather stats such as total satoshis received.
|
// to gather stats such as total satoshis received.
|
||||||
openChannelBucket = []byte("ocb")
|
openChannelBucket = []byte("ocb")
|
||||||
|
|
||||||
|
// chanIDBucket is a thrid-level bucket stored within a node's ID bucket
|
||||||
|
// in the open channel bucket. The resolution path looks something like:
|
||||||
|
// ocb -> nodeID -> cib. This bucket contains a series of keys with no
|
||||||
|
// values, these keys are the channel ID's of all the active channels
|
||||||
|
// we currently have with a specified nodeID. This bucket acts as an
|
||||||
|
// additional indexing allowing random access and sequential scans over
|
||||||
|
// active channels.
|
||||||
|
chanIDBucket = []byte("cib")
|
||||||
|
|
||||||
// closedChannelBucket stores summarization information concerning
|
// closedChannelBucket stores summarization information concerning
|
||||||
// previously open, but now closed channels.
|
// previously open, but now closed channels.
|
||||||
closedChannelBucket = []byte("ccb")
|
closedChannelBucket = []byte("ccb")
|
||||||
@ -91,7 +99,7 @@ type OpenChannel struct {
|
|||||||
TheirLNID [wire.HashSize]byte
|
TheirLNID [wire.HashSize]byte
|
||||||
|
|
||||||
// The ID of a channel is the txid of the funding transaction.
|
// The ID of a channel is the txid of the funding transaction.
|
||||||
ChanID [wire.HashSize]byte
|
ChanID *wire.OutPoint
|
||||||
|
|
||||||
MinFeePerKb btcutil.Amount
|
MinFeePerKb btcutil.Amount
|
||||||
// Our reserve. Assume symmetric reserve amounts. Only needed if the
|
// Our reserve. Assume symmetric reserve amounts. Only needed if the
|
||||||
@ -114,10 +122,11 @@ type OpenChannel struct {
|
|||||||
TheirCommitTx *wire.MsgTx
|
TheirCommitTx *wire.MsgTx
|
||||||
OurCommitTx *wire.MsgTx
|
OurCommitTx *wire.MsgTx
|
||||||
|
|
||||||
// The final funding transaction. Kept for wallet-related records.
|
// The outpoint of the final funding transaction.
|
||||||
FundingTx *wire.MsgTx
|
FundingOutpoint *wire.OutPoint
|
||||||
|
|
||||||
MultiSigKey *btcec.PrivateKey
|
OurMultiSigKey *btcec.PrivateKey
|
||||||
|
TheirMultiSigKey *btcec.PublicKey
|
||||||
FundingRedeemScript []byte
|
FundingRedeemScript []byte
|
||||||
|
|
||||||
// In blocks
|
// In blocks
|
||||||
@ -155,6 +164,46 @@ type OpenChannel struct {
|
|||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FullSync serializes, and writes to disk the *full* channel state, using
|
||||||
|
// both the active channel bucket to store the prefixed column fields, and the
|
||||||
|
// remote node's ID to store the remainder of the channel state.
|
||||||
|
//
|
||||||
|
// NOTE: This method requires an active EncryptorDecryptor to be registered in
|
||||||
|
// order to encrypt sensitive information.
|
||||||
|
func (c *OpenChannel) FullSync() error {
|
||||||
|
return c.Db.store.Update(func(tx *bolt.Tx) error {
|
||||||
|
// First fetch the top level bucket which stores all data related to
|
||||||
|
// current, active channels.
|
||||||
|
chanBucket, err := tx.CreateBucketIfNotExists(openChannelBucket)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Within this top level bucket, fetch the bucket dedicated to storing
|
||||||
|
// open channel data specific to the remote node.
|
||||||
|
nodeChanBucket, err := chanBucket.CreateBucketIfNotExists(c.TheirLNID[:])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add this channel ID to the node's active channel index if
|
||||||
|
// it doesn't already exist.
|
||||||
|
chanIDBucket, err := nodeChanBucket.CreateBucketIfNotExists(chanIDBucket)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var b bytes.Buffer
|
||||||
|
if err := writeOutpoint(&b, c.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if chanIDBucket.Get(b.Bytes()) == nil {
|
||||||
|
chanIDBucket.Put(b.Bytes(), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return putOpenChannel(chanBucket, nodeChanBucket, c, c.Db.cryptoSystem)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// ChannelSnapshot....
|
// ChannelSnapshot....
|
||||||
// TODO(roasbeef): methods to roll forwards/backwards in state etc
|
// TODO(roasbeef): methods to roll forwards/backwards in state etc
|
||||||
// * use botldb cursor?
|
// * use botldb cursor?
|
||||||
@ -195,29 +244,6 @@ func (c OpenChannel) RecordChannelDelta(theirRevokedCommit *wire.MsgTx, updateNu
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FullSync serializes, and writes to disk the *full* channel state, using
|
|
||||||
// both the active channel bucket to store the prefixed column fields, and the
|
|
||||||
// remote node's ID to store the remainder of the channel state.
|
|
||||||
//
|
|
||||||
// NOTE: This method requires an active EncryptorDecryptor to be registered in
|
|
||||||
// order to encrypt sensitive information.
|
|
||||||
func (c *OpenChannel) FullSync() error {
|
|
||||||
return c.Db.store.Update(func(tx *bolt.Tx) error {
|
|
||||||
// First fetch the top level bucket which stores all data related to
|
|
||||||
// current, active channels.
|
|
||||||
chanBucket := tx.Bucket(openChannelBucket)
|
|
||||||
|
|
||||||
// WIthin this top level bucket, fetch the bucket dedicated to storing
|
|
||||||
// open channel data specific to the remote node.
|
|
||||||
nodeChanBucket, err := chanBucket.CreateBucketIfNotExists(c.TheirLNID[:])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return putOpenChannel(chanBucket, nodeChanBucket, c, c.Db.cryptoSystem)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// putChannel serializes, and stores the current state of the channel in its
|
// putChannel serializes, and stores the current state of the channel in its
|
||||||
// entirety.
|
// entirety.
|
||||||
func putOpenChannel(openChanBucket *bolt.Bucket, nodeChanBucket *bolt.Bucket,
|
func putOpenChannel(openChanBucket *bolt.Bucket, nodeChanBucket *bolt.Bucket,
|
||||||
@ -269,19 +295,13 @@ func putOpenChannel(openChanBucket *bolt.Bucket, nodeChanBucket *bolt.Bucket,
|
|||||||
// sensitive) the complete channel currently active with the passed nodeID.
|
// sensitive) the complete channel currently active with the passed nodeID.
|
||||||
// An EncryptorDecryptor is required to decrypt sensitive information stored
|
// An EncryptorDecryptor is required to decrypt sensitive information stored
|
||||||
// within the database.
|
// within the database.
|
||||||
func fetchOpenChannel(openChanBucket *bolt.Bucket, nodeID [32]byte,
|
func fetchOpenChannel(openChanBucket *bolt.Bucket, nodeChanBucket *bolt.Bucket,
|
||||||
decryptor EncryptorDecryptor) (*OpenChannel, error) {
|
chanID *wire.OutPoint, decryptor EncryptorDecryptor) (*OpenChannel, error) {
|
||||||
|
|
||||||
// WIthin this top level bucket, fetch the bucket dedicated to storing
|
channel := &OpenChannel{
|
||||||
// open channel data specific to the remote node.
|
ChanID: chanID,
|
||||||
nodeChanBucket := openChanBucket.Bucket(nodeID[:])
|
|
||||||
if nodeChanBucket == nil {
|
|
||||||
return nil, fmt.Errorf("node chan bucket for node %v does not exist",
|
|
||||||
hex.EncodeToString(nodeID[:]))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
channel := &OpenChannel{}
|
|
||||||
|
|
||||||
// First, read out the fields of the channel update less frequently.
|
// First, read out the fields of the channel update less frequently.
|
||||||
if err := fetchChannelIDs(nodeChanBucket, channel); err != nil {
|
if err := fetchChannelIDs(nodeChanBucket, channel); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -330,8 +350,13 @@ func putChanCapacity(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
|||||||
scratch2 := make([]byte, 8)
|
scratch2 := make([]byte, 8)
|
||||||
scratch3 := make([]byte, 8)
|
scratch3 := make([]byte, 8)
|
||||||
|
|
||||||
keyPrefix := make([]byte, 3+32)
|
var b bytes.Buffer
|
||||||
copy(keyPrefix[3:], channel.ChanID[:])
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPrefix := make([]byte, 3+b.Len())
|
||||||
|
copy(keyPrefix[3:], b.Bytes())
|
||||||
|
|
||||||
copy(keyPrefix[:3], chanCapacityPrefix)
|
copy(keyPrefix[:3], chanCapacityPrefix)
|
||||||
byteOrder.PutUint64(scratch1, uint64(channel.Capacity))
|
byteOrder.PutUint64(scratch1, uint64(channel.Capacity))
|
||||||
@ -351,9 +376,14 @@ func putChanCapacity(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func fetchChanCapacity(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func fetchChanCapacity(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
// A byte slice re-used to compute each key prefix eblow.
|
// A byte slice re-used to compute each key prefix below.
|
||||||
keyPrefix := make([]byte, 3+32)
|
var b bytes.Buffer
|
||||||
copy(keyPrefix[3:], channel.ChanID[:])
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPrefix := make([]byte, 3+b.Len())
|
||||||
|
copy(keyPrefix[3:], b.Bytes())
|
||||||
|
|
||||||
copy(keyPrefix[:3], chanCapacityPrefix)
|
copy(keyPrefix[:3], chanCapacityPrefix)
|
||||||
capacityBytes := openChanBucket.Get(keyPrefix)
|
capacityBytes := openChanBucket.Get(keyPrefix)
|
||||||
@ -374,17 +404,27 @@ func putChanMinFeePerKb(openChanBucket *bolt.Bucket, channel *OpenChannel) error
|
|||||||
scratch := make([]byte, 8)
|
scratch := make([]byte, 8)
|
||||||
byteOrder.PutUint64(scratch, uint64(channel.MinFeePerKb))
|
byteOrder.PutUint64(scratch, uint64(channel.MinFeePerKb))
|
||||||
|
|
||||||
keyPrefix := make([]byte, 3+32)
|
var b bytes.Buffer
|
||||||
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPrefix := make([]byte, 3+b.Len())
|
||||||
copy(keyPrefix, minFeePerKbPrefix)
|
copy(keyPrefix, minFeePerKbPrefix)
|
||||||
copy(keyPrefix[3:], channel.ChanID[:])
|
copy(keyPrefix[3:], b.Bytes())
|
||||||
|
|
||||||
return openChanBucket.Put(keyPrefix, scratch)
|
return openChanBucket.Put(keyPrefix, scratch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchChanMinFeePerKb(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func fetchChanMinFeePerKb(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
keyPrefix := make([]byte, 3+32)
|
var b bytes.Buffer
|
||||||
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPrefix := make([]byte, 3+b.Len())
|
||||||
copy(keyPrefix, minFeePerKbPrefix)
|
copy(keyPrefix, minFeePerKbPrefix)
|
||||||
copy(keyPrefix[3:], channel.ChanID[:])
|
copy(keyPrefix[3:], b.Bytes())
|
||||||
|
|
||||||
feeBytes := openChanBucket.Get(keyPrefix)
|
feeBytes := openChanBucket.Get(keyPrefix)
|
||||||
channel.MinFeePerKb = btcutil.Amount(byteOrder.Uint64(feeBytes))
|
channel.MinFeePerKb = btcutil.Amount(byteOrder.Uint64(feeBytes))
|
||||||
@ -396,17 +436,27 @@ func putChanNumUpdates(openChanBucket *bolt.Bucket, channel *OpenChannel) error
|
|||||||
scratch := make([]byte, 8)
|
scratch := make([]byte, 8)
|
||||||
byteOrder.PutUint64(scratch, channel.NumUpdates)
|
byteOrder.PutUint64(scratch, channel.NumUpdates)
|
||||||
|
|
||||||
keyPrefix := make([]byte, 3+32)
|
var b bytes.Buffer
|
||||||
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPrefix := make([]byte, 3+b.Len())
|
||||||
copy(keyPrefix, updatePrefix)
|
copy(keyPrefix, updatePrefix)
|
||||||
copy(keyPrefix[3:], channel.ChanID[:])
|
copy(keyPrefix[3:], b.Bytes())
|
||||||
|
|
||||||
return openChanBucket.Put(keyPrefix, scratch)
|
return openChanBucket.Put(keyPrefix, scratch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchChanNumUpdates(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func fetchChanNumUpdates(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
keyPrefix := make([]byte, 3+32)
|
var b bytes.Buffer
|
||||||
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPrefix := make([]byte, 3+b.Len())
|
||||||
copy(keyPrefix, updatePrefix)
|
copy(keyPrefix, updatePrefix)
|
||||||
copy(keyPrefix[3:], channel.ChanID[:])
|
copy(keyPrefix[3:], b.Bytes())
|
||||||
|
|
||||||
updateBytes := openChanBucket.Get(keyPrefix)
|
updateBytes := openChanBucket.Get(keyPrefix)
|
||||||
channel.NumUpdates = byteOrder.Uint64(updateBytes)
|
channel.NumUpdates = byteOrder.Uint64(updateBytes)
|
||||||
@ -417,8 +467,14 @@ func fetchChanNumUpdates(openChanBucket *bolt.Bucket, channel *OpenChannel) erro
|
|||||||
func putChanTotalFlow(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func putChanTotalFlow(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
scratch1 := make([]byte, 8)
|
scratch1 := make([]byte, 8)
|
||||||
scratch2 := make([]byte, 8)
|
scratch2 := make([]byte, 8)
|
||||||
keyPrefix := make([]byte, 3+32)
|
|
||||||
copy(keyPrefix[3:], channel.ChanID[:])
|
var b bytes.Buffer
|
||||||
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPrefix := make([]byte, 3+b.Len())
|
||||||
|
copy(keyPrefix[3:], b.Bytes())
|
||||||
|
|
||||||
copy(keyPrefix[:3], satSentPrefix)
|
copy(keyPrefix[:3], satSentPrefix)
|
||||||
byteOrder.PutUint64(scratch1, uint64(channel.TotalSatoshisSent))
|
byteOrder.PutUint64(scratch1, uint64(channel.TotalSatoshisSent))
|
||||||
@ -432,8 +488,13 @@ func putChanTotalFlow(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func fetchChanTotalFlow(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func fetchChanTotalFlow(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
keyPrefix := make([]byte, 3+32)
|
var b bytes.Buffer
|
||||||
copy(keyPrefix[3:], channel.ChanID[:])
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPrefix := make([]byte, 3+b.Len())
|
||||||
|
copy(keyPrefix[3:], b.Bytes())
|
||||||
|
|
||||||
copy(keyPrefix[:3], satSentPrefix)
|
copy(keyPrefix[:3], satSentPrefix)
|
||||||
totalSentBytes := openChanBucket.Get(keyPrefix)
|
totalSentBytes := openChanBucket.Get(keyPrefix)
|
||||||
@ -448,19 +509,30 @@ func fetchChanTotalFlow(openChanBucket *bolt.Bucket, channel *OpenChannel) error
|
|||||||
|
|
||||||
func putChanNetFee(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func putChanNetFee(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
scratch := make([]byte, 8)
|
scratch := make([]byte, 8)
|
||||||
keyPrefix := make([]byte, 3+32)
|
|
||||||
|
|
||||||
|
var b bytes.Buffer
|
||||||
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPrefix := make([]byte, 3+b.Len())
|
||||||
copy(keyPrefix, netFeesPrefix)
|
copy(keyPrefix, netFeesPrefix)
|
||||||
copy(keyPrefix[3:], channel.ChanID[:])
|
copy(keyPrefix[3:], b.Bytes())
|
||||||
|
|
||||||
byteOrder.PutUint64(scratch, uint64(channel.TotalNetFees))
|
byteOrder.PutUint64(scratch, uint64(channel.TotalNetFees))
|
||||||
return openChanBucket.Put(keyPrefix, scratch)
|
return openChanBucket.Put(keyPrefix, scratch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchChanNetFee(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func fetchChanNetFee(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
keyPrefix := make([]byte, 3+32)
|
var b bytes.Buffer
|
||||||
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPrefix := make([]byte, 3+b.Len())
|
||||||
copy(keyPrefix, netFeesPrefix)
|
copy(keyPrefix, netFeesPrefix)
|
||||||
copy(keyPrefix[3:], channel.ChanID[:])
|
copy(keyPrefix[3:], b.Bytes())
|
||||||
|
|
||||||
feeBytes := openChanBucket.Get(keyPrefix)
|
feeBytes := openChanBucket.Get(keyPrefix)
|
||||||
channel.TotalNetFees = byteOrder.Uint64(feeBytes)
|
channel.TotalNetFees = byteOrder.Uint64(feeBytes)
|
||||||
|
|
||||||
@ -468,18 +540,33 @@ func fetchChanNetFee(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func putChannelIDs(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func putChannelIDs(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
idSlice := make([]byte, wire.HashSize*2)
|
var b bytes.Buffer
|
||||||
copy(idSlice, channel.TheirLNID[:])
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
copy(idSlice[32:], channel.ChanID[:])
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nodeChanBucket.Put(chanIDKey, idSlice)
|
// Construct the id key: cid || channelID.
|
||||||
|
// TODO(roasbeef): abstract out to func
|
||||||
|
idKey := make([]byte, len(chanIDKey)+b.Len())
|
||||||
|
copy(idKey[:3], chanIDKey)
|
||||||
|
copy(idKey[3:], b.Bytes())
|
||||||
|
|
||||||
|
return nodeChanBucket.Put(idKey, channel.TheirLNID[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchChannelIDs(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func fetchChannelIDs(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
idBytes := nodeChanBucket.Get(chanIDKey)
|
var b bytes.Buffer
|
||||||
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
copy(channel.TheirLNID[:], idBytes[:32])
|
// Construct the id key: cid || channelID.
|
||||||
copy(channel.ChanID[:], idBytes[32:])
|
idKey := make([]byte, len(chanIDKey)+b.Len())
|
||||||
|
copy(idKey[:3], chanIDKey)
|
||||||
|
copy(idKey[3:], b.Bytes())
|
||||||
|
|
||||||
|
idBytes := nodeChanBucket.Get(idKey)
|
||||||
|
copy(channel.TheirLNID[:], idBytes)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -487,6 +574,16 @@ func fetchChannelIDs(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
|||||||
func putChanCommitKeys(nodeChanBucket *bolt.Bucket, channel *OpenChannel,
|
func putChanCommitKeys(nodeChanBucket *bolt.Bucket, channel *OpenChannel,
|
||||||
ed EncryptorDecryptor) error {
|
ed EncryptorDecryptor) error {
|
||||||
|
|
||||||
|
// Construct the key which stores the commitment keys: ckk || channelID.
|
||||||
|
// TODO(roasbeef): factor into func
|
||||||
|
var bc bytes.Buffer
|
||||||
|
if err := writeOutpoint(&bc, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
commitKey := make([]byte, len(commitKeys)+bc.Len())
|
||||||
|
copy(commitKey[:3], commitKeys)
|
||||||
|
copy(commitKeys[3:], bc.Bytes())
|
||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
|
|
||||||
if _, err := b.Write(channel.TheirCommitKey.SerializeCompressed()); err != nil {
|
if _, err := b.Write(channel.TheirCommitKey.SerializeCompressed()); err != nil {
|
||||||
@ -502,14 +599,24 @@ func putChanCommitKeys(nodeChanBucket *bolt.Bucket, channel *OpenChannel,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeChanBucket.Put(commitKeys, b.Bytes())
|
return nodeChanBucket.Put(commitKey, b.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchChanCommitKeys(nodeChanBucket *bolt.Bucket, channel *OpenChannel,
|
func fetchChanCommitKeys(nodeChanBucket *bolt.Bucket, channel *OpenChannel,
|
||||||
ed EncryptorDecryptor) error {
|
ed EncryptorDecryptor) error {
|
||||||
|
|
||||||
|
// Construct the key which stores the commitment keys: ckk || channelID.
|
||||||
|
// TODO(roasbeef): factor into func
|
||||||
|
var bc bytes.Buffer
|
||||||
|
if err := writeOutpoint(&bc, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
commitKey := make([]byte, len(commitKeys)+bc.Len())
|
||||||
|
copy(commitKey[:3], commitKeys)
|
||||||
|
copy(commitKeys[3:], bc.Bytes())
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
keyBytes := nodeChanBucket.Get(commitKeys)
|
keyBytes := nodeChanBucket.Get(commitKey)
|
||||||
|
|
||||||
channel.TheirCommitKey, err = btcec.ParsePubKey(keyBytes[:33], btcec.S256())
|
channel.TheirCommitKey, err = btcec.ParsePubKey(keyBytes[:33], btcec.S256())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -530,6 +637,14 @@ func fetchChanCommitKeys(nodeChanBucket *bolt.Bucket, channel *OpenChannel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func putChanCommitTxns(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func putChanCommitTxns(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
|
var bc bytes.Buffer
|
||||||
|
if err := writeOutpoint(&bc, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
txnsKey := make([]byte, len(commitTxnsKey)+bc.Len())
|
||||||
|
copy(txnsKey[:3], commitTxnsKey)
|
||||||
|
copy(txnsKey[3:], bc.Bytes())
|
||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
|
|
||||||
if err := channel.TheirCommitTx.Serialize(&b); err != nil {
|
if err := channel.TheirCommitTx.Serialize(&b); err != nil {
|
||||||
@ -550,11 +665,19 @@ func putChanCommitTxns(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeChanBucket.Put(commitTxnsKey, b.Bytes())
|
return nodeChanBucket.Put(txnsKey, b.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchChanCommitTxns(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func fetchChanCommitTxns(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
txnBytes := bytes.NewReader(nodeChanBucket.Get(commitTxnsKey))
|
var bc bytes.Buffer
|
||||||
|
if err := writeOutpoint(&bc, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
txnsKey := make([]byte, len(commitTxnsKey)+bc.Len())
|
||||||
|
copy(txnsKey[:3], commitTxnsKey)
|
||||||
|
copy(txnsKey[3:], bc.Bytes())
|
||||||
|
|
||||||
|
txnBytes := bytes.NewReader(nodeChanBucket.Get(txnsKey))
|
||||||
|
|
||||||
channel.TheirCommitTx = wire.NewMsgTx()
|
channel.TheirCommitTx = wire.NewMsgTx()
|
||||||
if err := channel.TheirCommitTx.Deserialize(txnBytes); err != nil {
|
if err := channel.TheirCommitTx.Deserialize(txnBytes); err != nil {
|
||||||
@ -583,19 +706,32 @@ func fetchChanCommitTxns(nodeChanBucket *bolt.Bucket, channel *OpenChannel) erro
|
|||||||
|
|
||||||
func putChanFundingInfo(nodeChanBucket *bolt.Bucket, channel *OpenChannel,
|
func putChanFundingInfo(nodeChanBucket *bolt.Bucket, channel *OpenChannel,
|
||||||
ed EncryptorDecryptor) error {
|
ed EncryptorDecryptor) error {
|
||||||
|
|
||||||
|
var bc bytes.Buffer
|
||||||
|
if err := writeOutpoint(&bc, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fundTxnKey := make([]byte, len(fundingTxnKey)+bc.Len())
|
||||||
|
copy(fundTxnKey[:3], fundingTxnKey)
|
||||||
|
copy(fundTxnKey[3:], bc.Bytes())
|
||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
|
|
||||||
if err := channel.FundingTx.Serialize(&b); err != nil {
|
if err := writeOutpoint(&b, channel.FundingOutpoint); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptedPriv, err := ed.Encrypt(channel.MultiSigKey.Serialize())
|
encryptedPriv, err := ed.Encrypt(channel.OurMultiSigKey.Serialize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := wire.WriteVarBytes(&b, 0, encryptedPriv); err != nil {
|
if err := wire.WriteVarBytes(&b, 0, encryptedPriv); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
theirSerKey := channel.TheirMultiSigKey.SerializeCompressed()
|
||||||
|
if err := wire.WriteVarBytes(&b, 0, theirSerKey); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := wire.WriteVarBytes(&b, 0, channel.FundingRedeemScript[:]); err != nil {
|
if err := wire.WriteVarBytes(&b, 0, channel.FundingRedeemScript[:]); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -608,16 +744,25 @@ func putChanFundingInfo(nodeChanBucket *bolt.Bucket, channel *OpenChannel,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeChanBucket.Put(fundingTxnKey, b.Bytes())
|
return nodeChanBucket.Put(fundTxnKey, b.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchChanFundingInfo(nodeChanBucket *bolt.Bucket, channel *OpenChannel,
|
func fetchChanFundingInfo(nodeChanBucket *bolt.Bucket, channel *OpenChannel,
|
||||||
ed EncryptorDecryptor) error {
|
ed EncryptorDecryptor) error {
|
||||||
|
|
||||||
infoBytes := bytes.NewReader(nodeChanBucket.Get(fundingTxnKey))
|
var b bytes.Buffer
|
||||||
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fundTxnKey := make([]byte, len(fundingTxnKey)+b.Len())
|
||||||
|
copy(fundTxnKey[:3], fundingTxnKey)
|
||||||
|
copy(fundTxnKey[3:], b.Bytes())
|
||||||
|
|
||||||
channel.FundingTx = wire.NewMsgTx()
|
infoBytes := bytes.NewReader(nodeChanBucket.Get(fundTxnKey))
|
||||||
if err := channel.FundingTx.Deserialize(infoBytes); err != nil {
|
|
||||||
|
// TODO(roasbeef): can remove as channel ID *is* the funding point now.
|
||||||
|
channel.FundingOutpoint = &wire.OutPoint{}
|
||||||
|
if err := readOutpoint(infoBytes, channel.FundingOutpoint); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -629,7 +774,16 @@ func fetchChanFundingInfo(nodeChanBucket *bolt.Bucket, channel *OpenChannel,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
channel.MultiSigKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), decryptedPriv)
|
channel.OurMultiSigKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), decryptedPriv)
|
||||||
|
|
||||||
|
theirKeyBytes, err := wire.ReadVarBytes(infoBytes, 0, 33, "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
channel.TheirMultiSigKey, err = btcec.ParsePubKey(theirKeyBytes, btcec.S256())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
channel.FundingRedeemScript, err = wire.ReadVarBytes(infoBytes, 0, 520, "")
|
channel.FundingRedeemScript, err = wire.ReadVarBytes(infoBytes, 0, 520, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -647,6 +801,15 @@ func fetchChanFundingInfo(nodeChanBucket *bolt.Bucket, channel *OpenChannel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func putChanEklremState(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func putChanEklremState(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
|
var bc bytes.Buffer
|
||||||
|
if err := writeOutpoint(&bc, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
elkremKey := make([]byte, len(elkremStateKey)+bc.Len())
|
||||||
|
copy(elkremKey[:3], elkremStateKey)
|
||||||
|
copy(elkremKey[3:], bc.Bytes())
|
||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
|
|
||||||
if _, err := b.Write(channel.TheirCurrentRevocation[:]); err != nil {
|
if _, err := b.Write(channel.TheirCurrentRevocation[:]); err != nil {
|
||||||
@ -669,11 +832,19 @@ func putChanEklremState(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeChanBucket.Put(elkremStateKey, b.Bytes())
|
return nodeChanBucket.Put(elkremKey, b.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchChanEklremState(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func fetchChanEklremState(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
elkremStateBytes := bytes.NewReader(nodeChanBucket.Get(elkremStateKey))
|
var b bytes.Buffer
|
||||||
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
elkremKey := make([]byte, len(elkremStateKey)+b.Len())
|
||||||
|
copy(elkremKey[:3], elkremStateKey)
|
||||||
|
copy(elkremKey[3:], b.Bytes())
|
||||||
|
|
||||||
|
elkremStateBytes := bytes.NewReader(nodeChanBucket.Get(elkremKey))
|
||||||
|
|
||||||
if _, err := elkremStateBytes.Read(channel.TheirCurrentRevocation[:]); err != nil {
|
if _, err := elkremStateBytes.Read(channel.TheirCurrentRevocation[:]); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -703,6 +874,14 @@ func fetchChanEklremState(nodeChanBucket *bolt.Bucket, channel *OpenChannel) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func putChanDeliveryScripts(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func putChanDeliveryScripts(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
|
var bc bytes.Buffer
|
||||||
|
if err := writeOutpoint(&bc, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
deliveryKey := make([]byte, len(deliveryScriptsKey)+bc.Len())
|
||||||
|
copy(deliveryKey[:3], deliveryScriptsKey)
|
||||||
|
copy(deliveryKey[3:], bc.Bytes())
|
||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
if err := wire.WriteVarBytes(&b, 0, channel.OurDeliveryScript); err != nil {
|
if err := wire.WriteVarBytes(&b, 0, channel.OurDeliveryScript); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -716,6 +895,14 @@ func putChanDeliveryScripts(nodeChanBucket *bolt.Bucket, channel *OpenChannel) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func fetchChanDeliveryScripts(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
func fetchChanDeliveryScripts(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||||
|
var b bytes.Buffer
|
||||||
|
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
deliveryKey := make([]byte, len(deliveryScriptsKey)+b.Len())
|
||||||
|
copy(deliveryKey[:3], deliveryScriptsKey)
|
||||||
|
copy(deliveryKey[3:], b.Bytes())
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
deliveryBytes := bytes.NewReader(nodeChanBucket.Get(deliveryScriptsKey))
|
deliveryBytes := bytes.NewReader(nodeChanBucket.Get(deliveryScriptsKey))
|
||||||
|
|
||||||
@ -731,3 +918,35 @@ func fetchChanDeliveryScripts(nodeChanBucket *bolt.Bucket, channel *OpenChannel)
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeOutpoint(w io.Writer, o *wire.OutPoint) error {
|
||||||
|
scratch := make([]byte, 4)
|
||||||
|
|
||||||
|
if err := wire.WriteVarBytes(w, 0, o.Hash[:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
byteOrder.PutUint32(scratch, o.Index)
|
||||||
|
if _, err := w.Write(scratch); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readOutpoint(r io.Reader, o *wire.OutPoint) error {
|
||||||
|
scratch := make([]byte, 4)
|
||||||
|
|
||||||
|
txid, err := wire.ReadVarBytes(r, 0, 32, "prevout")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
copy(o.Hash[:], txid)
|
||||||
|
|
||||||
|
if _, err := r.Read(scratch); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.Index = byteOrder.Uint32(scratch)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -4,16 +4,17 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/lightningnetwork/lnd/elkrem"
|
||||||
"github.com/roasbeef/btcd/btcec"
|
"github.com/roasbeef/btcd/btcec"
|
||||||
"github.com/roasbeef/btcd/chaincfg"
|
"github.com/roasbeef/btcd/chaincfg"
|
||||||
"github.com/roasbeef/btcd/txscript"
|
"github.com/roasbeef/btcd/txscript"
|
||||||
"github.com/roasbeef/btcd/wire"
|
"github.com/roasbeef/btcd/wire"
|
||||||
_ "github.com/roasbeef/btcwallet/walletdb/bdb"
|
|
||||||
"github.com/lightningnetwork/lnd/elkrem"
|
|
||||||
"github.com/roasbeef/btcutil"
|
"github.com/roasbeef/btcutil"
|
||||||
|
_ "github.com/roasbeef/btcwallet/walletdb/bdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -25,11 +26,14 @@ var (
|
|||||||
0xd, 0xe7, 0x93, 0xe4, 0xb7, 0x25, 0xb8, 0x4d,
|
0xd, 0xe7, 0x93, 0xe4, 0xb7, 0x25, 0xb8, 0x4d,
|
||||||
0x1e, 0xb, 0x4c, 0xf9, 0x9e, 0xc5, 0x8c, 0xe9,
|
0x1e, 0xb, 0x4c, 0xf9, 0x9e, 0xc5, 0x8c, 0xe9,
|
||||||
}
|
}
|
||||||
id = [wire.HashSize]byte{
|
id = &wire.OutPoint{
|
||||||
0x51, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
|
Hash: [wire.HashSize]byte{
|
||||||
0x48, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
|
0x51, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
|
||||||
0x2d, 0xe7, 0x93, 0xe4, 0xb7, 0x25, 0xb8, 0x4d,
|
0x48, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
|
||||||
0x1f, 0xb, 0x4c, 0xf9, 0x9e, 0xc5, 0x8c, 0xe9,
|
0x2d, 0xe7, 0x93, 0xe4, 0xb7, 0x25, 0xb8, 0x4d,
|
||||||
|
0x1f, 0xb, 0x4c, 0xf9, 0x9e, 0xc5, 0x8c, 0xe9,
|
||||||
|
},
|
||||||
|
Index: 9,
|
||||||
}
|
}
|
||||||
rev = [20]byte{
|
rev = [20]byte{
|
||||||
0x51, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
|
0x51, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
|
||||||
@ -68,6 +72,10 @@ var (
|
|||||||
},
|
},
|
||||||
LockTime: 5,
|
LockTime: 5,
|
||||||
}
|
}
|
||||||
|
testOutpoint = &wire.OutPoint{
|
||||||
|
Hash: key,
|
||||||
|
Index: 0,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
type MockEncryptorDecryptor struct {
|
type MockEncryptorDecryptor struct {
|
||||||
@ -132,7 +140,7 @@ func TestOpenChannelEncodeDecode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
state := OpenChannel{
|
state := OpenChannel{
|
||||||
TheirLNID: id,
|
TheirLNID: key,
|
||||||
ChanID: id,
|
ChanID: id,
|
||||||
MinFeePerKb: btcutil.Amount(5000),
|
MinFeePerKb: btcutil.Amount(5000),
|
||||||
OurCommitKey: privKey,
|
OurCommitKey: privKey,
|
||||||
@ -144,8 +152,9 @@ func TestOpenChannelEncodeDecode(t *testing.T) {
|
|||||||
OurCommitTx: testTx,
|
OurCommitTx: testTx,
|
||||||
LocalElkrem: &sender,
|
LocalElkrem: &sender,
|
||||||
RemoteElkrem: &receiver,
|
RemoteElkrem: &receiver,
|
||||||
FundingTx: testTx,
|
FundingOutpoint: testOutpoint,
|
||||||
MultiSigKey: privKey,
|
OurMultiSigKey: privKey,
|
||||||
|
TheirMultiSigKey: privKey.PubKey(),
|
||||||
FundingRedeemScript: script,
|
FundingRedeemScript: script,
|
||||||
TheirCurrentRevocation: rev,
|
TheirCurrentRevocation: rev,
|
||||||
OurDeliveryScript: script,
|
OurDeliveryScript: script,
|
||||||
@ -164,17 +173,20 @@ func TestOpenChannelEncodeDecode(t *testing.T) {
|
|||||||
t.Fatalf("unable to save and serialize channel state: %v", err)
|
t.Fatalf("unable to save and serialize channel state: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newState, err := cdb.FetchOpenChannel(id)
|
nodeID := wire.ShaHash(state.TheirLNID)
|
||||||
|
openChannels, err := cdb.FetchOpenChannels(&nodeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to fetch open channel: %v", err)
|
t.Fatalf("unable to fetch open channel: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newState := openChannels[0]
|
||||||
|
|
||||||
// The decoded channel state should be identical to what we stored
|
// The decoded channel state should be identical to what we stored
|
||||||
// above.
|
// above.
|
||||||
if !bytes.Equal(state.TheirLNID[:], newState.TheirLNID[:]) {
|
if !bytes.Equal(state.TheirLNID[:], newState.TheirLNID[:]) {
|
||||||
t.Fatalf("their id doesn't match")
|
t.Fatalf("their id doesn't match")
|
||||||
}
|
}
|
||||||
if !bytes.Equal(state.ChanID[:], newState.ChanID[:]) {
|
if !reflect.DeepEqual(state.ChanID, newState.ChanID) {
|
||||||
t.Fatalf("chan id's don't match")
|
t.Fatalf("chan id's don't match")
|
||||||
}
|
}
|
||||||
if state.MinFeePerKb != newState.MinFeePerKb {
|
if state.MinFeePerKb != newState.MinFeePerKb {
|
||||||
@ -228,19 +240,18 @@ func TestOpenChannelEncodeDecode(t *testing.T) {
|
|||||||
b1.Reset()
|
b1.Reset()
|
||||||
b2.Reset()
|
b2.Reset()
|
||||||
|
|
||||||
if err := state.FundingTx.Serialize(&b1); err != nil {
|
// TODO(roasbeef): replace with a single equal?
|
||||||
t.Fatalf("unable to serialize transaction")
|
if !reflect.DeepEqual(state.FundingOutpoint, newState.FundingOutpoint) {
|
||||||
}
|
t.Fatalf("funding outpoint doesn't match")
|
||||||
if err := newState.FundingTx.Serialize(&b2); err != nil {
|
|
||||||
t.Fatalf("unable to serialize transaction")
|
|
||||||
}
|
|
||||||
if !bytes.Equal(b1.Bytes(), b2.Bytes()) {
|
|
||||||
t.Fatalf("funding tx doesn't match")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(state.MultiSigKey.Serialize(),
|
if !bytes.Equal(state.OurMultiSigKey.Serialize(),
|
||||||
newState.MultiSigKey.Serialize()) {
|
newState.OurMultiSigKey.Serialize()) {
|
||||||
t.Fatalf("multisig key doesn't match")
|
t.Fatalf("our multisig key doesn't match")
|
||||||
|
}
|
||||||
|
if !bytes.Equal(state.TheirMultiSigKey.SerializeCompressed(),
|
||||||
|
newState.TheirMultiSigKey.SerializeCompressed()) {
|
||||||
|
t.Fatalf("their multisig key doesn't match")
|
||||||
}
|
}
|
||||||
if !bytes.Equal(state.FundingRedeemScript, newState.FundingRedeemScript) {
|
if !bytes.Equal(state.FundingRedeemScript, newState.FundingRedeemScript) {
|
||||||
t.Fatalf("redeem script doesn't match")
|
t.Fatalf("redeem script doesn't match")
|
||||||
|
@ -3,5 +3,6 @@ package channeldb
|
|||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrNoExists = fmt.Errorf("channel db has not yet been created")
|
ErrNoExists = fmt.Errorf("channel db has not yet been created")
|
||||||
|
ErrNoActiveChannels = fmt.Errorf("no active channels exist")
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user