Skip to content

Commit 06fc1fd

Browse files
authored
feat: track Handshake domain resource updates (#455)
Signed-off-by: Aurora Gaffney <[email protected]>
1 parent 797ab79 commit 06fc1fd

File tree

2 files changed

+205
-2
lines changed

2 files changed

+205
-2
lines changed

internal/indexer/handshake.go

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
package indexer
88

99
import (
10+
"encoding/base32"
1011
"fmt"
1112
"log/slog"
1213
"time"
1314

1415
"github.com/blinklabs-io/cdnsd/handshake"
1516
"github.com/blinklabs-io/cdnsd/internal/config"
1617
"github.com/blinklabs-io/cdnsd/internal/state"
18+
"github.com/miekg/dns"
1719
)
1820

1921
type handshakeState struct {
@@ -127,14 +129,164 @@ func (i *Indexer) handshakeHandleSync(block *handshake.Block) error {
127129
return err
128130
}
129131
slog.Debug("Handshake domain registration", "name", name, "resdata", c.ResourceData)
132+
records, err := handshakeResourceDataToDomainRecords(name, c.ResourceData)
133+
if err != nil {
134+
return err
135+
}
136+
if err := state.GetState().UpdateHandshakeDomain(name, records); err != nil {
137+
return err
138+
}
130139
case *handshake.UpdateCovenant:
131140
name, err := state.GetState().GetHandshakeNameByHash(c.NameHash)
132141
if err != nil {
133142
return err
134143
}
135144
slog.Debug("Handshake domain update", "name", name, "resdata", c.ResourceData)
145+
records, err := handshakeResourceDataToDomainRecords(name, c.ResourceData)
146+
if err != nil {
147+
return err
148+
}
149+
if err := state.GetState().UpdateHandshakeDomain(name, records); err != nil {
150+
return err
151+
}
136152
}
137153
}
138154
}
139155
return nil
140156
}
157+
158+
func handshakeResourceDataToDomainRecords(domainName string, resData handshake.DomainResourceData) ([]state.DomainRecord, error) {
159+
// The return may be larger than this, but it will be at least as large
160+
ret := make([]state.DomainRecord, 0, len(resData.Records))
161+
for _, record := range resData.Records {
162+
switch r := record.(type) {
163+
case *handshake.DsDomainRecord:
164+
ret = append(
165+
ret,
166+
state.DomainRecord{
167+
Lhs: dns.CanonicalName(domainName),
168+
Type: "DS",
169+
Rhs: fmt.Sprintf(
170+
"%d %d %d %x",
171+
r.KeyTag,
172+
r.Algorithm,
173+
r.DigestType,
174+
r.Digest,
175+
),
176+
},
177+
)
178+
case *handshake.NsDomainRecord:
179+
ret = append(
180+
ret,
181+
state.DomainRecord{
182+
Lhs: dns.CanonicalName(domainName),
183+
Type: "NS",
184+
Rhs: r.Name,
185+
},
186+
)
187+
case *handshake.Glue4DomainRecord:
188+
ret = append(
189+
ret,
190+
state.DomainRecord{
191+
Lhs: dns.CanonicalName(domainName),
192+
Type: "NS",
193+
Rhs: r.Name,
194+
},
195+
)
196+
ret = append(
197+
ret,
198+
state.DomainRecord{
199+
Lhs: dns.CanonicalName(r.Name),
200+
Type: "A",
201+
Rhs: r.Address.String(),
202+
},
203+
)
204+
case *handshake.Glue6DomainRecord:
205+
ret = append(
206+
ret,
207+
state.DomainRecord{
208+
Lhs: dns.CanonicalName(domainName),
209+
Type: "NS",
210+
Rhs: r.Name,
211+
},
212+
)
213+
ret = append(
214+
ret,
215+
state.DomainRecord{
216+
Lhs: dns.CanonicalName(r.Name),
217+
Type: "AAAA",
218+
Rhs: r.Address.String(),
219+
},
220+
)
221+
case *handshake.Synth4DomainRecord:
222+
ip4 := r.Address.To4()
223+
if ip4 == nil {
224+
return nil, fmt.Errorf("Synth4 record has invalid IPv4 address: %s", r.Address.String())
225+
}
226+
nsName := fmt.Sprintf(
227+
"_%s._synth.",
228+
base32.HexEncoding.EncodeToString(
229+
ip4,
230+
),
231+
)
232+
ret = append(
233+
ret,
234+
state.DomainRecord{
235+
Lhs: dns.CanonicalName(domainName),
236+
Type: "NS",
237+
Rhs: nsName,
238+
},
239+
)
240+
ret = append(
241+
ret,
242+
state.DomainRecord{
243+
Lhs: nsName,
244+
Type: "A",
245+
Rhs: r.Address.String(),
246+
},
247+
)
248+
case *handshake.Synth6DomainRecord:
249+
nsName := fmt.Sprintf(
250+
"_%s._synth.",
251+
base32.HexEncoding.EncodeToString(
252+
r.Address,
253+
),
254+
)
255+
ret = append(
256+
ret,
257+
state.DomainRecord{
258+
Lhs: dns.CanonicalName(domainName),
259+
Type: "NS",
260+
Rhs: nsName,
261+
},
262+
)
263+
ret = append(
264+
ret,
265+
state.DomainRecord{
266+
Lhs: nsName,
267+
Type: "AAAA",
268+
Rhs: r.Address.String(),
269+
},
270+
)
271+
case *handshake.TextDomainRecord:
272+
var txtVal string
273+
for _, item := range r.Items {
274+
if txtVal != "" {
275+
txtVal += " "
276+
}
277+
txtVal += `"` + string(item) + `"`
278+
}
279+
ret = append(
280+
ret,
281+
state.DomainRecord{
282+
Lhs: dns.CanonicalName(domainName),
283+
Type: "TXT",
284+
Rhs: txtVal,
285+
},
286+
)
287+
default:
288+
return nil, fmt.Errorf("unsupported record type: %T", record)
289+
}
290+
}
291+
return ret, nil
292+
}

