Skip to content

Commit 125325f

Browse files
ellemoutonyyforyongyu
authored andcommitted
multi: freeze graph SQL migration logic
Copy over all the code that the graph SQL migration needs to a separate folder. This will let us advance the main graph SQL CRUD code without worrying about changing the sql migration code. It will also let us change the SQL queries without changing the migration. In this commit, only the migration logic is "frozen" but in an upcoming commit, the sqlc queries & models will be frozen too.
1 parent 07d0f08 commit 125325f

17 files changed

+5136
-6
lines changed

config_builder.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
"github.com/lightningnetwork/lnd/fn/v2"
3737
"github.com/lightningnetwork/lnd/funding"
3838
graphdb "github.com/lightningnetwork/lnd/graph/db"
39+
graphdbmig1 "github.com/lightningnetwork/lnd/graph/db/migration1"
3940
"github.com/lightningnetwork/lnd/htlcswitch"
4041
"github.com/lightningnetwork/lnd/invoices"
4142
"github.com/lightningnetwork/lnd/keychain"
@@ -1134,12 +1135,12 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
11341135
}
11351136

11361137
graphMig := func(tx *sqlc.Queries) error {
1137-
cfg := &graphdb.SQLStoreConfig{
1138+
cfg := &graphdbmig1.SQLStoreConfig{
11381139
//nolint:ll
11391140
ChainHash: *d.cfg.ActiveNetParams.GenesisHash,
11401141
QueryCfg: queryCfg,
11411142
}
1142-
err := graphdb.MigrateGraphToSQL(
1143+
err := graphdbmig1.MigrateGraphToSQL(
11431144
ctx, cfg, dbs.ChanStateDB.Backend, tx,
11441145
)
11451146
if err != nil {

graph/db/migration1/addr.go

Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
package migration1
2+
3+
import (
4+
"encoding/binary"
5+
"errors"
6+
"fmt"
7+
"io"
8+
"net"
9+
10+
"github.com/lightningnetwork/lnd/lnwire"
11+
"github.com/lightningnetwork/lnd/tor"
12+
)
13+
14+
// addressType specifies the network protocol and version that should be used
15+
// when connecting to a node at a particular address.
16+
type addressType uint8
17+
18+
const (
19+
// tcp4Addr denotes an IPv4 TCP address.
20+
tcp4Addr addressType = 0
21+
22+
// tcp6Addr denotes an IPv6 TCP address.
23+
tcp6Addr addressType = 1
24+
25+
// v2OnionAddr denotes a version 2 Tor onion service address.
26+
v2OnionAddr addressType = 2
27+
28+
// v3OnionAddr denotes a version 3 Tor (prop224) onion service address.
29+
v3OnionAddr addressType = 3
30+
31+
// opaqueAddrs denotes an address (or a set of addresses) that LND was
32+
// not able to parse since LND is not yet aware of the address type.
33+
opaqueAddrs addressType = 4
34+
35+
// dnsAddr denotes a DNS address type.
36+
dnsAddr addressType = 5
37+
)
38+
39+
// encodeDNSAddr encodes a DNS address.
40+
func encodeDNSAddr(w io.Writer, addr *lnwire.DNSAddress) error {
41+
if _, err := w.Write([]byte{byte(dnsAddr)}); err != nil {
42+
return err
43+
}
44+
45+
// Write the length of the hostname.
46+
hostLen := len(addr.Hostname)
47+
if _, err := w.Write([]byte{byte(hostLen)}); err != nil {
48+
return err
49+
}
50+
51+
if _, err := w.Write([]byte(addr.Hostname)); err != nil {
52+
return err
53+
}
54+
55+
var port [2]byte
56+
byteOrder.PutUint16(port[:], addr.Port)
57+
if _, err := w.Write(port[:]); err != nil {
58+
return err
59+
}
60+
61+
return nil
62+
}
63+
64+
// encodeTCPAddr serializes a TCP address into its compact raw bytes
65+
// representation.
66+
func encodeTCPAddr(w io.Writer, addr *net.TCPAddr) error {
67+
var (
68+
addrType byte
69+
ip []byte
70+
)
71+
72+
if addr.IP.To4() != nil {
73+
addrType = byte(tcp4Addr)
74+
ip = addr.IP.To4()
75+
} else {
76+
addrType = byte(tcp6Addr)
77+
ip = addr.IP.To16()
78+
}
79+
80+
if ip == nil {
81+
return fmt.Errorf("unable to encode IP %v", addr.IP)
82+
}
83+
84+
if _, err := w.Write([]byte{addrType}); err != nil {
85+
return err
86+
}
87+
88+
if _, err := w.Write(ip); err != nil {
89+
return err
90+
}
91+
92+
var port [2]byte
93+
byteOrder.PutUint16(port[:], uint16(addr.Port))
94+
if _, err := w.Write(port[:]); err != nil {
95+
return err
96+
}
97+
98+
return nil
99+
}
100+
101+
// encodeOnionAddr serializes an onion address into its compact raw bytes
102+
// representation.
103+
func encodeOnionAddr(w io.Writer, addr *tor.OnionAddr) error {
104+
var suffixIndex int
105+
hostLen := len(addr.OnionService)
106+
switch hostLen {
107+
case tor.V2Len:
108+
if _, err := w.Write([]byte{byte(v2OnionAddr)}); err != nil {
109+
return err
110+
}
111+
suffixIndex = tor.V2Len - tor.OnionSuffixLen
112+
case tor.V3Len:
113+
if _, err := w.Write([]byte{byte(v3OnionAddr)}); err != nil {
114+
return err
115+
}
116+
suffixIndex = tor.V3Len - tor.OnionSuffixLen
117+
default:
118+
return errors.New("unknown onion service length")
119+
}
120+
121+
suffix := addr.OnionService[suffixIndex:]
122+
if suffix != tor.OnionSuffix {
123+
return fmt.Errorf("invalid suffix \"%v\"", suffix)
124+
}
125+
126+
host, err := tor.Base32Encoding.DecodeString(
127+
addr.OnionService[:suffixIndex],
128+
)
129+
if err != nil {
130+
return err
131+
}
132+
133+
// Sanity check the decoded length.
134+
switch {
135+
case hostLen == tor.V2Len && len(host) != tor.V2DecodedLen:
136+
return fmt.Errorf("onion service %v decoded to invalid host %x",
137+
addr.OnionService, host)
138+
139+
case hostLen == tor.V3Len && len(host) != tor.V3DecodedLen:
140+
return fmt.Errorf("onion service %v decoded to invalid host %x",
141+
addr.OnionService, host)
142+
}
143+
144+
if _, err := w.Write(host); err != nil {
145+
return err
146+
}
147+
148+
var port [2]byte
149+
byteOrder.PutUint16(port[:], uint16(addr.Port))
150+
if _, err := w.Write(port[:]); err != nil {
151+
return err
152+
}
153+
154+
return nil
155+
}
156+
157+
// encodeOpaqueAddrs serializes the lnwire.OpaqueAddrs type to a raw set of
158+
// bytes that we will persist.
159+
func encodeOpaqueAddrs(w io.Writer, addr *lnwire.OpaqueAddrs) error {
160+
// Write the type byte.
161+
if _, err := w.Write([]byte{byte(opaqueAddrs)}); err != nil {
162+
return err
163+
}
164+
165+
// Write the length of the payload.
166+
var l [2]byte
167+
binary.BigEndian.PutUint16(l[:], uint16(len(addr.Payload)))
168+
if _, err := w.Write(l[:]); err != nil {
169+
return err
170+
}
171+
172+
// Write the payload.
173+
_, err := w.Write(addr.Payload)
174+
175+
return err
176+
}
177+
178+
// DeserializeAddr reads the serialized raw representation of an address and
179+
// deserializes it into the actual address. This allows us to avoid address
180+
// resolution within the channeldb package.
181+
func DeserializeAddr(r io.Reader) (net.Addr, error) {
182+
var addrType [1]byte
183+
if _, err := r.Read(addrType[:]); err != nil {
184+
return nil, err
185+
}
186+
187+
var address net.Addr
188+
switch addressType(addrType[0]) {
189+
case tcp4Addr:
190+
var ip [4]byte
191+
if _, err := r.Read(ip[:]); err != nil {
192+
return nil, err
193+
}
194+
195+
var port [2]byte
196+
if _, err := r.Read(port[:]); err != nil {
197+
return nil, err
198+
}
199+
200+
address = &net.TCPAddr{
201+
IP: net.IP(ip[:]),
202+
Port: int(binary.BigEndian.Uint16(port[:])),
203+
}
204+
205+
case tcp6Addr:
206+
var ip [16]byte
207+
if _, err := r.Read(ip[:]); err != nil {
208+
return nil, err
209+
}
210+
211+
var port [2]byte
212+
if _, err := r.Read(port[:]); err != nil {
213+
return nil, err
214+
}
215+
216+
address = &net.TCPAddr{
217+
IP: net.IP(ip[:]),
218+
Port: int(binary.BigEndian.Uint16(port[:])),
219+
}
220+
221+
case v2OnionAddr:
222+
var h [tor.V2DecodedLen]byte
223+
if _, err := r.Read(h[:]); err != nil {
224+
return nil, err
225+
}
226+
227+
var p [2]byte
228+
if _, err := r.Read(p[:]); err != nil {
229+
return nil, err
230+
}
231+
232+
onionService := tor.Base32Encoding.EncodeToString(h[:])
233+
onionService += tor.OnionSuffix
234+
port := int(binary.BigEndian.Uint16(p[:]))
235+
236+
address = &tor.OnionAddr{
237+
OnionService: onionService,
238+
Port: port,
239+
}
240+
241+
case v3OnionAddr:
242+
var h [tor.V3DecodedLen]byte
243+
if _, err := r.Read(h[:]); err != nil {
244+
return nil, err
245+
}
246+
247+
var p [2]byte
248+
if _, err := r.Read(p[:]); err != nil {
249+
return nil, err
250+
}
251+
252+
onionService := tor.Base32Encoding.EncodeToString(h[:])
253+
onionService += tor.OnionSuffix
254+
port := int(binary.BigEndian.Uint16(p[:]))
255+
256+
address = &tor.OnionAddr{
257+
OnionService: onionService,
258+
Port: port,
259+
}
260+
261+
case dnsAddr:
262+
// Read the length of the hostname.
263+
var hostLen [1]byte
264+
if _, err := r.Read(hostLen[:]); err != nil {
265+
return nil, err
266+
}
267+
268+
// Read the hostname.
269+
hostname := make([]byte, hostLen[0])
270+
if _, err := r.Read(hostname); err != nil {
271+
return nil, err
272+
}
273+
274+
// Read the port.
275+
var port [2]byte
276+
if _, err := r.Read(port[:]); err != nil {
277+
return nil, err
278+
}
279+
280+
address = &lnwire.DNSAddress{
281+
Hostname: string(hostname),
282+
Port: binary.BigEndian.Uint16(port[:]),
283+
}
284+
285+
case opaqueAddrs:
286+
// Read the length of the payload.
287+
var l [2]byte
288+
if _, err := r.Read(l[:]); err != nil {
289+
return nil, err
290+
}
291+
292+
// Read the payload.
293+
payload := make([]byte, binary.BigEndian.Uint16(l[:]))
294+
if _, err := r.Read(payload); err != nil {
295+
return nil, err
296+
}
297+
298+
address = &lnwire.OpaqueAddrs{
299+
Payload: payload,
300+
}
301+
302+
default:
303+
return nil, ErrUnknownAddressType
304+
}
305+
306+
return address, nil
307+
}
308+
309+
// SerializeAddr serializes an address into its raw bytes representation so that
310+
// it can be deserialized without requiring address resolution.
311+
func SerializeAddr(w io.Writer, address net.Addr) error {
312+
switch addr := address.(type) {
313+
case *net.TCPAddr:
314+
return encodeTCPAddr(w, addr)
315+
case *tor.OnionAddr:
316+
return encodeOnionAddr(w, addr)
317+
case *lnwire.OpaqueAddrs:
318+
return encodeOpaqueAddrs(w, addr)
319+
case *lnwire.DNSAddress:
320+
return encodeDNSAddr(w, addr)
321+
default:
322+
return ErrUnknownAddressType
323+
}
324+
}

0 commit comments

Comments
 (0)