Skip to content

Commit

Permalink
channeldb: remove address resolution from channeldb
Browse files Browse the repository at this point in the history
  • Loading branch information
meshcollider authored and Roasbeef committed Feb 6, 2018
1 parent 945be73 commit d8f453d
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 92 deletions.
103 changes: 103 additions & 0 deletions channeldb/addr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package channeldb

import (
"io"
"net"
)

// addressType specifies the network protocol and version that should be used
// when connecting to a node at a particular address.
type addressType uint8

const (
// tcp4Addr denotes an IPv4 TCP address.
tcp4Addr addressType = 0

// tcp6Addr denotes an IPv6 TCP address.
tcp6Addr addressType = 1

// v2OnionAddr denotes a version 2 Tor onion service address.
v2OnionAddr addressType = 2

// v3OnionAddr denotes a version 3 Tor (prop224) onion service addresses.
v3OnionAddr addressType = 3
)

// deserializeAddr reads the serialized raw representation of an address and
// deserializes it into the actual address, to avoid performing address
// resolution in the database module
func deserializeAddr(r io.Reader) (net.Addr, error) {
var scratch [8]byte
var address net.Addr

if _, err := r.Read(scratch[:1]); err != nil {
return nil, err
}

// TODO(roasbeef): also add onion addrs
switch addressType(scratch[0]) {
case tcp4Addr:
addr := &net.TCPAddr{}
var ip [4]byte
if _, err := r.Read(ip[:]); err != nil {
return nil, err
}
addr.IP = (net.IP)(ip[:])
if _, err := r.Read(scratch[:2]); err != nil {
return nil, err
}
addr.Port = int(byteOrder.Uint16(scratch[:2]))
address = addr
case tcp6Addr:
addr := &net.TCPAddr{}
var ip [16]byte
if _, err := r.Read(ip[:]); err != nil {
return nil, err
}
addr.IP = (net.IP)(ip[:])
if _, err := r.Read(scratch[:2]); err != nil {
return nil, err
}
addr.Port = int(byteOrder.Uint16(scratch[:2]))
address = addr
default:
return nil, ErrUnknownAddressType
}

return address, nil
}

// serializeAddr serializes an address into a raw byte representation so it
// can be deserialized without requiring address resolution
func serializeAddr(w io.Writer, address net.Addr) error {
var scratch [16]byte

if address.Network() == "tcp" {
if address.(*net.TCPAddr).IP.To4() != nil {
scratch[0] = uint8(tcp4Addr)
if _, err := w.Write(scratch[:1]); err != nil {
return err
}
copy(scratch[:4], address.(*net.TCPAddr).IP.To4())
if _, err := w.Write(scratch[:4]); err != nil {
return err
}
} else {
scratch[0] = uint8(tcp6Addr)
if _, err := w.Write(scratch[:1]); err != nil {
return err
}
copy(scratch[:], address.(*net.TCPAddr).IP.To16())
if _, err := w.Write(scratch[:]); err != nil {
return err
}
}
byteOrder.PutUint16(scratch[:2],
uint16(address.(*net.TCPAddr).Port))
if _, err := w.Write(scratch[:2]); err != nil {
return err
}
}

return nil
}
12 changes: 0 additions & 12 deletions channeldb/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,6 @@ var (
// channel closure. This key should be accessed from within the
// sub-bucket of a target channel, identified by its channel point.
revocationLogBucket = []byte("revocation-log-key")

// resolveTCP is a resolver that is used to resolve nodes'
// publicly advertised addresses. It is set to net.ResolveTCPAddr
// initially, but the SetResolver function can be used to change this
// to a Tor-specific resolver.
resolveTCP = net.ResolveTCPAddr
)

