@ -1,4 +1,4 @@
package lnwallet
package channeldb
import (
"bytes"
@ -7,39 +7,96 @@ import (
"io"
"time"
"li.lan/labs/plasma/shachain"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/btcsuite/btcwallet/waddrmgr"
"github.com/btcsuite/btcwallet/walletdb"
"li.lan/labs/plasma/shachain"
)
var (
// Namespace bucket keys.
lightningNamespaceKey = [ ] byte ( "ln-wallet" )
waddrmgrNamespaceKey = [ ] byte ( "waddrmgr" )
wtxmgrNamespaceKey = [ ] byte ( "wtxmgr" )
openChannelBucket = [ ] byte ( "o" )
closedChannelBucket = [ ] byte ( "c" )
activeChanKey = [ ] byte ( "a" )
endian = binary . BigEndian
// TODO(roasbeef): replace w/ tesnet-L also revisit dependancy...
ActiveNetParams = & chaincfg . TestNet3Params
)
// ChannelDB ...
// TODO(roasbeef): CHECKSUMS, REDUNDANCY, etc etc.
type ChannelDB struct {
// TODO(roasbeef): caching, etc?
addrmgr * waddrmgr . Manager
// Payment ...
type Payment struct {
// r [32]byte
// path *Route
}
namespace walletdb . Namespace
// ClosedChannel...
type ClosedChannel struct {
}
// OpenChannel...
// TODO(roasbeef): store only the essentials? optimize space...
// TODO(roasbeef): switch to "column store"
type OpenChannel 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 // TODO(roasbeef): store hash instead?
TheirCommitSig [ ] byte // TODO(roasbeef): fixed length?, same w/ redeem
// The final funding transaction. Kept wallet-related records.
FundingTx * wire . MsgTx
MultiSigKey * btcec . PrivateKey
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
}
// PutOpenChannel...
func ( c * ChannelDB ) PutOpenChannel ( channel * OpenChannelState ) error {
func ( c * DB ) PutOpenChannel ( channel * OpenChannel ) error {
return c . namespace . Update ( func ( tx walletdb . Tx ) error {
// Get the bucket dedicated to storing the meta-data for open
// channels.
@ -49,16 +106,16 @@ func (c *ChannelDB) PutOpenChannel(channel *OpenChannelState) error {
return err
}
return dbP utOpenChannel( openChanBucket , channel , c . addrmgr )
return p utOpenChannel( openChanBucket , channel , c . addrmgr )
} )
}
// GetOpenChannel...
// TODO(roasbeef): assumes only 1 active channel per-node
func ( c * Channel DB) FetchOpenChannel ( nodeID [ 32 ] byte ) ( * OpenChannelState , error ) {
var channel * OpenChannelState
func ( c * DB ) FetchOpenChannel ( nodeID [ 32 ] byte ) ( * OpenChannel , error ) {
var channel * OpenChannel
dbE rr := c . namespace . View ( func ( tx walletdb . Tx ) error {
e rr := c . namespace . View ( func ( tx walletdb . Tx ) error {
// Get the bucket dedicated to storing the meta-data for open
// channels.
rootBucket := tx . RootBucket ( )
@ -67,7 +124,8 @@ func (c *ChannelDB) FetchOpenChannel(nodeID [32]byte) (*OpenChannelState, error)
return fmt . Errorf ( "open channel bucket does not exist" )
}
oChannel , err := dbGetOpenChannel ( openChanBucket , nodeID , c . addrmgr )
oChannel , err := fetchOpenChannel ( openChanBucket , nodeID ,
c . addrmgr )
if err != nil {
return err
}
@ -75,11 +133,11 @@ func (c *ChannelDB) FetchOpenChannel(nodeID [32]byte) (*OpenChannelState, error)
return nil
} )
return channel , dbE rr
return channel , e rr
}
// dbP utChannel...
func dbP utOpenChannel( activeChanBucket walletdb . Bucket , channel * OpenChannelState ,
// p utChannel...
func p utOpenChannel( activeChanBucket walletdb . Bucket , channel * OpenChannel ,
addrmgr * waddrmgr . Manager ) error {
// Generate a serialized version of the open channel. The addrmgr is
@ -99,9 +157,9 @@ func dbPutOpenChannel(activeChanBucket walletdb.Bucket, channel *OpenChannelStat
return nodeBucket . Put ( activeChanKey , b . Bytes ( ) )
}
// dbPutChannel...
func dbGet OpenChannel( bucket walletdb . Bucket , nodeID [ 32 ] byte ,
addrmgr * waddrmgr . Manager ) ( * OpenChannelState , error ) {
// fetchOpenChannel
func fetch OpenChannel( bucket walletdb . Bucket , nodeID [ 32 ] byte ,
addrmgr * waddrmgr . Manager ) ( * OpenChannel , error ) {
// Grab the bucket dedicated to storing data related to this particular
// node.
@ -118,7 +176,7 @@ func dbGetOpenChannel(bucket walletdb.Bucket, nodeID [32]byte,
// Decode the serialized channel state, using the addrmgr to decrypt
// sensitive information.
channel := & OpenChannelState { }
channel := & OpenChannel { }
reader := bytes . NewReader ( serializedChannel )
if err := channel . Decode ( reader , addrmgr ) ; err != nil {
return nil , err
@ -127,76 +185,9 @@ func dbGetOpenChannel(bucket walletdb.Bucket, nodeID [32]byte,
return channel , nil
}
// NewChannelDB...
// TODO(roasbeef): re-visit this dependancy...
func NewChannelDB ( addrmgr * waddrmgr . Manager , namespace walletdb . Namespace ) * ChannelDB {
// TODO(roasbeef): create buckets if not created?
return & ChannelDB { addrmgr , namespace }
}
// OpenChannelState...
// TODO(roasbeef): store only the essentials? optimize space...
// TODO(roasbeef): switch to "column store"
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 // TODO(roasbeef): store hash instead?
TheirCommitSig [ ] byte // TODO(roasbeef): fixed length?, same w/ redeem
// The final funding transaction. Kept wallet-related records.
FundingTx * wire . MsgTx
MultiSigKey * btcec . PrivateKey
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
}
// Encode...
// TODO(roasbeef): checksum
func ( o * OpenChannelState ) Encode ( b io . Writer , addrManager * waddrmgr . Manager ) error {
func ( o * OpenChannel ) Encode ( b io . Writer , addrManager * waddrmgr . Manager ) error {
if _ , err := b . Write ( o . TheirLNID [ : ] ) ; err != nil {
return err
}
@ -289,7 +280,7 @@ func (o *OpenChannelState) Encode(b io.Writer, addrManager *waddrmgr.Manager) er
}
// Decode...
func ( o * OpenChannelState ) Decode ( b io . Reader , addrManager * waddrmgr . Manager ) error {
func ( o * OpenChannel ) Decode ( b io . Reader , addrManager * waddrmgr . Manager ) error {
var scratch [ 8 ] byte
if _ , err := b . Read ( o . TheirLNID [ : ] ) ; err != nil {