watchtower/multi: send connection features + chain hash in Init

This commit is contained in:
Conner Fromknecht committed 2019-02-06 20:09:19 -08:00
1 parent eaea92e2cf
commit 4dbade64dd
6 files changed
+149 -67

No files matched your search

+19 -21
View File
@@ -10,6 +10,7 @@ import (
"time"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/connmgr"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcutil"
@@ -51,6 +52,9 @@ type Config struct {
// NewAddress is used to generate reward addresses, where a cut of
// successfully sent funds can be received.
NewAddress func() (btcutil.Address, error)
// ChainHash identifies the network that the server is watching.
ChainHash chainhash.Hash
}
// Server houses the state required to handle watchtower peers. It's primary job
@@ -68,7 +72,7 @@ type Server struct {
clients map[wtdb.SessionID]Peer
globalFeatures *lnwire.RawFeatureVector
localFeatures *lnwire.RawFeatureVector
connFeatures *lnwire.RawFeatureVector
wg sync.WaitGroup
quit chan struct{}
@@ -78,7 +82,7 @@ type Server struct {
// clients connecting to the listener addresses, and allows them to open
// sessions and send state updates.
func New(cfg *Config) (*Server, error) {
localFeatures := lnwire.NewRawFeatureVector(
connFeatures := lnwire.NewRawFeatureVector(
wtwire.WtSessionsOptional,
)
@@ -86,7 +90,7 @@ func New(cfg *Config) (*Server, error) {
cfg: cfg,
clients: make(map[wtdb.SessionID]Peer),
globalFeatures: lnwire.NewRawFeatureVector(),
localFeatures: localFeatures,
connFeatures: connFeatures,
quit: make(chan struct{}),
}
@@ -206,7 +210,7 @@ func (s *Server) handleClient(peer Peer) {
}
localInit := wtwire.NewInitMessage(
s.localFeatures, s.globalFeatures,
s.connFeatures, s.cfg.ChainHash,
)
err = s.sendMessage(peer, localInit)
@@ -296,25 +300,19 @@ func (s *Server) handleClient(peer Peer) {
// handleInit accepts the local and remote Init messages, and verifies that the
// client is not requesting any required features that are unknown to the tower.
func (s *Server) handleInit(localInit, remoteInit *wtwire.Init) error {
remoteLocalFeatures := lnwire.NewFeatureVector(
remoteInit.LocalFeatures, wtwire.LocalFeatures,
)
remoteGlobalFeatures := lnwire.NewFeatureVector(
remoteInit.GlobalFeatures, wtwire.GlobalFeatures,
)
unknownLocalFeatures := remoteLocalFeatures.UnknownRequiredFeatures()
if len(unknownLocalFeatures) > 0 {
err := fmt.Errorf("Peer set unknown local feature bits: %v",
unknownLocalFeatures)
return err
if localInit.ChainHash != remoteInit.ChainHash {
return fmt.Errorf("Peer chain hash unknown: %x",
remoteInit.ChainHash)
}
unknownGlobalFeatures := remoteGlobalFeatures.UnknownRequiredFeatures()
if len(unknownGlobalFeatures) > 0 {
err := fmt.Errorf("Peer set unknown global feature bits: %v",
unknownGlobalFeatures)
return err
remoteConnFeatures := lnwire.NewFeatureVector(
remoteInit.ConnFeatures, wtwire.LocalFeatures,
)
unknownLocalFeatures := remoteConnFeatures.UnknownRequiredFeatures()
if len(unknownLocalFeatures) > 0 {
return fmt.Errorf("Peer set unknown local feature bits: %v",
unknownLocalFeatures)
}
return nil
+38 -35
View File
@@ -27,6 +27,8 @@ var (
)
addrScript, _ = txscript.PayToAddrScript(addr)
testnetChainHash = *chaincfg.TestNet3Params.GenesisHash
)
// randPubKey generates a new secp keypair, and returns the public key.
@@ -59,6 +61,7 @@ func initServer(t *testing.T, db wtserver.DB,
NewAddress: func() (btcutil.Address, error) {
return addr, nil
},
ChainHash: testnetChainHash,
})
if err != nil {
t.Fatalf("unable to create server: %v", err)
@@ -91,7 +94,7 @@ func TestServerOnlyAcceptOnePeer(t *testing.T) {
// Serialize a Init message to be sent by both peers.
init := wtwire.NewInitMessage(
lnwire.NewRawFeatureVector(), lnwire.NewRawFeatureVector(),
lnwire.NewRawFeatureVector(), testnetChainHash,
)
var b bytes.Buffer
@@ -159,7 +162,7 @@ var createSessionTests = []createSessionTestCase{
name: "reject duplicate session create",
initMsg: wtwire.NewInitMessage(
lnwire.NewRawFeatureVector(),
lnwire.NewRawFeatureVector(),
testnetChainHash,
),
createMsg: &wtwire.CreateSession{
BlobType: blob.TypeDefault,
@@ -181,7 +184,7 @@ var createSessionTests = []createSessionTestCase{
name: "reject unsupported blob type",
initMsg: wtwire.NewInitMessage(
lnwire.NewRawFeatureVector(),
lnwire.NewRawFeatureVector(),
testnetChainHash,
),
createMsg: &wtwire.CreateSession{
BlobType: 0,
@@ -279,10 +282,10 @@ var stateUpdateTests = []stateUpdateTestCase{
// Valid update sequence, send seqnum == lastapplied as last update.
{
name: "perm fail after sending seqnum equal lastapplied",
initMsg: &wtwire.Init{&lnwire.Init{
LocalFeatures: lnwire.NewRawFeatureVector(),
GlobalFeatures: lnwire.NewRawFeatureVector(),
}},
initMsg: wtwire.NewInitMessage(
lnwire.NewRawFeatureVector(),
testnetChainHash,
),
createMsg: &wtwire.CreateSession{
BlobType: blob.TypeDefault,
MaxUpdates: 3,
@@ -309,10 +312,10 @@ var stateUpdateTests = []stateUpdateTestCase{
// Send update that skips next expected sequence number.
{
name: "skip sequence number",
initMsg: &wtwire.Init{&lnwire.Init{
LocalFeatures: lnwire.NewRawFeatureVector(),
GlobalFeatures: lnwire.NewRawFeatureVector(),
}},
initMsg: wtwire.NewInitMessage(
lnwire.NewRawFeatureVector(),
testnetChainHash,
),
createMsg: &wtwire.CreateSession{
BlobType: blob.TypeDefault,
MaxUpdates: 4,
@@ -333,10 +336,10 @@ var stateUpdateTests = []stateUpdateTestCase{
// Send update that reverts to older sequence number.
{
name: "revert to older seqnum",
initMsg: &wtwire.Init{&lnwire.Init{
LocalFeatures: lnwire.NewRawFeatureVector(),
GlobalFeatures: lnwire.NewRawFeatureVector(),
}},
initMsg: wtwire.NewInitMessage(
lnwire.NewRawFeatureVector(),
testnetChainHash,
),
createMsg: &wtwire.CreateSession{
BlobType: blob.TypeDefault,
MaxUpdates: 4,
@@ -361,10 +364,10 @@ var stateUpdateTests = []stateUpdateTestCase{
// Send update echoing a last applied that is lower than previous value.
{
name: "revert to older lastapplied",
initMsg: &wtwire.Init{&lnwire.Init{
LocalFeatures: lnwire.NewRawFeatureVector(),
GlobalFeatures: lnwire.NewRawFeatureVector(),
}},
initMsg: wtwire.NewInitMessage(
lnwire.NewRawFeatureVector(),
testnetChainHash,
),
createMsg: &wtwire.CreateSession{
BlobType: blob.TypeDefault,
MaxUpdates: 4,
@@ -389,10 +392,10 @@ var stateUpdateTests = []stateUpdateTestCase{
// Client echos last applied as they are received.
{
name: "resume after disconnect",
initMsg: &wtwire.Init{&lnwire.Init{
LocalFeatures: lnwire.NewRawFeatureVector(),
GlobalFeatures: lnwire.NewRawFeatureVector(),
}},
initMsg: wtwire.NewInitMessage(
lnwire.NewRawFeatureVector(),
testnetChainHash,
),
createMsg: &wtwire.CreateSession{
BlobType: blob.TypeDefault,
MaxUpdates: 4,
@@ -419,10 +422,10 @@ var stateUpdateTests = []stateUpdateTestCase{
// Client doesn't echo last applied until last message.
{
name: "resume after disconnect lagging lastapplied",
initMsg: &wtwire.Init{&lnwire.Init{
LocalFeatures: lnwire.NewRawFeatureVector(),
GlobalFeatures: lnwire.NewRawFeatureVector(),
}},
initMsg: wtwire.NewInitMessage(
lnwire.NewRawFeatureVector(),
testnetChainHash,
),
createMsg: &wtwire.CreateSession{
BlobType: blob.TypeDefault,
MaxUpdates: 4,
@@ -448,10 +451,10 @@ var stateUpdateTests = []stateUpdateTestCase{
// Send update with sequence number that exceeds MaxUpdates.
{
name: "seqnum exceed maxupdates",
initMsg: &wtwire.Init{&lnwire.Init{
LocalFeatures: lnwire.NewRawFeatureVector(),
GlobalFeatures: lnwire.NewRawFeatureVector(),
}},
initMsg: wtwire.NewInitMessage(
lnwire.NewRawFeatureVector(),
testnetChainHash,
),
createMsg: &wtwire.CreateSession{
BlobType: blob.TypeDefault,
MaxUpdates: 3,
@@ -478,10 +481,10 @@ var stateUpdateTests = []stateUpdateTestCase{
// Ensure sequence number 0 causes permanent failure.
{
name: "perm fail after seqnum 0",
initMsg: &wtwire.Init{&lnwire.Init{
LocalFeatures: lnwire.NewRawFeatureVector(),
GlobalFeatures: lnwire.NewRawFeatureVector(),
}},
initMsg: wtwire.NewInitMessage(
lnwire.NewRawFeatureVector(),
testnetChainHash,
),
createMsg: &wtwire.CreateSession{
BlobType: blob.TypeDefault,
MaxUpdates: 3,