From 3ee63766b08cc3fe1b4826ccf965989d460234c0 Mon Sep 17 00:00:00 2001 From: Lars Bahner Date: Sat, 6 Apr 2024 18:01:15 +0200 Subject: [PATCH] DropDB and use CSV with fsnotify --- .vscode/launch.json | 67 +------------ Makefile | 2 +- cmd/actor/config.go | 8 ++ cmd/node/{entity.go => actors.go} | 24 ++--- cmd/node/subscription.go | 2 +- cmd/pong/main.go | 6 ++ cmd/robot/robot.go | 4 +- config/actor.go | 6 +- config/db.go | 35 +++++-- db/badger/db.go | 78 --------------- db/badger/keys.go | 141 --------------------------- db/csv.go | 140 +++++++++++++++++++++++++++ db/db.go | 74 --------------- db/keys.go | 141 --------------------------- entity/actor/actor.go | 8 +- entity/actor/document.go | 6 +- entity/actor/init.go | 4 +- entity/document.go | 4 +- entity/entities.go | 39 ++++++++ entity/entity.go | 74 ++------------- entity/nicks.go | 99 +++++++++++-------- go.mod | 53 ++++++----- go.sum | 153 +++++++++++------------------- p2p/connmgr/gater.go | 30 ++---- p2p/peer/allowed.go | 37 -------- p2p/peer/connect.go | 21 +--- p2p/peer/errors.go | 10 +- p2p/peer/nicks.go | 138 ++++++++++++++++++--------- p2p/peer/peer.go | 30 ------ p2p/peers.go | 6 +- p2p/protect.go | 3 +- sysctl.sh | 1 + ui/chat.go | 8 +- ui/enter.go | 8 +- ui/entity.go | 37 +++----- ui/events.go | 1 + ui/msg.go | 4 +- ui/peer.go | 33 ++----- ui/refresh.go | 20 ++-- ui/run.go | 2 +- ui/set.go | 2 +- ui/web/components.go | 5 +- 42 files changed, 560 insertions(+), 1004 deletions(-) rename cmd/node/{entity.go => actors.go} (74%) delete mode 100644 db/badger/db.go delete mode 100644 db/badger/keys.go create mode 100644 db/csv.go delete mode 100644 db/db.go delete mode 100644 db/keys.go create mode 100644 entity/entities.go delete mode 100644 p2p/peer/allowed.go delete mode 100644 p2p/peer/peer.go diff --git a/.vscode/launch.json b/.vscode/launch.json index bc708f3..1f29164 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -17,23 +17,6 @@ "request": "launch", "mode": "auto", "program": "${workspaceFolder}/cmd/node", - }, - { - "name": "Launch allowAll", - "type": "go", - "request": "launch", - "mode": "auto", - "program": "${workspaceFolder}/cmd/actor/", - "console": "integratedTerminal", - "args": [ - "--p2p-discovery-allow-all" - ], - "env": { - "GOLOG_FILE": "/tmp/debug.log", - "GOLOG_LOG_LEVEL": "debug", - "GOLOG_STDOUT": "false", - "GOLOG_OUTPUT": "file" - } }, { "name": "Launch actor as bahner", @@ -67,20 +50,6 @@ "GOLOG_OUTPUT": "file" } }, - { - "name": "Launch relay", - "type": "go", - "request": "launch", - "mode": "auto", - "program": "${workspaceFolder}/cmd/relay/", - "console": "integratedTerminal", - "env": { - "GOLOG_FILE": "/tmp/debug.log", - "GOLOG_LOG_LEVEL": "debug", - "GOLOG_STDOUT": "false", - "GOLOG_OUTPUT": "file" - } - }, { "name": "go-ma-actor generate", "type": "go", @@ -98,39 +67,9 @@ "--generate", "--nick", "FUBAR", + "--publish", + "--force", ] - }, - { - "name": "Launch Foo", - "type": "go", - "request": "launch", - "mode": "auto", - "program": "${workspaceFolder}/cmd/actor/", - "args": [ - "-c", - "~/.ma/foo.yaml" - ], - "console": "integratedTerminal" - }, - { - "name": "show-config", - "type": "go", - "request": "launch", - "mode": "auto", - "program": "${workspaceFolder}/cmd/actor/", - "console": "integratedTerminal", - "args": [ - "--show-config" - ], - "env": { - "GO_MA_ACTOR_ACTOR_NICK": "jonatan", - "GO_MA_ACTOR_LOG_FILE": "/dev/null", - "GOLOG_FILE": "debug.log", - "GOLOG_LOG_LEVEL": "debug", - "GOLOG_STDOUT": "false", - "GOLOG_OUTPUT": "file" - } - } - + } ] } \ No newline at end of file diff --git a/Makefile b/Makefile index 5692fb1..1dee19f 100644 --- a/Makefile +++ b/Makefile @@ -89,7 +89,7 @@ clean: rm -f $(NAME)-*.tar find -type f -name "*.log" -delete rm -f actor.exe - rm go-ma-actor* + rm -f go-ma-actor* distclean: clean rm -rf releases diff --git a/cmd/actor/config.go b/cmd/actor/config.go index 307a1a6..fe49a7e 100644 --- a/cmd/actor/config.go +++ b/cmd/actor/config.go @@ -4,7 +4,11 @@ import ( "os" "github.com/bahner/go-ma-actor/config" + "github.com/bahner/go-ma-actor/entity" "github.com/bahner/go-ma-actor/entity/actor" + "github.com/bahner/go-ma-actor/p2p/peer" + + log "github.com/sirupsen/logrus" ) func initConfig(defaultProfileName string) actor.ActorConfig { @@ -24,5 +28,9 @@ func initConfig(defaultProfileName string) actor.ActorConfig { os.Exit(0) } + log.Info("Reading CSV files...") + go entity.WatchCSV() + go peer.WatchCSV() + return c } diff --git a/cmd/node/entity.go b/cmd/node/actors.go similarity index 74% rename from cmd/node/entity.go rename to cmd/node/actors.go index 3906a18..15faf0b 100644 --- a/cmd/node/entity.go +++ b/cmd/node/actors.go @@ -9,23 +9,23 @@ import ( log "github.com/sirupsen/logrus" ) -var entities *entityCache +var actors *actorCache -type entityCache struct { +type actorCache struct { store sync.Map } func init() { - entities = new(entityCache) + actors = new(actorCache) } // GetOrCreateEntity returns an entity from the cache or creates a new one // The id is just the uniqgue name of the calling entity, not the full DID -func getOrCreateEntity(id string) (*actor.Actor, error) { +func getOrCreateActor(id string) (*actor.Actor, error) { // Attempt to retrieve the entity from cache. // This is runtime, so entities will be generated at least once. - if cachedEntity, ok := entities.Get(id); ok { + if cachedEntity, ok := actors.Get(id); ok { if entity, ok := cachedEntity.(*actor.Actor); ok { log.Debugf("found topic: %s in entities cache.", id) return entity, nil // Successfully type-asserted and returned @@ -40,12 +40,12 @@ func getOrCreateEntity(id string) (*actor.Actor, error) { } // Assuming entity.NewFromKeyset returns *actor.Actor - e, err := actor.NewFromKeyset(k) + a, err := actor.NewFromKeyset(k) if err != nil { return nil, fmt.Errorf("failed to create entity: %w", err) } - e.Entity.Doc, err = e.CreateDocument(e.Entity.DID.Id) + a.Entity.Doc, err = a.CreateEntityDocument(a.Entity.DID.Id) if err != nil { return nil, fmt.Errorf("failed to create DID Document: %w", err) } @@ -53,18 +53,18 @@ func getOrCreateEntity(id string) (*actor.Actor, error) { // Force publication of document. o := doc.DefaultPublishOptions() o.Force = true - e.Entity.Doc.Publish(o) + a.Entity.Doc.Publish(o) // Cache the newly created entity for future retrievals - entities.Set(id, e) + actors.Set(id, a) - return e, nil + return a, nil } -func (e *entityCache) Set(key string, value interface{}) { +func (e *actorCache) Set(key string, value interface{}) { e.store.Store(key, value) } -func (e *entityCache) Get(key string) (interface{}, bool) { +func (e *actorCache) Get(key string) (interface{}, bool) { return e.store.Load(key) } diff --git a/cmd/node/subscription.go b/cmd/node/subscription.go index 8964e16..2c2ef40 100644 --- a/cmd/node/subscription.go +++ b/cmd/node/subscription.go @@ -65,7 +65,7 @@ func New(id string) gen.ServerBehavior { log.Debugf("Creating new genServer: %s", id) - a, err := getOrCreateEntity(id) + a, err := getOrCreateActor(id) if err != nil { log.Errorf("Error getting or creating entity: %s", err) return nil diff --git a/cmd/pong/main.go b/cmd/pong/main.go index f5ae33d..0d7b0bd 100644 --- a/cmd/pong/main.go +++ b/cmd/pong/main.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/bahner/go-ma-actor/entity/actor" + "github.com/bahner/go-ma-actor/ui/web" "github.com/bahner/go-ma-actor/p2p" ) @@ -48,6 +49,11 @@ func main() { actor.HelloWorld(ctx, a) fmt.Println("Sent hello world.") + // WEB + fmt.Println("Initialising web UI...") + wh := web.NewEntityHandler(p, a.Entity) + go web.Start(wh) + fmt.Printf("Running in pong mode as %s@%s\n", a.Entity.DID.Id, p.Host.ID()) fmt.Println("Press Ctrl-C to stop.") diff --git a/cmd/robot/robot.go b/cmd/robot/robot.go index fd23346..302c9f0 100644 --- a/cmd/robot/robot.go +++ b/cmd/robot/robot.go @@ -42,7 +42,7 @@ func NewRobot() (i *RobotStruct, err error) { go i.Robot.Entity.HandleIncomingMessages(context.Background(), messages) // Subscribe to message at location - i.Location, err = entity.GetOrCreate(config.ActorLocation(), true) + i.Location, err = entity.GetOrCreate(config.ActorLocation()) if err != nil { return nil, fmt.Errorf("failed to get or create actor location: %w", errors.Cause(err)) } @@ -110,7 +110,7 @@ func (i *RobotStruct) handleMessage(ctx context.Context, m *entity.Message) erro // Switch sender and receiver. Reply back to from :-) // Broadcast are sent to the topic, and the topic is the DID of the recipient replyFrom := i.Robot.Entity.DID.Id - replyTo, err := entity.New(m.Message.From) + replyTo, err := entity.GetOrCreate(m.Message.From) if err != nil { return fmt.Errorf("failed to create new entity: %w", errors.Cause(err)) } diff --git a/config/actor.go b/config/actor.go index ca30ce6..56ae0c6 100644 --- a/config/actor.go +++ b/config/actor.go @@ -101,7 +101,8 @@ func initActor() { // This function fails fatally, so no return value initActorKeyset(keyset_string) - if PublishFlag() && keyset_string != "" { + // If publish then publish, unless we are to generate a new keyset. + if PublishFlag() && !GenerateFlag() { fmt.Println("Publishing identity to IPFS...") err := PublishIdentityFromKeyset(keyset) if err != nil { @@ -146,7 +147,6 @@ func initActorKeyset(keyset_string string) { log.Errorf("config.initActor: %v", err) os.Exit(70) // EX_SOFTWARE } - } func generateActorIdentity(nick string) (string, error) { @@ -164,7 +164,7 @@ func generateActorIdentity(nick string) (string, error) { if err != nil { if errors.Is(err, doc.ErrAlreadyPublished) { - log.Warnf("Actor document already published: %v", err) + log.Debugf("Actor document already published: %v", err) } else { return "", fmt.Errorf("failed to publish actor identity: %w", err) } diff --git a/config/db.go b/config/db.go index b995b79..96503e3 100644 --- a/config/db.go +++ b/config/db.go @@ -6,27 +6,42 @@ import ( "github.com/spf13/viper" ) -var DefaultDbPath = internal.NormalisePath(dataHome + "/." + Profile()) +const CSVMode = 0664 + +var ( + defaultPeersPath = internal.NormalisePath(dataHome + "/peers.csv") + defaultEntitiesPath = internal.NormalisePath(dataHome + "/entities.csv") +) func init() { - pflag.String("db-path", DefaultDbPath, "Directory to use for database.") - viper.BindPFlag("db.path", pflag.Lookup("db-path")) - viper.SetDefault("db.path", DefaultDbPath) + pflag.String("peers", defaultPeersPath, "Filename for CSV peers file.") + pflag.String("entities", defaultEntitiesPath, "Filename for CSV entities file.") + + viper.BindPFlag("db.peers", pflag.Lookup("peers")) + viper.BindPFlag("db.entities", pflag.Lookup("entities")) + + viper.SetDefault("db.peers", defaultPeersPath) + viper.SetDefault("db.entities", defaultEntitiesPath) } type DBConfig struct { - Path string `yaml:"path"` + Peers string `yaml:"peers"` + Entities string `yaml:"entities"` } func DB() DBConfig { - viper.SetDefault("db.path", DefaultDbPath) - return DBConfig{ - Path: DBPath(), + Peers: DBPeers(), + Entities: DBEntities(), } + +} + +func DBPeers() string { + return viper.GetString("db.peers") } -func DBPath() string { - return viper.GetString("db.path") +func DBEntities() string { + return viper.GetString("db.entities") } diff --git a/db/badger/db.go b/db/badger/db.go deleted file mode 100644 index 27d53c6..0000000 --- a/db/badger/db.go +++ /dev/null @@ -1,78 +0,0 @@ -package db - -import ( - "fmt" - "sync" - - "github.com/bahner/go-ma-actor/config" - "github.com/bahner/go-ma-actor/internal" - badger "github.com/dgraph-io/badger/v3" - "github.com/mitchellh/go-homedir" -) - -var ( - db *badger.DB - once sync.Once -) - -// InitDB initializes the Badger database and sets the global `db` variable. -// It uses `sync.Once` to ensure that the database is opened only once. -func initDB() (*badger.DB, error) { - - var err error - - once.Do(func() { - - var dbPath string - - dbPath, err = dbDir() - if err != nil { - return - } - - read_only := config.DBRo() - - badgerOpts := badger.DefaultOptions(dbPath).WithReadOnly(read_only) - - db, err = badger.Open(badgerOpts) - if err != nil { - return - } - }) - - return db, nil -} - -// CloseDB closes the Badger database. This should be called when your application exits. -func Close() (err error) { - if db != nil { - err = db.Close() - if err != nil { - return fmt.Errorf("failed to close BadgerDB: %v", err) - } - } - return nil -} - -func DB() *badger.DB { - - if db == nil { - initDB() - } - - return db -} - -// Returns expanded path to the dbDir file -// If the expansion fails it returns an empty string -func dbDir() (string, error) { - - p := config.DBPath() - p, err := homedir.Expand(p) - if err != nil { - return "", err - } - - return internal.NormalisePath(p), nil - -} diff --git a/db/badger/keys.go b/db/badger/keys.go deleted file mode 100644 index a7c1d19..0000000 --- a/db/badger/keys.go +++ /dev/null @@ -1,141 +0,0 @@ -package db - -import ( - "errors" - "strings" - - badger "github.com/dgraph-io/badger/v3" -) - -var ( - ErrKeyNotFound = errors.New("key not found") -) - -// Returns the DID . Returns the input if the node does not exist -// This is used before we know in an Entity exists or not. It can be used anywhere. -func Get(key []byte) ([]byte, error) { - - var value []byte - - err := DB().View(func(txn *badger.Txn) error { - item, err := txn.Get(key) - if err != nil { - return err // Key not found or other error - } - err = item.Value(func(val []byte) error { - value = val - return nil - }) - return err - }) - - if err != nil { - return nil, err - } - return value, nil -} - -// Removes a node from the database if it exists. Must be a DID -// The prefix has a name, to make it obvious. eg. "entity:nick:" or "peer:nick:" -func Delete(key []byte) error { - - return DB().Update(func(txn *badger.Txn) error { - return txn.Delete(key) - }) -} - -// Sets a key to the value in the database -// Remember to use a prefix for the key. eg. "entity:nick:" or "peer:nick:" -func Set(key []byte, value []byte) error { - - return DB().Update(func(txn *badger.Txn) error { - return txn.Set(key, value) - }) -} - -// Sets a key to the value in the database, but -// it deletes the old key first if it exists. -func Upsert(prefix []byte, key []byte, value []byte) error { - return DB().Update(func(txn *badger.Txn) error { - oldKey, err := Lookup(value) - if err == nil { - if delErr := txn.Delete(oldKey); delErr != nil { - return delErr - } - } else if err != ErrKeyNotFound && err != badger.ErrKeyNotFound { - return err - } - fullKey := append(prefix, key...) - return txn.Set(fullKey, value) - }) -} - -// Try to find a key for a value. Returns the key first key found for the value. -func Lookup(value []byte) ([]byte, error) { - var foundKey []byte - - err := DB().View(func(txn *badger.Txn) error { - opts := badger.DefaultIteratorOptions - it := txn.NewIterator(opts) - defer it.Close() - - for it.Rewind(); it.Valid(); it.Next() { - item := it.Item() - err := item.Value(func(val []byte) error { - if string(val) == string(value) { - foundKey = item.Key() - return nil - } - return nil - }) - if err != nil { - return err - } - if foundKey != nil { - break // Exit the loop early if the key is found - } - } - return nil - }) - - if err != nil { - return nil, err - } - if foundKey == nil { - return nil, ErrKeyNotFound - } - return foundKey, nil -} - -// Returns a map of all keys with a given prefix. It removes the prefix from the key. -func Keys(prefix string) (map[string]string, error) { - nicks := make(map[string]string) - - err := DB().View(func(txn *badger.Txn) error { - opts := badger.DefaultIteratorOptions - opts.Prefix = []byte(prefix) - it := txn.NewIterator(opts) - defer it.Close() - - for it.Rewind(); it.Valid(); it.Next() { - item := it.Item() - key := item.Key() - - err := item.Value(func(val []byte) error { - nick := strings.TrimPrefix(string(key), prefix) - nicks[nick] = string(val) - return nil - }) - if err != nil { - return err - } - } - return nil - }) - - if err != nil { - return nil, err - } - - return nicks, nil -} diff --git a/db/csv.go b/db/csv.go new file mode 100644 index 0000000..4c5d790 --- /dev/null +++ b/db/csv.go @@ -0,0 +1,140 @@ +package db + +import ( + "encoding/csv" + "fmt" + "os" + "sync" + + "github.com/bahner/go-ma-actor/config" + "github.com/fsnotify/fsnotify" + log "github.com/sirupsen/logrus" +) + +// Save saves a sync.Map to a CSV file. +func Save(syncMap *sync.Map, filename string) error { + + file, err := os.Create(filename) + if err != nil { + log.Error("db.Save: ", err) + return err + } + defer file.Close() + + writer := csv.NewWriter(file) + syncMap.Range(func(key, value interface{}) bool { + writer.Write([]string{key.(string), value.(string)}) + return true + }) + writer.Flush() + + return writer.Error() +} + +// Watch monitors a CSV file for changes and reloads it +// and updates the sync.Map when changed. +func Watch(filename string, syncMap *sync.Map) error { + log.Debugf("db.Watch: watching %s", filename) + + err := load(filename, syncMap) // Load the file initially + if err != nil { + log.Errorf("db.Watch: %v", err) + return fmt.Errorf("db.Watch: %w", err) + } + + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Errorf("db.Watch: %v", err) + return fmt.Errorf("db.Watch: %w", err) + } + defer watcher.Close() + + // Function to re-add the file or directory to the watcher list + reAddWatcher := func(path string) error { + if err := watcher.Remove(path); err != nil { + log.Debugf("db.Watch: error removing watcher for %s: %v", path, err) + } + if err := watcher.Add(path); err != nil { + log.Errorf("db.Watch: error re-adding watcher for %s: %v", path, err) + return fmt.Errorf("db.Watch: %w", err) + } + return nil + } + + done := make(chan bool) + go func() { + defer close(done) + for { + select { + case event, ok := <-watcher.Events: + if !ok { + return + } + log.Debugf("db.Watch: event: %v", event) + if event.Op&fsnotify.Write == fsnotify.Write || event.Op&fsnotify.Rename == fsnotify.Rename { + log.Infof("db.Watch: %s modified. Reloading.", filename) + load(filename, syncMap) // Reload the file when it changes + // Attempt to re-add the file to the watcher, to continue monitoring + if err := reAddWatcher(filename); err != nil { + log.Errorf("db.Watch: %v", err) + return + } + } + case err, ok := <-watcher.Errors: + if !ok { + return + } + // Handle errors + log.Errorf("db.Watch: %v", err) + } + } + }() + + if err := watcher.Add(filename); err != nil { + log.Errorf("db.Watch: %v", err) + return fmt.Errorf("db.Watch: %w", err) + } + + // Block until the watcher is done to keep the watcher alive. + // You may need a mechanism to signal `done` based on your application's needs (not shown here). + <-done + return nil +} + +// load reads peers from a CSV file and updates the sync.Map. +func load(filename string, nicks *sync.Map) error { + + file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, config.CSVMode) + if err != nil { + log.Errorf("db.load: %v", err) + return err + } + defer file.Close() + + reader := csv.NewReader(file) + records, err := reader.ReadAll() + if err != nil { + log.Errorf("db.load: %v", err) + return err + } + + tempMap := make(map[string]string) + for _, record := range records { + tempMap[record[0]] = record[1] + } + + // Upsert entries from tempPeers into the global peers map + for key, value := range tempMap { + nicks.Store(key, value) + } + + // Optionally, remove entries in peers that are not in tempPeers + nicks.Range(func(key, value interface{}) bool { + if _, exists := tempMap[key.(string)]; !exists { + nicks.Delete(key) + } + return true + }) + + return nil +} diff --git a/db/db.go b/db/db.go deleted file mode 100644 index 41b4c40..0000000 --- a/db/db.go +++ /dev/null @@ -1,74 +0,0 @@ -package db - -import ( - "fmt" - "sync" - - "github.com/bahner/go-ma-actor/internal" - badger "github.com/dgraph-io/badger/v3" - "github.com/mitchellh/go-homedir" - "github.com/spf13/viper" -) - -var ( - db *badger.DB - once sync.Once -) - -// InitDB initializes the Badger database and sets the global `db` variable. -// It uses `sync.Once` to ensure that the database is opened only once. -func initDB() (*badger.DB, error) { - - var err error - - once.Do(func() { - - var dbPath string - - dbPath, err = dbDir() - if err != nil { - return - } - - db, err = badger.Open(badger.DefaultOptions(dbPath)) - if err != nil { - return - } - }) - - return db, nil -} - -// CloseDB closes the Badger database. This should be called when your application exits. -func Close() (err error) { - if db != nil { - err = db.Close() - if err != nil { - return fmt.Errorf("failed to close BadgerDB: %v", err) - } - } - return nil -} - -func DB() *badger.DB { - - if db == nil { - initDB() - } - - return db -} - -// Returns expanded path to the dbDir file -// If the expansion fails it returns an empty string -func dbDir() (string, error) { - - p := viper.GetString("db.path") - p, err := homedir.Expand(p) - if err != nil { - return "", err - } - - return internal.NormalisePath(p), nil - -} diff --git a/db/keys.go b/db/keys.go deleted file mode 100644 index a7c1d19..0000000 --- a/db/keys.go +++ /dev/null @@ -1,141 +0,0 @@ -package db - -import ( - "errors" - "strings" - - badger "github.com/dgraph-io/badger/v3" -) - -var ( - ErrKeyNotFound = errors.New("key not found") -) - -// Returns the DID . Returns the input if the node does not exist -// This is used before we know in an Entity exists or not. It can be used anywhere. -func Get(key []byte) ([]byte, error) { - - var value []byte - - err := DB().View(func(txn *badger.Txn) error { - item, err := txn.Get(key) - if err != nil { - return err // Key not found or other error - } - err = item.Value(func(val []byte) error { - value = val - return nil - }) - return err - }) - - if err != nil { - return nil, err - } - return value, nil -} - -// Removes a node from the database if it exists. Must be a DID -// The prefix has a name, to make it obvious. eg. "entity:nick:" or "peer:nick:" -func Delete(key []byte) error { - - return DB().Update(func(txn *badger.Txn) error { - return txn.Delete(key) - }) -} - -// Sets a key to the value in the database -// Remember to use a prefix for the key. eg. "entity:nick:" or "peer:nick:" -func Set(key []byte, value []byte) error { - - return DB().Update(func(txn *badger.Txn) error { - return txn.Set(key, value) - }) -} - -// Sets a key to the value in the database, but -// it deletes the old key first if it exists. -func Upsert(prefix []byte, key []byte, value []byte) error { - return DB().Update(func(txn *badger.Txn) error { - oldKey, err := Lookup(value) - if err == nil { - if delErr := txn.Delete(oldKey); delErr != nil { - return delErr - } - } else if err != ErrKeyNotFound && err != badger.ErrKeyNotFound { - return err - } - fullKey := append(prefix, key...) - return txn.Set(fullKey, value) - }) -} - -// Try to find a key for a value. Returns the key first key found for the value. -func Lookup(value []byte) ([]byte, error) { - var foundKey []byte - - err := DB().View(func(txn *badger.Txn) error { - opts := badger.DefaultIteratorOptions - it := txn.NewIterator(opts) - defer it.Close() - - for it.Rewind(); it.Valid(); it.Next() { - item := it.Item() - err := item.Value(func(val []byte) error { - if string(val) == string(value) { - foundKey = item.Key() - return nil - } - return nil - }) - if err != nil { - return err - } - if foundKey != nil { - break // Exit the loop early if the key is found - } - } - return nil - }) - - if err != nil { - return nil, err - } - if foundKey == nil { - return nil, ErrKeyNotFound - } - return foundKey, nil -} - -// Returns a map of all keys with a given prefix. It removes the prefix from the key. -func Keys(prefix string) (map[string]string, error) { - nicks := make(map[string]string) - - err := DB().View(func(txn *badger.Txn) error { - opts := badger.DefaultIteratorOptions - opts.Prefix = []byte(prefix) - it := txn.NewIterator(opts) - defer it.Close() - - for it.Rewind(); it.Valid(); it.Next() { - item := it.Item() - key := item.Key() - - err := item.Value(func(val []byte) error { - nick := strings.TrimPrefix(string(key), prefix) - nicks[nick] = string(val) - return nil - }) - if err != nil { - return err - } - } - return nil - }) - - if err != nil { - return nil, err - } - - return nicks, nil -} diff --git a/entity/actor/actor.go b/entity/actor/actor.go index 90a55f5..8e48a4a 100644 --- a/entity/actor/actor.go +++ b/entity/actor/actor.go @@ -32,11 +32,7 @@ func New(d did.DID, k set.Keyset) (*Actor, error) { return nil, fmt.Errorf("entity/new: failed to verify keyset: %w", err) } - // Hrm. Use the entity context or create own ... - // ctx, cancel := context.WithCancel(context.Background()) - // defer cancel() - - e, err := entity.NewFromDID(d) + e, err := entity.New(d) if err != nil { return nil, err } @@ -47,7 +43,7 @@ func New(d did.DID, k set.Keyset) (*Actor, error) { Envelopes: make(chan *msg.Envelope, ENVELOPES_BUFFERSIZE), } - a.CreateDocument(d.Id) + a.CreateEntityDocument(d.Id) // Cache the entity store(a) diff --git a/entity/actor/document.go b/entity/actor/document.go index 20e2a65..5833501 100644 --- a/entity/actor/document.go +++ b/entity/actor/document.go @@ -13,7 +13,7 @@ import ( // is the controller alone. // NB! All entities must have a document, hence we apply this to the Entity struct, // but we can only create Documents for actors. For entities we fetch them. -func (a *Actor) CreateDocument(controller string) (*doc.Document, error) { +func (a *Actor) CreateEntityDocument(controller string) (*doc.Document, error) { id := a.Entity.DID.Id @@ -99,9 +99,9 @@ func (a *Actor) CreateDocument(controller string) (*doc.Document, error) { // Creates a new DID Document for the entity, and sets it as the entity's document. // This only applies if the entity has a keyset. If the controller is "", the entity // is the controller alone. -func (a *Actor) CreateAndSetDocument(controller string) error { +func (a *Actor) CreateAndSetEntityDocument(controller string) error { - doc, err := a.CreateDocument(controller) + doc, err := a.CreateEntityDocument(controller) if err != nil { return fmt.Errorf("entity: failed to create document: %s", err) } diff --git a/entity/actor/init.go b/entity/actor/init.go index 3ee57ff..e9a905a 100644 --- a/entity/actor/init.go +++ b/entity/actor/init.go @@ -22,7 +22,7 @@ func Init() *Actor { id := a.Entity.DID.Id fmt.Println("Creating and setting DID Document for actor...") - err = a.CreateAndSetDocument(id) + err = a.CreateAndSetEntityDocument(id) if err != nil { panic(fmt.Sprintf("error creating document: %s", err)) } @@ -33,7 +33,7 @@ func Init() *Actor { panic(fmt.Sprintf("%s is not a valid actor: %v", id, err)) } - _, err = entity.GetOrCreateFromDID(a.Entity.DID, false) + _, err = entity.New(a.Entity.DID) if err != nil { panic(fmt.Sprintf("error getting or creating entity: %s", err)) } diff --git a/entity/document.go b/entity/document.go index 72b22aa..3507649 100644 --- a/entity/document.go +++ b/entity/document.go @@ -24,7 +24,7 @@ func (e *Entity) FetchDocument(cached bool) (*doc.Document, error) { // Fetch the document and set it in the entity. // If cached is true, the document will be fetched from the IPFS cache, // if available. -func (e *Entity) FetchAndSetDocument(cached bool) error { +func (e *Entity) FetchAndSetDocument() error { var ( err error @@ -32,7 +32,7 @@ func (e *Entity) FetchAndSetDocument(cached bool) error { if e.Doc == nil { // Fetch the document - e.Doc, _, err = doc.FetchFromDID(e.DID, cached) + e.Doc, _, err = doc.FetchFromDID(e.DID, false) if err != nil { return err } diff --git a/entity/entities.go b/entity/entities.go new file mode 100644 index 0000000..2b3a3b4 --- /dev/null +++ b/entity/entities.go @@ -0,0 +1,39 @@ +package entity + +import ( + "fmt" + "sync" + + "github.com/bahner/go-ma/did" +) + +var entities *sync.Map + +func init() { + entities = new(sync.Map) +} + +// GetOrCreate checks if an Entity with the given DID string exists and returns it; +// otherwise, it creates a new Entity, stores it, and returns it. +// The boolean signifies whether to use a cached Entity document in IPFS, or +// to perform a network search. This might take time at the scale of minutes. +func GetOrCreate(didString string) (*Entity, error) { + + d, err := did.New(didString) + if err != nil { + return nil, fmt.Errorf("entity/getorcreate: %w", err) + } + + if entity, ok := entities.Load(d.Id); ok { + return entity.(*Entity), nil + } + + entity, err := New(d) + if err != nil { + return nil, err + } + + entities.Store(entity.DID.Id, entity) + + return entity, nil +} diff --git a/entity/entity.go b/entity/entity.go index dbd231e..77f365e 100644 --- a/entity/entity.go +++ b/entity/entity.go @@ -3,9 +3,7 @@ package entity import ( "context" "fmt" - "strings" - "github.com/bahner/go-ma-actor/db" "github.com/bahner/go-ma-actor/p2p/pubsub" "github.com/bahner/go-ma/did" "github.com/bahner/go-ma/did/doc" @@ -33,20 +31,10 @@ type Entity struct { Messages chan *Message } -// Create a new entity from a DID -// In this case the DID is the string, not the struct. -func New(id string) (*Entity, error) { - - d, err := did.New(id) - if err != nil { - return nil, fmt.Errorf("entity/getorcreate: %w", err) - } - - return NewFromDID(d) -} - -// Create a new entity from a DID -func NewFromDID(d did.DID) (*Entity, error) { +// Create a new entity from a DID. If the entity is already known, it is returned. +// The cached parameter is used to determine if the entity should be fetched from the local IPFS node, +// or if a network search should be performed. +func New(d did.DID) (*Entity, error) { // Only 1 topic, but this is where it's at! One topic per entity. _topic, err := pubsub.GetOrCreateTopic(d.Id) @@ -57,7 +45,7 @@ func NewFromDID(d did.DID) (*Entity, error) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - return &Entity{ + e := &Entity{ Ctx: ctx, Cancel: cancel, @@ -66,59 +54,10 @@ func NewFromDID(d did.DID) (*Entity, error) { Topic: _topic, Messages: make(chan *Message, MESSAGES_BUFFERSIZE), - }, nil -} - -func GetOrCreate(id string, cached bool) (*Entity, error) { - - d, err := did.New(id) - if err != nil { - return nil, fmt.Errorf("entity/getorcreate: %w", err) - } - - return GetOrCreateFromDID(d, cached) -} - -// Sets a node in the database -// takes new did and nick. If an old did for the alias exists it is removed. -// This makes this the only alias for the DID and the only complex function in this file. -func (e Entity) SetNick(nick string) error { - - prefixBytes := []byte(entityNickPrefix) - nickBytes := []byte(nick) - idBytes := []byte(e.DID.Id) - - return db.Upsert(prefixBytes, nickBytes, idBytes) - -} - -// Returns the Entitty's nick. If it doesn't exist it returns the DID. -func (e Entity) Nick() string { - - idBytes := []byte(e.DID.Id) - - key, err := db.Lookup(idBytes) - if err != nil { - return e.DID.Id - } - - return strings.TrimPrefix(string(key), entityNickPrefix) -} - -// Get an entity from the global map. -// The input is a full did string. If one is created it will have no Nick. -// The function should do the required lookups to get the nick. -// And verify the entity. -// Cached is whether or not to use the cached copy of the entity document in IPFS -func GetOrCreateFromDID(id did.DID, cached bool) (*Entity, error) { - - e, err := NewFromDID(id) - if err != nil { - return nil, fmt.Errorf("GetOrCreateFromDID: %w", err) } // Fetch the document - err = e.FetchAndSetDocument(cached) + err = e.FetchAndSetDocument() if err != nil { return nil, fmt.Errorf("GetOrCreateFromDID: %w", err) } @@ -129,4 +68,5 @@ func GetOrCreateFromDID(id did.DID, cached bool) (*Entity, error) { } return e, nil + } diff --git a/entity/nicks.go b/entity/nicks.go index ab43c6e..fb801aa 100644 --- a/entity/nicks.go +++ b/entity/nicks.go @@ -1,61 +1,80 @@ package entity import ( - "errors" - "strings" + "sync" + "github.com/bahner/go-ma-actor/config" "github.com/bahner/go-ma-actor/db" + log "github.com/sirupsen/logrus" ) -const ( - entityNickPrefix = entityPrefix + "nick:" -) - -var ( - ErrFailedToCreateNick = errors.New("failed to set entity nick") - ErrDIDNotFound = errors.New("DID not found") - ErrNickNotFound = errors.New("Nick not found") -) +var nicks *sync.Map -// This returns the DID for the nick. -// If it doesn't exist it returns the query. -func DID(query string) string { - - queryBytes := []byte(entityNickPrefix + query) +func init() { + nicks = new(sync.Map) +} - id, err := db.Get(queryBytes) - if err != nil { - return query +// Returns the Entity's nick. Uses and sets the DID as fallback. +// This does not actually save the nick, as it it will always return +// the same value for the same DID. +func (e Entity) Nick() string { + if nick, ok := nicks.Load(e.DID.Id); ok { + return nick.(string) } - - return string(id) + return e.DID.Id } -// Removes a an entity nick from the database if it exists. -// It does a lookup to you can enter both a nick or a DID. -func DeleteNick(q string) error { - - nick := Nick(q) - nickBytes := []byte(entityNickPrefix + nick) +// Sets a node in the database +// takes new did and nick. If an old did for the alias exists it is removed. +// This makes this the only alias for the DID and the only complex function in this file. +func (e Entity) SetNick(nick string) error { + nicks.Store(e.DID.Id, nick) + return db.Save(nicks, config.DBPeers()) +} - return db.Delete(nickBytes) +func DeleteNick(id string) { + nicks.Delete(id) } -// Nick is the opposite of LookupDID. It returns the nick for a DID. -// This means iterating over all nicks to find the right one, -// hence it's not as efficient as LookupDID. -func Nick(q string) string { +// Lookup takes an input string that can be either a nick or an ID, +// and returns the corresponding ID if found; otherwise, it returns the input. +func Lookup(q string) string { + found := "" + nicks.Range(func(key, value interface{}) bool { + id := key.(string) + nick := value.(string) + + // Check if input matches either the key (ID) or the value (nick) + if q == id || q == nick { + found = id + return false // Stop iterating + } + return true // Continue iterating + }) + + if found != "" { + return found + } + return q // Return the input if no match is found +} - qBytes := []byte(q) +func Nicks() map[string]string { + nmap := make(map[string]string) // Pun intended - id, err := db.Lookup(qBytes) - if err != nil { - return q - } + nicks.Range(func(key, value interface{}) bool { + strKey, okKey := key.(string) + strValue, okValue := value.(string) + if okKey && okValue { + nmap[strKey] = strValue + } + return true + }) - return strings.TrimPrefix(string(id), entityNickPrefix) + return nmap } -func Nicks() (map[string]string, error) { - return db.Keys(entityNickPrefix) +func WatchCSV() error { + filename := config.DBEntities() + log.Infof("entity.WatchCSV: watching %s", filename) + return db.Watch(filename, nicks) } diff --git a/go.mod b/go.mod index 6ab8ad3..e2615fb 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,8 @@ require ( github.com/adrg/xdg v0.4.0 github.com/ayush6624/go-chatgpt v0.3.0 github.com/bahner/go-ma v0.7.6 - github.com/dgraph-io/badger/v3 v3.2103.5 github.com/ergo-services/ergo v1.999.224 + github.com/fsnotify/fsnotify v1.7.0 github.com/fxamacker/cbor/v2 v2.6.0 github.com/gdamore/tcell/v2 v2.7.4 github.com/hashicorp/vault/api v1.12.1 @@ -32,21 +32,18 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v3 v3.0.0 // indirect - github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect github.com/flynn/noise v1.0.1 // indirect github.com/francoispqt/gojay v1.2.13 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gdamore/encoding v1.0.0 // indirect github.com/go-jose/go-jose/v3 v3.0.1 // indirect github.com/go-logr/logr v1.4.1 // indirect @@ -54,15 +51,13 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/google/flatbuffers v1.12.1 // indirect + github.com/golang/glog v1.2.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 // indirect - github.com/google/uuid v1.5.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -118,7 +113,6 @@ require ( github.com/matoous/go-nanoid/v2 v2.0.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/miekg/dns v1.1.57 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect @@ -141,9 +135,9 @@ require ( github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect - github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/client_golang v1.19.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.4.1 // indirect @@ -161,34 +155,41 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect + github.com/stretchr/testify v1.9.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/x448/float16 v0.8.4 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.21.0 // indirect - go.opentelemetry.io/otel/trace v1.21.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/sdk v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect go.uber.org/dig v1.17.1 // indirect go.uber.org/fx v1.20.1 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect + go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.20.0 // indirect + golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.17.0 // indirect - golang.org/x/term v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.16.1 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/protobuf v1.32.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8 // indirect + google.golang.org/grpc v1.62.1 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect diff --git a/go.sum b/go.sum index 9fc95d4..3cce163 100644 --- a/go.sum +++ b/go.sum @@ -32,8 +32,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= @@ -57,7 +55,6 @@ github.com/alibabacloud-go/tea-utils v1.3.5/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQ github.com/aliyun/credentials-go v1.1.0/go.mod h1:ZXrrxv386Mj6z8NpihLKpexQE550m7j3LlyCvYub9aE= github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/ayush6624/go-chatgpt v0.3.0 h1:tQUfwSvSL9KA2XmBqj3L8aVdVPRb0Hcs3XtMmZKqsc8= github.com/ayush6624/go-chatgpt v0.3.0/go.mod h1:bn550cv7EHT7sHJG5yR60IGqjKlZ0S0Ll+IZp3z7nOc= @@ -82,8 +79,6 @@ github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -96,14 +91,10 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 h1:ZFUue+PNxmHlu7pYv+IYMtqlaO/0VwaGEqKepZf9JpA= @@ -118,15 +109,12 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= -github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= -github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -197,8 +185,9 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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 h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -220,16 +209,12 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= -github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -237,8 +222,6 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= @@ -255,8 +238,8 @@ github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0Z github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -264,13 +247,12 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/grpc-gateway v1.5.0 h1:WcmKMm43DR7RdtlkEXQJyo5ws8iTp98CyhCCbOHMvNI= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -307,7 +289,6 @@ github.com/hashicorp/vault/api v1.12.1/go.mod h1:1pqP/sErScodde+ybJCyP+ONC4jzEg7 github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c h1:17FO7HnKiFhO7iadu3zCgII+EblpdRmJt5qg9FqQo8Y= github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c/go.mod h1:1oj4+g/mN6JRuZiXHt5iFRG02e62wp5AKcB3gdgknbk= github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7UynTbtdlt+w08ggb1UGLGaGjp1mMaZhoTZSctpn5Ak= @@ -408,7 +389,6 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= @@ -469,7 +449,6 @@ github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0 github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -490,8 +469,6 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= @@ -511,7 +488,6 @@ github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceT github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -573,7 +549,6 @@ github.com/openzipkin/zipkin-go v0.4.2 h1:zjqfqHjUpPmB3c1GlCvvgsM1G4LkvqQbBDueDO github.com/openzipkin/zipkin-go v0.4.2/go.mod h1:ZeVkFjuuBiSy13y8vpSDCjMi9GoI3hPpCJSBx/EYFhY= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= @@ -620,15 +595,15 @@ github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4 github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= @@ -707,22 +682,15 @@ github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:Udh github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/speps/go-hashids v2.0.0+incompatible/go.mod h1:P7hqPzMdnZOfyIk+xrlG1QaSMw+gCBdHKsBDnhpaZvc= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -738,8 +706,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ 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.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= @@ -748,7 +717,6 @@ github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cb github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb/go.mod h1:ikPs9bRWicNw3S7XpJ8sK/smGwU9WcSVU3dy9qahYBM= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -772,7 +740,6 @@ github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1: github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -783,29 +750,28 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= -go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0/go.mod h1:iSDOcsnSA5INXzZtwaBPrKp/lWu/V14Dd+llD0oI2EA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 h1:Mw5xcxMwlqoJd97vwPxA8isEaIoxsta9/Q51+TTJLGE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0/go.mod h1:CQNu9bj7o7mC6U7+CA/schKEYakYXWr79ucDHTMGhCM= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYfrPk5SOryw1e9LDDTZCbIPFrho0ec= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 h1:s0PHtIkN+3xrbDOpt2M8OTG92cWqUESvzh2MxiR5xY8= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0/go.mod h1:hZlFbDbRt++MMPCCfSJfmhkGIWnX1h3XjkfxZUjLrIA= go.opentelemetry.io/otel/exporters/zipkin v1.21.0 h1:D+Gv6lSfrFBWmQYyxKjDd0Zuld9SRXpIrEsKZvE4DO4= go.opentelemetry.io/otel/exporters/zipkin v1.21.0/go.mod h1:83oMKR6DzmHisFOW3I+yIMGZUTjxiWaiBI8M8+TU5zE= -go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= -go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= -go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= +go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= +go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= @@ -815,8 +781,8 @@ go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -826,15 +792,14 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= go4.org v0.0.0-20230225012048-214862532bf5/go.mod h1:F57wTi5Lrj6WLyswp5EYV1ncrEbFGHD4hhz6S1ZYeaU= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -847,8 +812,8 @@ golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= -golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -913,8 +878,8 @@ golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -934,14 +899,13 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -977,13 +941,15 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1081,11 +1047,10 @@ google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 h1:OPXtXn7fNMaXwO3JvOmF1QyTc00jsSFFz1vXXBOdCDo= -google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= +google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8 h1:8eadJkXbwDEMNwcB5O0s5Y5eCfyuCLdvaiOIaGTrWmQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8 h1:IR+hp6ypxjH24bkMfEJ0yHR21+gwPWdV+/IBrPQyn3k= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1098,8 +1063,8 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1109,10 +1074,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/p2p/connmgr/gater.go b/p2p/connmgr/gater.go index 52c6c28..8324cc4 100644 --- a/p2p/connmgr/gater.go +++ b/p2p/connmgr/gater.go @@ -2,13 +2,11 @@ package connmgr import ( "github.com/bahner/go-ma-actor/config" - "github.com/bahner/go-ma-actor/p2p/peer" "github.com/libp2p/go-libp2p/core/control" "github.com/libp2p/go-libp2p/core/network" p2peer "github.com/libp2p/go-libp2p/core/peer" p2pConnmgr "github.com/libp2p/go-libp2p/p2p/net/connmgr" "github.com/multiformats/go-multiaddr" - log "github.com/sirupsen/logrus" ) // ConnectionGater is a struct that implements the network.ConnectionGater interface. @@ -41,19 +39,11 @@ func (cg *ConnectionGater) InterceptAccept(conn network.ConnMultiaddrs) (allow b func (cg *ConnectionGater) InterceptSecured(nd network.Direction, p p2peer.ID, _ network.ConnMultiaddrs) (allow bool) { // We should probably run with cg.AllowAll = true in the future - if nd == network.DirOutbound || cg.AllowAll { - return true - } - - // We normally shouldn't arrive here. - allow = cg.isAllowed(p) + // if nd == network.DirOutbound || cg.AllowAll { + // return true + // } - if allow { - log.Debugf("InterceptSecured: Allow dialing to %s", p) - } else { - log.Debugf("InterceptSecured: Block dialing to %s", p) - } - return allow + return true } func (cg *ConnectionGater) InterceptAddrDial(p p2peer.ID, _ multiaddr.Multiaddr) (allow bool) { @@ -65,11 +55,11 @@ func (cg *ConnectionGater) InterceptUpgraded(_ network.Conn) (allow bool, reason return true, 0 } -func (cg *ConnectionGater) isAllowed(p p2peer.ID) bool { +// func (cg *ConnectionGater) isAllowed(p p2peer.ID) bool { - if cg.AllowAll { - return true - } +// if cg.AllowAll { +// return true +// } - return peer.IsAllowed(p.String()) -} +// return peer.IsAllowed(p.String()) +// } diff --git a/p2p/peer/allowed.go b/p2p/peer/allowed.go deleted file mode 100644 index 755225d..0000000 --- a/p2p/peer/allowed.go +++ /dev/null @@ -1,37 +0,0 @@ -package peer - -import ( - "github.com/bahner/go-ma-actor/config" - "github.com/bahner/go-ma-actor/db" -) - -const peerAllowedPrefix = peerPrefix + "allowed:" - -func IsAllowed(id string) bool { - - allowedIdBytes := []byte(peerAllowedPrefix + id) - - allowed, err := db.Get(allowedIdBytes) - if err != nil { - return config.ALLOW_ALL_PEERS - } - return byteToBool(allowed) -} - -func SetAllowed(id string, allowed bool) error { - - allowedIdBytes := []byte(peerAllowedPrefix + id) - - return db.Set(allowedIdBytes, boolToByte(allowed)) -} - -func boolToByte(b bool) []byte { - if b { - return []byte{1} - } - return []byte{0} -} - -func byteToBool(b []byte) bool { - return b[0] == 1 -} diff --git a/p2p/peer/connect.go b/p2p/peer/connect.go index 56267b7..44a42f9 100644 --- a/p2p/peer/connect.go +++ b/p2p/peer/connect.go @@ -21,12 +21,6 @@ func ConnectAndProtect(ctx context.Context, h host.Host, pai p2peer.AddrInfo) er return ErrAddrInfoAddrsEmpty } - if !IsAllowed(id) { - log.Debugf("Peer %s is explicitly denied", id) - UnprotectPeer(h, pai.ID) - return ErrPeerDenied - } - if h.Network().Connectedness(pai.ID) == network.Connected { log.Debugf("Already connected to DHT peer: %s", id) return ErrAlreadyConnected // This is not an error, but we'll return it as such for now. @@ -37,14 +31,7 @@ func ConnectAndProtect(ctx context.Context, h host.Host, pai p2peer.AddrInfo) er log.Warnf("Failed to protect peer %s: %v", id, err) } - err = h.Connect(ctx, pai) - if err != nil { - log.Warnf("Failed to connect to peer %s: %v", id, err) - return err - } - - // Use Allowed as an indicator of known peers - return SetAllowed(id, true) + return h.Connect(ctx, pai) } func Protect(h host.Host, id p2peer.ID) error { @@ -55,10 +42,10 @@ func Protect(h host.Host, id p2peer.ID) error { h.ConnManager().Protect(id, ma.RENDEZVOUS) } - return nil + return AssertNick(id) } -func UnprotectPeer(h host.Host, id p2peer.ID) error { +func UnprotectPeer(h host.Host, id p2peer.ID) { if h.ConnManager().IsProtected(id, ma.RENDEZVOUS) { log.Infof("Unprotecting previously protected peer %s", id.String()) @@ -66,5 +53,5 @@ func UnprotectPeer(h host.Host, id p2peer.ID) error { h.ConnManager().Unprotect(id, ma.RENDEZVOUS) } - return nil + DeleteNick(id.String()) } diff --git a/p2p/peer/errors.go b/p2p/peer/errors.go index b5c5bac..29634df 100644 --- a/p2p/peer/errors.go +++ b/p2p/peer/errors.go @@ -3,11 +3,7 @@ package peer import "errors" var ( - ErrAddrInfoAddrsEmpty = errors.New("addrInfo.Addrs is empty") - ErrPeerDenied = errors.New("peer not allowed") - ErrPeerNotAllowedByDefault = errors.New("peer not allowed by default") - ErrAlreadyConnected = errors.New("already connected") - ErrFailedToCreateNick = errors.New("failed to set entity nick") - ErrDIDNotFound = errors.New("DID not found") - ErrNickNotFound = errors.New("Nick not found") + ErrAddrInfoAddrsEmpty = errors.New("addrInfo.Addrs is empty") + ErrAlreadyConnected = errors.New("already connected") + ErrNickNotFound = errors.New("Nick not found") ) diff --git a/p2p/peer/nicks.go b/p2p/peer/nicks.go index dbe5dd4..ae09eee 100644 --- a/p2p/peer/nicks.go +++ b/p2p/peer/nicks.go @@ -1,80 +1,128 @@ package peer import ( - "strings" + "sync" + "github.com/bahner/go-ma-actor/config" "github.com/bahner/go-ma-actor/db" + p2peer "github.com/libp2p/go-libp2p/core/peer" + log "github.com/sirupsen/logrus" ) -// Sets a node in the database -// takes new did and nick. If an old did for the alias exists it is removed. -// This makes this the only alias for the DID and the only complex function in this file. -func SetNick(nick string, id string) error { +const defaultNickLength = 8 - prefixBytes := []byte(peerNickPrefix) - keyBytes := []byte(nick) - valBytes := []byte(id) +var nicks *sync.Map - return db.Upsert(prefixBytes, keyBytes, valBytes) +func init() { + nicks = new(sync.Map) +} + +// If a nick is not found, it creates and sets a new one. +func AssertNick(pid p2peer.ID) error { + if IsKnown(pid) { + return nil + } + id := pid.String() + nick := createNick(id) + return SetNick(id, nick) } -// Returns the Entity's nick. If it doesn't exist it returns the query. -func Nick(id string) string { +// GetOrCreateNick looks for a peer's nick by its ID. +// If it does not exist, creates a default nick, stores, and returns it. +// Takes a peerID as input, to make sure it's valid so we don't have to +// do any more error checking. +func GetOrCreateNick(peerID p2peer.ID) string { - idBytes := []byte(id) + id := peerID.String() - key, err := db.Lookup(idBytes) - if err != nil { - return id + if nick, ok := nicks.Load(id); ok { + return nick.(string) } - return strings.TrimPrefix(string(key), peerNickPrefix) + // If not found, create a default nick + return createNick(id) } -func Nicks() (map[string]string, error) { - return db.Keys(peerNickPrefix) +func DeleteNick(id string) { + nicks.Delete(id) } -// Removes a nnick from the database if it exists. -func DeleteNick(nick string) error { +func IsKnown(peerID p2peer.ID) bool { - nickBytes := []byte(peerNickPrefix + nick) + _, ok := nicks.Load(peerID.String()) - return db.Delete(nickBytes) + return ok } -// ID is the opposite of Nick. It returns the PeerID for a nick. -func ID(q string) string { +// Lookup takes an input string that can be either a nick or an ID, +// and returns the corresponding ID if found; otherwise, it returns the input. +func Lookup(q string) string { + found := "" + nicks.Range(func(key, value interface{}) bool { + id := key.(string) + nick := value.(string) + + // Check if input matches either the key (ID) or the value (nick) + if q == id || q == nick { + found = id + return false // Stop iterating + } + return true // Continue iterating + }) + + if found != "" { + return found + } + return q // Return the input if no match is found +} - prefixBytes := []byte(peerNickPrefix) - qBytes := []byte(q) +// Nick returns the nick for a given peer ID. +func Nick(q string) (string, error) { - id, err := db.Get(append(prefixBytes, qBytes...)) - if err != nil { - return q + nick, ok := nicks.Load(q) + if !ok { + return "", ErrNickNotFound } - return string(id) + return nick.(string), nil + } -// Always returns a nick for the did, but also an error if it fails to set the nick. -func getOrCreateNick(id string) (nick string) { - nick = Nick(id) - if nick == id { - nick = createDefaultNick(id) - } - return nick +func Nicks() map[string]string { + nmap := make(map[string]string) // Pun intended + + nicks.Range(func(key, value interface{}) bool { + strKey, okKey := key.(string) + strValue, okValue := value.(string) + if okKey && okValue { + nmap[strKey] = strValue + } + return true + }) + + return nmap } -// Create a default nick from the DID -func createDefaultNick(s string) string { - runes := []rune(s) +// SetNick updates or sets a new nick for a given peer ID. +func SetNick(id, nick string) error { + nicks.Store(id, nick) + filename := config.DBPeers() + return db.Save(nicks, filename) +} + +func WatchCSV() error { + filename := config.DBPeers() + log.Infof("peer.WatchCSV: watching %s", filename) + return db.Watch(filename, nicks) +} - // This should be made from did's so length should be more than 8 - if len(runes) > 8 { - return string(runes[len(runes)-defailtNickLength:]) +// createNick creates a short nick from a peer ID. +// It simply takes the last 8 characters of the ID. +// If the ID is shorter than 8 characters, it returns the ID as is. +func createNick(id string) string { + if len(id) > defaultNickLength { + return id[len(id)-defaultNickLength:] } - // This is strange, but just return the string - return s + return id } diff --git a/p2p/peer/peer.go b/p2p/peer/peer.go deleted file mode 100644 index c0ca9b9..0000000 --- a/p2p/peer/peer.go +++ /dev/null @@ -1,30 +0,0 @@ -package peer - -import ( - "github.com/bahner/go-ma-actor/db" -) - -const ( - peerPrefix = "peer:" - peerNickPrefix = peerPrefix + "nick:" - defailtNickLength = 8 -) - -// Use the the fact that IsAllowed is set as an indicator of known peers -func IsKnown(id string) bool { - - allowedIdBytes := []byte(peerAllowedPrefix + id) - - _, err := db.Get(allowedIdBytes) - return err == nil -} - -func GetOrCreate(id string) (string, error) { - - nick := getOrCreateNick(id) - if nick == id { - return nick, ErrFailedToCreateNick - } - - return nick, nil -} diff --git a/p2p/peers.go b/p2p/peers.go index 2ed419b..42d3ac6 100644 --- a/p2p/peers.go +++ b/p2p/peers.go @@ -66,7 +66,11 @@ func (p *P2P) ConnectedProctectedPeersNickList() []string { peers := p.ConnectedProtectedPeersAddrInfo() peersNickList := make([]string, 0, len(peers)) for _, p := range peers { - nick := peer.Nick(p.ID.String()) + nick, err := peer.Nick(p.ID.String()) + if err != nil { + // We only want known live peers in the list + continue + } peersNickList = append(peersNickList, nick) } return peersNickList diff --git a/p2p/protect.go b/p2p/protect.go index 3143b19..34de9ab 100644 --- a/p2p/protect.go +++ b/p2p/protect.go @@ -26,8 +26,7 @@ func (p *P2P) protectLoop(ctx context.Context) { peers := p.Host.Network().Peers() for _, pid := range peers { - idStr := pid.String() - if peer.IsKnown(idStr) && peer.IsAllowed(idStr) { + if peer.IsKnown(pid) { peer.Protect(p.Host, pid) } } diff --git a/sysctl.sh b/sysctl.sh index 5874f61..6f05ffe 100755 --- a/sysctl.sh +++ b/sysctl.sh @@ -2,3 +2,4 @@ sudo sysctl -w net.core.rmem_max=2500000 sudo sysctl -w net.core.wmem_max=2500000 +sudo sysctl -w vm.overcommit_memory=1 diff --git a/ui/chat.go b/ui/chat.go index 2e801ad..c5bc27c 100644 --- a/ui/chat.go +++ b/ui/chat.go @@ -13,7 +13,7 @@ import ( // with the sender's nick highlighted in green. // func (ui *ChatUI) displayChatMessage(cm *msg.Message) { func (ui *ChatUI) displayChatMessage(cm *msg.Message) { - e, err := entity.GetOrCreate(cm.From, true) + e, err := entity.GetOrCreate(cm.From) if err != nil { log.Debugf("entity lookup error: %s", err) return @@ -23,7 +23,7 @@ func (ui *ChatUI) displayChatMessage(cm *msg.Message) { } func (ui *ChatUI) displayBroadcastMessage(cm *msg.Message) { - e, err := entity.GetOrCreate(cm.From, true) + e, err := entity.GetOrCreate(cm.From) if err != nil { log.Debugf("entity lookup error: %s", err) return @@ -33,7 +33,7 @@ func (ui *ChatUI) displayBroadcastMessage(cm *msg.Message) { } func (ui *ChatUI) displayPrivateMessage(cm *msg.Message) { - e, err := entity.GetOrCreate(cm.From, true) + e, err := entity.GetOrCreate(cm.From) if err != nil { log.Debugf("entity lookup error: %s", err) return @@ -43,7 +43,7 @@ func (ui *ChatUI) displayPrivateMessage(cm *msg.Message) { } func (ui *ChatUI) displaySentPrivateMessage(cm *msg.Message) { - e, err := entity.GetOrCreate(cm.To, true) + e, err := entity.GetOrCreate(cm.To) if err != nil { log.Debugf("entity lookup error: %s", err) return diff --git a/ui/enter.go b/ui/enter.go index 32648f6..9148fe2 100644 --- a/ui/enter.go +++ b/ui/enter.go @@ -21,16 +21,16 @@ func (ui *ChatUI) handleEnterCommand(args []string) { if len(args) >= 2 { id := strings.Join(args[1:], separator) - id = entity.DID(id) + id = entity.Lookup(id) - e, err := entity.GetOrCreate(id, false) + e, err := entity.GetOrCreate(id) if err != nil { ui.displaySystemMessage("Error getting entity: " + err.Error()) return } // This function handles the verification of the entity - err = ui.enterEntity(e, true) + err = ui.enterEntity(e, false) if err != nil { ui.displaySystemMessage("Error entering entity: " + err.Error()) return @@ -75,7 +75,7 @@ func (ui *ChatUI) enterEntity(e *entity.Entity, reEntry bool) error { ui.currentEntityCtx, ui.currentEntityCancel = context.WithCancel(context.Background()) ui.msgBox.Clear() - ui.msgBox.SetTitle(entity.Nick(e.DID.Id)) + ui.msgBox.SetTitle(e.Nick()) // Start handling the new topic // This *must* be called *after* the entity is set! diff --git a/ui/entity.go b/ui/entity.go index 59449d3..17c423b 100644 --- a/ui/entity.go +++ b/ui/entity.go @@ -67,11 +67,7 @@ func (ui *ChatUI) handleEntityListCommand(args []string) { log.Debugf("entity list command: %v", args) if len(args) == 2 { - nicks, err := entity.Nicks() - if err != nil { - ui.displaySystemMessage("Error fetching nicks: " + err.Error()) - return - } + nicks := entity.Nicks() log.Debugf("nicks: %v", nicks) if len(nicks) > 0 { @@ -90,19 +86,15 @@ func (ui *ChatUI) handleEntityListCommand(args []string) { func (ui *ChatUI) handleEntityNickCommand(args []string) { if len(args) >= 4 { - id := entity.DID(args[2]) + id := entity.Lookup(args[2]) nick := strings.Join(args[3:], separator) - e, err := entity.GetOrCreate(id, true) + e, err := entity.GetOrCreate(id) if err != nil { ui.displaySystemMessage("Error: " + err.Error()) return } - err = e.SetNick(nick) - if err != nil { - ui.displaySystemMessage("Error setting entity nick: " + err.Error()) - return - } + e.SetNick(nick) // Change the window title if the ID matches the current entity if id == ui.e.DID.Id { ui.msgBox.SetTitle(nick) @@ -118,7 +110,8 @@ func (ui *ChatUI) handleEntityShowCommand(args []string) { if len(args) >= 3 { id := strings.Join(args[2:], separator) - e, err := entity.GetOrCreate(entity.DID(id), true) + id = entity.Lookup(id) + e, err := entity.GetOrCreate(id) if err != nil { ui.displaySystemMessage("Error: " + err.Error()) return @@ -136,11 +129,7 @@ func (ui *ChatUI) handleEntityDeleteCommand(args []string) { if len(args) >= 3 { id := strings.Join(args[2:], separator) - err := entity.DeleteNick(id) - if err != nil { - ui.displaySystemMessage("Error deleting nick: " + err.Error()) - return - } + entity.DeleteNick(id) ui.displaySystemMessage("Nick deleted for " + id + " if it existed") return } @@ -152,8 +141,8 @@ func (ui *ChatUI) handleEntityConnectCommand(args []string) { if len(args) >= 3 { id := strings.Join(args[2:], separator) - id = entity.DID(id) - e, err := entity.GetOrCreate(id, false) // Lookup up the entity document properly. + id = entity.Lookup(id) + e, err := entity.GetOrCreate(id) if err != nil { ui.displaySystemMessage("Error: " + err.Error()) return @@ -175,14 +164,10 @@ func (ui *ChatUI) handleEntityResolveCommand(args []string) { if len(args) >= 3 { - // We must absolutely get the entity, so we can get the DID Document. - // So no caching. - CACHED := false - id := strings.Join(args[2:], separator) - id = entity.DID(id) + id = entity.Lookup(id) - e, err := entity.GetOrCreate(id, CACHED) + e, err := entity.GetOrCreate(id) if err != nil { ui.displaySystemMessage("Error fetching entity: " + err.Error()) return diff --git a/ui/events.go b/ui/events.go index 37ae419..cad90d8 100644 --- a/ui/events.go +++ b/ui/events.go @@ -70,6 +70,7 @@ func (ui *ChatUI) handleEvents() { case <-peerRefreshTicker.C: ui.refreshPeers() + ui.refreshTitle() case <-ui.chDone: return diff --git a/ui/msg.go b/ui/msg.go index 7a9164f..1e9d6bf 100644 --- a/ui/msg.go +++ b/ui/msg.go @@ -24,7 +24,7 @@ func (ui *ChatUI) handleMsgCommand(input string) { recipient := parts[0][1:] // The recipient is the first argument, without the leading @ if !did.IsValid(recipient) { - recipient = entity.DID(recipient) + recipient = entity.Lookup(recipient) } if recipient == "" { @@ -50,7 +50,7 @@ func (ui *ChatUI) handleMsgCommand(input string) { ui.displaySystemMessage(fmt.Sprintf("envelope creation error: %s", err)) } - recp, err := entity.GetOrCreate(recipient, false) + recp, err := entity.GetOrCreate(recipient) if err != nil { ui.displaySystemMessage(fmt.Sprintf("entity creation error: %s", err)) } diff --git a/ui/peer.go b/ui/peer.go index 94ac912..0703a7a 100644 --- a/ui/peer.go +++ b/ui/peer.go @@ -63,7 +63,7 @@ func (ui *ChatUI) handlePeerShowCommand(args []string) { if len(args) >= 3 { id := strings.Join(args[2:], separator) - id = peer.ID(id) + id = peer.Lookup(id) pid, err := p2peer.Decode(id) if err != nil { ui.displaySystemMessage("Error: " + err.Error()) @@ -71,7 +71,7 @@ func (ui *ChatUI) handlePeerShowCommand(args []string) { } ui.displaySystemMessage("ID: " + id) - ui.displaySystemMessage("Nick: " + peer.Nick(id)) + ui.displaySystemMessage("Nick: " + peer.GetOrCreateNick(pid)) ui.displaySystemMessage("Maddrs:") for _, maddr := range ui.p.Host.Peerstore().Addrs(pid) { ui.displaySystemMessage(maddr.String()) @@ -87,11 +87,7 @@ func (ui *ChatUI) handlePeerNickListCommand(args []string) { log.Debugf("peer list command: %v", args) if len(args) == 2 { - nicks, err := peer.Nicks() - if err != nil { - ui.displaySystemMessage("Error fetching nicks: " + err.Error()) - return - } + nicks := peer.Nicks() if len(nicks) > 0 { for k, v := range nicks { @@ -110,14 +106,10 @@ func (ui ChatUI) handlePeerNickCommand(args []string) { if len(args) >= 4 { - id := peer.ID(args[2]) + id := peer.Lookup(args[2]) nick := strings.Join(args[3:], separator) - err := peer.SetNick(nick, id) - if err != nil { - ui.displaySystemMessage("Error: " + err.Error()) - return - } + peer.SetNick(id, nick) ui.displaySystemMessage(id + " is now known as " + nick) } else { ui.handleHelpCommand(peerNickUsage, peerNickHelp) @@ -129,7 +121,7 @@ func (ui *ChatUI) handlePeerConnectCommand(args []string) { if len(args) == 3 { id := strings.Join(args[2:], separator) - id = peer.ID(id) + id = peer.Lookup(id) addrInfo, err := peer.PeerAddrInfoFromPeerIDString(ui.p.Host, id) if err != nil { @@ -151,7 +143,7 @@ func (ui *ChatUI) handlePeerFindCommand(args []string) { if len(args) >= 3 { id := strings.Join(args[2:], separator) - id = peer.ID(id) + id = peer.Lookup(id) pid, err := p2peer.Decode(id) if err != nil { ui.displaySystemMessage("Error: " + err.Error()) @@ -176,14 +168,9 @@ func (ui *ChatUI) handlePeerDeleteCommand(args []string) { if len(args) >= 3 { id := strings.Join(args[2:], separator) - id = peer.ID(id) - err := peer.DeleteNick(id) - if err != nil { - ui.displaySystemMessage("Error: " + err.Error()) - return - } - - ui.displaySystemMessage("Peer " + id + " deleted") + id = peer.Lookup(id) + peer.DeleteNick(id) + ui.displaySystemMessage("Peer " + id + " deleted if it existed") } else { ui.handleHelpCommand(peerDeleteUsage, peerDeleteHelp) } diff --git a/ui/refresh.go b/ui/refresh.go index 87dcae5..2dbf6d8 100644 --- a/ui/refresh.go +++ b/ui/refresh.go @@ -3,8 +3,6 @@ package ui import ( "fmt" "sort" - - "github.com/bahner/go-ma-actor/p2p/peer" ) const ( @@ -32,24 +30,20 @@ func (ui *ChatUI) handleRefresh() { // displays the last 8 chars of their peer id in the Peers panel in the ui. func (ui *ChatUI) refreshPeers() { - // Tweak this to change the timeout for peer discovery - peers := ui.p.ConnectedProtectedPeersAddrInfo() + plist := ui.p.ConnectedProctectedPeersNickList() + sort.Strings(plist) // clear is thread-safe ui.peersList.Clear() - plist := []string{} - - for _, p := range peers { - n := peer.Nick(p.ID.String()) - plist = append(plist, n) - } - - sort.Strings(plist) - for _, p := range plist { fmt.Fprintln(ui.peersList, p) } ui.app.Draw() } + +func (ui *ChatUI) refreshTitle() { + ui.msgBox.SetTitle(ui.e.Nick()) + ui.app.Draw() +} diff --git a/ui/run.go b/ui/run.go index dc71e59..23bc1a6 100644 --- a/ui/run.go +++ b/ui/run.go @@ -29,7 +29,7 @@ func (ui *ChatUI) Run() error { // We must wait for this to finish. fmt.Printf("Entering %s ...\n", config.ActorLocation()) - e, err := entity.GetOrCreate(config.ActorLocation(), false) + e, err := entity.GetOrCreate(config.ActorLocation()) if err != nil { return fmt.Errorf("ui/run: %w", err) } diff --git a/ui/set.go b/ui/set.go index 952168f..4480f00 100644 --- a/ui/set.go +++ b/ui/set.go @@ -60,7 +60,7 @@ func (ui *ChatUI) handleSetLocationCommand(args []string) { if location == "here" { location = ui.e.DID.Id } else { - location = entity.Nick(location) + location = entity.Lookup(location) } viper.Set("actor.location", location) diff --git a/ui/web/components.go b/ui/web/components.go index c195ca1..2011201 100644 --- a/ui/web/components.go +++ b/ui/web/components.go @@ -10,9 +10,8 @@ import ( func unorderedListFromPeerIDSlice(peers p2peer.IDSlice) string { peersMap := make(map[string]string) for _, p := range peers { - id := p.String() - nick := peer.Nick(id) - peersMap[id] = nick + nick := peer.GetOrCreateNick(p) + peersMap[p.String()] = nick } var keys []string