From d8f453d9dce2b032695c9f08d16190e414ca1fec Mon Sep 17 00:00:00 2001 From: MeshCollider Date: Tue, 30 Jan 2018 13:00:23 +1300 Subject: [PATCH] channeldb: remove address resolution from channeldb --- channeldb/addr.go | 103 +++++++++++++++++++++++++++++++++++++++++++ channeldb/channel.go | 12 ----- channeldb/graph.go | 72 ++---------------------------- channeldb/nodes.go | 15 ++----- 4 files changed, 110 insertions(+), 92 deletions(-) create mode 100644 channeldb/addr.go diff --git a/channeldb/addr.go b/channeldb/addr.go new file mode 100644 index 00000000..daa61a8b --- /dev/null +++ b/channeldb/addr.go @@ -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 +} diff --git a/channeldb/channel.go b/channeldb/channel.go index f93ef3b9..8e246e3e 100644 --- a/channeldb/channel.go +++ b/channeldb/channel.go @@ -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 ( @@ -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. diff --git a/channeldb/graph.go b/channeldb/graph.go index eca5f9c6..5c1ebb2b 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -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. @@ -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 } } @@ -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 diff --git a/channeldb/nodes.go b/channeldb/nodes.go index e42a15df..9274bc08 100644 --- a/channeldb/nodes.go +++ b/channeldb/nodes.go @@ -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 } } @@ -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