Skip to content

feat: asset verification #115

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module github.com/blinklabs-io/cdnsd
go 1.20

require (
github.com/blinklabs-io/cardano-models v0.2.0
github.com/blinklabs-io/gouroboros v0.69.5
github.com/blinklabs-io/cardano-models v0.3.0
github.com/blinklabs-io/gouroboros v0.70.0
github.com/blinklabs-io/snek v0.17.1
github.com/dgraph-io/badger/v4 v4.2.0
github.com/kelseyhightower/envconfig v1.4.0
Expand All @@ -18,6 +18,10 @@ require (
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/fxamacker/cbor/v2 v2.5.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.17.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.0.0 // indirect
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect
Expand All @@ -26,6 +30,7 @@ require (
github.com/google/flatbuffers v1.12.1 // indirect
github.com/jinzhu/copier v0.4.0 // indirect
github.com/klauspost/compress v1.12.3 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opencensus.io v0.22.5 // indirect
Expand All @@ -34,6 +39,7 @@ require (
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.17.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)
28 changes: 24 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/blinklabs-io/cardano-models v0.2.0 h1:fQ2vkvMLFgQodtFpYE73i+6+eNN5vaIB3GBIys8FsyI=
github.com/blinklabs-io/cardano-models v0.2.0/go.mod h1:iH8IqSca4WzFQIAT3Ssd3TviILfoCgaJQ8mc3JrIvwE=
github.com/blinklabs-io/gouroboros v0.69.5 h1:oFTObwPchrzZAunNA/+Y6g5NwMZQhA1Zj+iZGzX4TsU=
github.com/blinklabs-io/gouroboros v0.69.5/go.mod h1:ecxtryJb+vIeVizQl4nYJr0tVdyIgOTze7R9xeGqFu4=
github.com/blinklabs-io/cardano-models v0.3.0 h1:Xc7H1l4i96Vaf5bBKXrOl1ctL0vyT/bJ9+OrZUqD6E4=
github.com/blinklabs-io/cardano-models v0.3.0/go.mod h1:mahC1oL4zVM5TCqZzqZ9I2GWAcEfzhJ3tYBpjwBWVI4=
github.com/blinklabs-io/gouroboros v0.70.0 h1:/Jlo1G2c7rQDjijSXNti4v+J34QSkQwS57Vso6STqBo=
github.com/blinklabs-io/gouroboros v0.70.0/go.mod h1:ecxtryJb+vIeVizQl4nYJr0tVdyIgOTze7R9xeGqFu4=
github.com/blinklabs-io/snek v0.17.1 h1:3u5eBTWF9tHQSNnHtHs7AQVSdX99xtqiPS5Hk7EU1qE=
github.com/blinklabs-io/snek v0.17.1/go.mod h1:6XJ2eDcU4n5V6TgpLDod+YD7pM43JOXcCiNOrDhdtKY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
Expand All @@ -23,6 +23,15 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.17.0 h1:SmVVlfAOtlZncTxRuinDPomC2DkXJ4E5T9gDA0AIH74=
github.com/go-playground/validator/v10 v10.17.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
Expand Down Expand Up @@ -53,14 +62,21 @@ github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/Vq
github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
Expand Down Expand Up @@ -114,6 +130,8 @@ golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
Expand Down Expand Up @@ -143,5 +161,7 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
62 changes: 36 additions & 26 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,14 @@ import (
"gopkg.in/yaml.v2"
)

// Per-network script address for Handshake
var networkScriptAddresses = map[string]string{
"preprod": "addr_test1wpf6lxntd3dztphew0m5dagrs7ptjcg9g6vgjyazt7mw44gdnwq0h",
}

// Per-network intercept points for starting the chain-sync
// We start the sync somewhere near where we expect the first data to appear to save time
// during the initial sync
var networkInterceptPoints = map[string]struct {
Hash string
Slot uint64
}{
"preprod": {
Hash: "a35a0d216e00c64c257e41089138f4d22be721281d73f2ab8ef61ca8863d04a0",
Slot: 34255089,
},
}

type Config struct {
Logging LoggingConfig `yaml:"logging"`
Metrics MetricsConfig `yaml:"metrics"`
Dns DnsConfig `yaml:"dns"`
Debug DebugConfig `yaml:"debug"`
Indexer IndexerConfig `yaml:"indexer"`
State StateConfig `yaml:"state"`
Profile string `yaml:"profile" envconfig:"PROFILE"`
}

type LoggingConfig struct {
Expand Down Expand Up @@ -72,6 +55,9 @@ type IndexerConfig struct {
ScriptAddress string `yaml:"scriptAddress" envconfig:"INDEXER_SCRIPT_ADDRESS"`
InterceptHash string `yaml:"interceptHash" envconfig:"INDEXER_INTERCEPT_HASH"`
InterceptSlot uint64 `yaml:"interceptSlot" envconfig:"INDEXER_INTERCEPT_SLOT"`
Tld string `yaml:"tld" envconfig:"INDEXER_TLD"`
PolicyId string `yaml:"policyId" envconfig:"INDEXER_POLICY_ID"`
Verify bool `yaml:"verify" envconfig:"INDEXER_VERIFY"`
}

type StateConfig struct {
Expand Down Expand Up @@ -105,10 +91,12 @@ var globalConfig = &Config{
},
Indexer: IndexerConfig{
Network: "preprod",
Verify: true,
},
State: StateConfig{
Directory: "./.state",
},
Profile: "cardano-preprod-testing",
}

func Load(configFile string) (*Config, error) {
Expand All @@ -130,19 +118,41 @@ func Load(configFile string) (*Config, error) {
if err != nil {
return nil, fmt.Errorf("error processing environment: %s", err)
}
// Provide default script address for named network
// Check profile
profile, ok := Profiles[globalConfig.Profile]
if !ok {
return nil, fmt.Errorf("unknown profile: %s", globalConfig.Profile)
}
// Provide default network
if globalConfig.Indexer.Network != "" {
if profile.Network != "" {
globalConfig.Indexer.Network = profile.Network
} else {
return nil, fmt.Errorf("no built-in network name for specified profile, please provide one")
}
}
// Provide default script address from profile
if globalConfig.Indexer.ScriptAddress == "" {
if scriptAddress, ok := networkScriptAddresses[globalConfig.Indexer.Network]; ok {
globalConfig.Indexer.ScriptAddress = scriptAddress
if profile.ScriptAddress != "" {
globalConfig.Indexer.ScriptAddress = profile.ScriptAddress
} else {
return nil, fmt.Errorf("no built-in script address for specified network, please provide one")
return nil, fmt.Errorf("no built-in script address for specified profile, please provide one")
}
}
// Provide default intercept point for named network
// Provide default intercept point from profile
if globalConfig.Indexer.InterceptSlot == 0 || globalConfig.Indexer.InterceptHash == "" {
if interceptPoint, ok := networkInterceptPoints[globalConfig.Indexer.Network]; ok {
globalConfig.Indexer.InterceptHash = interceptPoint.Hash
globalConfig.Indexer.InterceptSlot = interceptPoint.Slot
if profile.InterceptHash != "" && profile.InterceptSlot > 0 {
globalConfig.Indexer.InterceptHash = profile.InterceptHash
globalConfig.Indexer.InterceptSlot = profile.InterceptSlot
}
}
// Provide default TLD and Policy ID from profile
if globalConfig.Indexer.Tld == "" || globalConfig.Indexer.PolicyId == "" {
if profile.Tld != "" && profile.PolicyId != "" {
globalConfig.Indexer.Tld = profile.Tld
globalConfig.Indexer.PolicyId = profile.PolicyId
} else {
return nil, fmt.Errorf("no built-in TLD and/or policy ID for specified profile, please provide one")
}
}
return globalConfig, nil
Expand Down
29 changes: 29 additions & 0 deletions internal/config/profile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2023 Blink Labs Software
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

package config

type Profile struct {
Network string // Cardano network name
Tld string // Top-level domain
PolicyId string // Verification asset policy ID
ScriptAddress string // Address to follow
InterceptSlot uint64 // Chain-sync initial intercept slot
InterceptHash string // Chain-sync initial intercept hash
}

var Profiles = map[string]Profile{
// This (default) profile corresponds to the values specified in:
// https://github.com/blinklabs-io/cardano-dns/blob/main/README.md
"cardano-preprod-testing": Profile{
Network: "preprod",
Tld: "cardano",
PolicyId: "6af60c2a7a06551ef09b3810a41d086b26ca26f926d22e462103194d",
ScriptAddress: "addr_test1vr75xezmpxastymx985l3gamuxrwqdwcfrcnjlygs55aynsqu3edq",
InterceptSlot: 50844079,
InterceptHash: "81325118471fddb00a20327572b371aee7cce13b846a18500d011b9cefd2a34c",
},
}
74 changes: 70 additions & 4 deletions internal/indexer/indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ func (i *Indexer) Start() error {
}

func (i *Indexer) handleEvent(evt event.Event) error {
cfg := config.GetConfig()
logger := logging.GetLogger()
eventTx := evt.Payload.(input_chainsync.TransactionEvent)
eventCtx := evt.Context.(input_chainsync.TransactionContext)
Expand All @@ -169,17 +170,82 @@ func (i *Indexer) handleEvent(evt event.Event) error {
// Stop processing TX output if we can't parse the datum
continue
}
domainName := string(dnsDomain.Origin)
// Convert to canonical form for consistency
domainName = dns.CanonicalName(domainName)
origin := string(dnsDomain.Origin)
// Convert origin to canonical form for consistency
// This mostly means adding a trailing period if it doesn't have one
domainName := dns.CanonicalName(origin)
// We want an empty value for the TLD root for convenience
if domainName == `.` {
domainName = ``
}
// Append TLD
domainName = dns.CanonicalName(
domainName + cfg.Indexer.Tld,
)
if cfg.Indexer.Verify {
// Look for asset matching domain origin and TLD policy ID
if txOutput.Assets() == nil {
logger.Warnf(
"ignoring datum for domain %q with no matching asset",
domainName,
)
continue
}
foundAsset := false
for _, policyId := range txOutput.Assets().Policies() {
for _, assetName := range txOutput.Assets().Assets(policyId) {
if policyId.String() == cfg.Indexer.PolicyId {
if string(assetName) == string(origin) {
foundAsset = true
} else {
logger.Warnf(
"ignoring datum for domain %q with no matching asset",
domainName,
)
}
} else {
logger.Warnf(
"ignoring datum for domain %q with no matching asset",
domainName,
)
}
}
}
if !foundAsset {
continue
}
// Make sure all records are for specified origin domain
badRecordName := false
for _, record := range dnsDomain.Records {
recordName := dns.CanonicalName(
string(record.Lhs),
)
if !strings.HasSuffix(recordName, domainName) {
logger.Warnf(
"ignoring datum with record %q outside of origin domain (%s)",
recordName,
domainName,
)
badRecordName = true
break
}
}
if badRecordName {
continue
}
}
nameServers := map[string]string{}
for _, record := range dnsDomain.Records {
recordName := strings.Trim(
string(record.Lhs),
`.`,
)
// NOTE: we're losing information here, but we need to revamp the storage
// format before we can use it. We're also making the assumption that all
// records are for nameservers
switch strings.ToUpper(string(record.Type)) {
case "A", "AAAA":
nameServers[string(record.Lhs)] = string(record.Rhs)
nameServers[recordName] = string(record.Rhs)
default:
continue
}
Expand Down