2015-12-26 09:09:17 +03:00
|
|
|
package main
|
2016-01-14 08:41:46 +03:00
|
|
|
|
|
|
|
import (
|
2016-01-17 06:07:44 +03:00
|
|
|
"encoding/hex"
|
2016-01-14 08:41:46 +03:00
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"sync"
|
|
|
|
"sync/atomic"
|
|
|
|
|
2016-01-17 06:07:44 +03:00
|
|
|
"github.com/btcsuite/btcd/btcec"
|
|
|
|
"github.com/lightningnetwork/lnd/lndc"
|
2016-01-16 21:38:48 +03:00
|
|
|
"github.com/lightningnetwork/lnd/lnwallet"
|
2016-01-14 08:41:46 +03:00
|
|
|
|
|
|
|
"github.com/btcsuite/btcd/chaincfg"
|
2016-01-17 06:07:44 +03:00
|
|
|
"github.com/btcsuite/btcwallet/waddrmgr"
|
2016-01-14 08:41:46 +03:00
|
|
|
"github.com/btcsuite/btcwallet/walletdb"
|
|
|
|
)
|
|
|
|
|
|
|
|
// server...
|
|
|
|
type server struct {
|
|
|
|
started int32 // atomic
|
|
|
|
shutdown int32 // atomic
|
|
|
|
|
2016-01-17 06:07:44 +03:00
|
|
|
longTermPriv *btcec.PrivateKey
|
|
|
|
bitcoinNet *chaincfg.Params
|
|
|
|
|
|
|
|
listeners []net.Listener
|
|
|
|
peers map[int32]*peer
|
2016-01-14 08:41:46 +03:00
|
|
|
|
|
|
|
rpcServer *rpcServer
|
|
|
|
lnwallet *lnwallet.LightningWallet
|
2016-01-17 06:07:44 +03:00
|
|
|
db walletdb.DB
|
2016-01-14 08:41:46 +03:00
|
|
|
|
|
|
|
newPeers chan *peer
|
|
|
|
donePeers chan *peer
|
2016-01-17 06:07:44 +03:00
|
|
|
queries chan interface{}
|
2016-01-14 08:41:46 +03:00
|
|
|
|
|
|
|
wg sync.WaitGroup
|
|
|
|
quit chan struct{}
|
|
|
|
}
|
|
|
|
|
2016-01-17 06:07:44 +03:00
|
|
|
// newServer...
|
|
|
|
func newServer(listenAddrs []string, bitcoinNet *chaincfg.Params,
|
|
|
|
wallet *lnwallet.LightningWallet) (*server, error) {
|
|
|
|
privKey, err := getIdentityPrivKey(wallet)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
listeners := make([]net.Listener, len(listenAddrs))
|
|
|
|
for i, addr := range listenAddrs {
|
|
|
|
listeners[i], err = lndc.NewListener(privKey, addr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
s := &server{
|
|
|
|
longTermPriv: privKey,
|
|
|
|
listeners: listeners,
|
|
|
|
peers: make(map[int32]*peer),
|
|
|
|
newPeers: make(chan *peer, 100),
|
|
|
|
donePeers: make(chan *peer, 100),
|
|
|
|
lnwallet: wallet,
|
|
|
|
queries: make(chan interface{}),
|
|
|
|
quit: make(chan struct{}),
|
|
|
|
}
|
|
|
|
|
|
|
|
s.rpcServer = newRpcServer(s)
|
|
|
|
|
|
|
|
return s, nil
|
|
|
|
}
|
|
|
|
|
2016-01-14 08:41:46 +03:00
|
|
|
// addPeer...
|
|
|
|
func (s *server) addPeer(p *peer) {
|
|
|
|
}
|
|
|
|
|
|
|
|
// removePeer...
|
|
|
|
func (s *server) removePeer(p *peer) {
|
|
|
|
}
|
|
|
|
|
|
|
|
// peerManager...
|
|
|
|
func (s *server) peerManager() {
|
|
|
|
out:
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
// New peers.
|
|
|
|
case p := <-s.newPeers:
|
|
|
|
s.addPeer(p)
|
|
|
|
// Finished peers.
|
|
|
|
case p := <-s.donePeers:
|
|
|
|
s.removePeer(p)
|
|
|
|
case <-s.quit:
|
|
|
|
break out
|
|
|
|
}
|
|
|
|
}
|
|
|
|
s.wg.Done()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *server) queryHandler() {
|
|
|
|
out:
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
// TODO(roasbeef): meta-rpc-stuff
|
|
|
|
case <-s.quit:
|
|
|
|
break out
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
s.wg.Done()
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddPeer...
|
|
|
|
func (s *server) AddPeer(p *peer) {
|
|
|
|
s.newPeers <- p
|
|
|
|
}
|
|
|
|
|
|
|
|
// listener...
|
|
|
|
func (s *server) listener(l net.Listener) {
|
|
|
|
for atomic.LoadInt32(&s.shutdown) == 0 {
|
|
|
|
conn, err := l.Accept()
|
|
|
|
if err != nil {
|
|
|
|
// TODO(roasbeef): log
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// TODO(roasbeef): create new peer, start it's goroutines
|
|
|
|
fmt.Println(conn)
|
|
|
|
}
|
|
|
|
|
|
|
|
s.wg.Done()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start...
|
|
|
|
func (s *server) Start() {
|
|
|
|
// Already running?
|
|
|
|
if atomic.AddInt32(&s.started, 1) != 1 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start all the listeners.
|
|
|
|
for _, l := range s.listeners {
|
|
|
|
s.wg.Add(1)
|
|
|
|
go s.listener(l)
|
|
|
|
}
|
|
|
|
|
|
|
|
s.wg.Add(1)
|
|
|
|
go s.peerManager()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop...
|
|
|
|
func (s *server) Stop() error {
|
|
|
|
// Bail if we're already shutting down.
|
|
|
|
if atomic.AddInt32(&s.shutdown, 1) != 1 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop all the listeners.
|
|
|
|
for _, listener := range s.listeners {
|
|
|
|
if err := listener.Close(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
s.rpcServer.Stop()
|
|
|
|
s.lnwallet.Stop()
|
|
|
|
|
|
|
|
// Signal all the lingering goroutines to quit.
|
|
|
|
close(s.quit)
|
|
|
|
return nil
|
|
|
|
}
|
2016-01-17 06:05:13 +03:00
|
|
|
|
|
|
|
// getIdentityPrivKey gets the identity private key out of the wallet DB.
|
|
|
|
func getIdentityPrivKey(l *lnwallet.LightningWallet) (*btcec.PrivateKey, error) {
|
|
|
|
adr, err := l.ChannelDB.GetIdAdr()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
fmt.Printf("got ID address: %s\n", adr.String())
|
|
|
|
adr2, err := l.Manager.Address(adr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
fmt.Println("pubkey: %v", hex.EncodeToString(adr2.(waddrmgr.ManagedPubKeyAddress).PubKey().SerializeCompressed()))
|
|
|
|
priv, err := adr2.(waddrmgr.ManagedPubKeyAddress).PrivKey()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return priv, nil
|
|
|
|
}
|