internal/state/state.go

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ const (
2828
discoveredAddrKey = "discovered_addresses"
2929
fingerprintKey = "config_fingerprint"
3030

31-
recordKeyPrefix = "r_"
32-
domainKeyPrefix = "d_"
31+
cardanoRecordKeyPrefix = "r_"
32+
cardanoDomainKeyPrefix = "d_"
3333
handshakeNameHashKeyPrefix = "hs_name_hash_"
34+
handshakeDomainKeyPrefix = "hs_d_"
35+
handshakeRecordKeyPrefix = "hs_r_"
3436
)
3537

3638
type State struct {
@@ -221,6 +223,20 @@ func (s *State) GetDiscoveredAddresses() ([]DiscoveredAddress, error) {
221223
func (s *State) UpdateDomain(
222224
domainName string,
223225
records []DomainRecord,
226+
) error {
227+
return s.updateDomain(
228+
domainName,
229+
records,
230+
cardanoDomainKeyPrefix,
231+
cardanoRecordKeyPrefix,
232+
)
233+
}
234+
235+
func (s *State) updateDomain(
236+
domainName string,
237+
records []DomainRecord,
238+
domainKeyPrefix string,
239+
recordKeyPrefix string,
224240
) error {
225241
err := s.db.Update(func(txn *badger.Txn) error {
226242
// Add new records
@@ -290,6 +306,18 @@ func (s *State) UpdateDomain(
290306
func (s *State) LookupRecords(
291307
recordTypes []string,
292308
recordName string,
309+
) ([]DomainRecord, error) {
310+
return s.lookupRecords(
311+
recordTypes,
312+
recordName,
313+
cardanoRecordKeyPrefix,
314+
)
315+
}
316+
317+
func (s *State) lookupRecords(
318+
recordTypes []string,
319+
recordName string,
320+
recordKeyPrefix string,
293321
) ([]DomainRecord, error) {
294322
ret := []DomainRecord{}
295323
recordName = strings.Trim(recordName, `.`)
@@ -367,6 +395,29 @@ func (s *State) GetHandshakeNameByHash(nameHash []byte) (string, error) {
367395
return ret, nil
368396
}
369397

398+
func (s *State) UpdateHandshakeDomain(
399+
domainName string,
400+
records []DomainRecord,
401+
) error {
402+
return s.updateDomain(
403+
domainName,
404+
records,
405+
handshakeDomainKeyPrefix,
406+
handshakeRecordKeyPrefix,
407+
)
408+
}
409+
410+
func (s *State) LookupHandshakeRecords(
411+
recordTypes []string,
412+
recordName string,
413+
) ([]DomainRecord, error) {
414+
return s.lookupRecords(
415+
recordTypes,
416+
recordName,
417+
handshakeRecordKeyPrefix,
418+
)
419+
}
420+
370421
func GetState() *State {
371422
return globalState
372423
}

0 commit comments

Comments
 (0)