var (
Expand Down Expand Up @@ -395,12 +389,6 @@ type OpenChannel struct {
sync.RWMutex
}

// SetResolver sets resolveTCP to a resolver other than the default
// net.ResolveTCPAddr resolver function.
func SetResolver(resolver func(string, string) (*net.TCPAddr, error)) {
resolveTCP = resolver
}

// 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.
Expand Down
72 changes: 4 additions & 68 deletions channeldb/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,6 @@ func (c *ChannelGraph) Database() *DB {
return c.db
}

// addressType specifies the network protocol and version that should be used
// when connecting to a node at a particular address.
type addressType uint8

const (
tcp4Addr addressType = 0
tcp6Addr addressType = 1
onionAddr addressType = 2
)

// ForEachChannel iterates through all the channel edges stored within the
// graph and invokes the passed callback for each edge. The callback takes two
// edges as since this is a directed graph, both the in/out edges are visited.
Expand Down Expand Up @@ -1609,31 +1599,8 @@ func putLightningNode(nodeBucket *bolt.Bucket, aliasBucket *bolt.Bucket, node *L
}

for _, address := range node.Addresses {
if address.Network() == "tcp" {
if address.(*net.TCPAddr).IP.To4() != nil {
scratch[0] = uint8(tcp4Addr)
if _, err := b.Write(scratch[:1]); err != nil {
return err
}
copy(scratch[:4], address.(*net.TCPAddr).IP.To4())
if _, err := b.Write(scratch[:4]); err != nil {
return err
}
} else {
scratch[0] = uint8(tcp6Addr)
if _, err := b.Write(scratch[:1]); err != nil {
return err
}
copy(scratch[:], address.(*net.TCPAddr).IP.To16())
if _, err := b.Write(scratch[:]); err != nil {
return err
}
}
byteOrder.PutUint16(scratch[:2],
uint16(address.(*net.TCPAddr).Port))
if _, err := b.Write(scratch[:2]); err != nil {
return err
}
if err := serializeAddr(&b, address); err != nil {
return err
}
}

Expand Down Expand Up @@ -1731,41 +1698,10 @@ func deserializeLightningNode(r io.Reader) (*LightningNode, error) {

var addresses []net.Addr
for i := 0; i < numAddresses; i++ {
var address net.Addr
if _, err := r.Read(scratch[:1]); err != nil {
address, err := deserializeAddr(r)
if err != nil {
return nil, err
}

// TODO(roasbeef): also add onion addrs
switch addressType(scratch[0]) {
case tcp4Addr:
addr := &net.TCPAddr{}
var ip [4]byte
if _, err := r.Read(ip[:]); err != nil {
return nil, err
}
addr.IP = (net.IP)(ip[:])
if _, err := r.Read(scratch[:2]); err != nil {
return nil, err
}
addr.Port = int(byteOrder.Uint16(scratch[:2]))
address = addr
case tcp6Addr:
addr := &net.TCPAddr{}
var ip [16]byte
if _, err := r.Read(ip[:]); err != nil {
return nil, err
}
addr.IP = (net.IP)(ip[:])
if _, err := r.Read(scratch[:2]); err != nil {
return nil, err
}
addr.Port = int(byteOrder.Uint16(scratch[:2]))
address = addr
default:
return nil, ErrUnknownAddressType
}

addresses = append(addresses, address)
}
node.Addresses = addresses
Expand Down
15 changes: 3 additions & 12 deletions channeldb/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,7 @@ func serializeLinkNode(w io.Writer, l *LinkNode) error {
}

for _, addr := range l.Addresses {
addrString := addr.String()
if err := wire.WriteVarString(w, 0, addrString); err != nil {
if err := serializeAddr(w, addr); err != nil {
return err
}
}
Expand Down Expand Up @@ -270,19 +269,11 @@ func deserializeLinkNode(r io.Reader) (*LinkNode, error) {

node.Addresses = make([]*net.TCPAddr, numAddrs)
for i := uint32(0); i < numAddrs; i++ {
addrString, err := wire.ReadVarString(r, 0)
addr, err := deserializeAddr(r)
if err != nil {
return nil, err
}

// We use the general resolveTCP function in case a separate
// resolver was specified in the SetResolver function. By
// default resolveTCP = net.ResolveTCPAddr.
addr, err := resolveTCP("tcp", addrString)
if err != nil {
return nil, err
}
node.Addresses[i] = addr
node.Addresses[i] = addr.(*net.TCPAddr)
}

return node, nil
Expand Down

0 comments on commit d8f453d

Please sign in to comment.