github.com/ethersphere/bee/v2@v2.2.0/pkg/addressbook/addressbook.go (about) 1 // Copyright 2020 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package addressbook 6 7 import ( 8 "errors" 9 "fmt" 10 "strings" 11 12 "github.com/ethersphere/bee/v2/pkg/bzz" 13 "github.com/ethersphere/bee/v2/pkg/storage" 14 "github.com/ethersphere/bee/v2/pkg/swarm" 15 ) 16 17 const keyPrefix = "addressbook_entry_" 18 19 var _ Interface = (*store)(nil) 20 21 var ErrNotFound = errors.New("addressbook: not found") 22 23 // Interface is the AddressBook interface. 24 type Interface interface { 25 GetPutter 26 Remover 27 // Overlays returns a list of all overlay addresses saved in addressbook. 28 Overlays() ([]swarm.Address, error) 29 // IterateOverlays exposes overlays in a form of an iterator. 30 IterateOverlays(func(swarm.Address) (bool, error)) error 31 // Addresses returns a list of all bzz.Address-es saved in addressbook. 32 Addresses() ([]bzz.Address, error) 33 } 34 35 type GetPutter interface { 36 Getter 37 Putter 38 } 39 40 type Getter interface { 41 // Get returns pointer to saved bzz.Address for requested overlay address. 42 Get(overlay swarm.Address) (addr *bzz.Address, err error) 43 } 44 45 type Putter interface { 46 // Put saves relation between peer overlay address and bzz.Address address. 47 Put(overlay swarm.Address, addr bzz.Address) (err error) 48 } 49 50 type Remover interface { 51 // Remove removes overlay address. 52 Remove(overlay swarm.Address) error 53 } 54 55 type store struct { 56 store storage.StateStorer 57 } 58 59 // New creates new addressbook for state storer. 60 func New(storer storage.StateStorer) Interface { 61 return &store{ 62 store: storer, 63 } 64 } 65 66 func (s *store) Get(overlay swarm.Address) (*bzz.Address, error) { 67 key := keyPrefix + overlay.String() 68 v := &bzz.Address{} 69 err := s.store.Get(key, &v) 70 if err != nil { 71 if errors.Is(err, storage.ErrNotFound) { 72 return nil, ErrNotFound 73 } 74 75 return nil, err 76 } 77 return v, nil 78 } 79 80 func (s *store) Put(overlay swarm.Address, addr bzz.Address) (err error) { 81 key := keyPrefix + overlay.String() 82 return s.store.Put(key, &addr) 83 } 84 85 func (s *store) Remove(overlay swarm.Address) error { 86 return s.store.Delete(keyPrefix + overlay.String()) 87 } 88 89 func (s *store) IterateOverlays(cb func(swarm.Address) (bool, error)) error { 90 return s.store.Iterate(keyPrefix, func(key, _ []byte) (stop bool, err error) { 91 k := string(key) 92 if !strings.HasPrefix(k, keyPrefix) { 93 return true, nil 94 } 95 split := strings.SplitAfter(k, keyPrefix) 96 if len(split) != 2 { 97 return true, fmt.Errorf("invalid overlay key: %s", k) 98 } 99 addr, err := swarm.ParseHexAddress(split[1]) 100 if err != nil { 101 return true, err 102 } 103 stop, err = cb(addr) 104 if err != nil { 105 return true, err 106 } 107 if stop { 108 return true, nil 109 } 110 return false, nil 111 }) 112 } 113 114 func (s *store) Overlays() (overlays []swarm.Address, err error) { 115 err = s.IterateOverlays(func(addr swarm.Address) (stop bool, err error) { 116 overlays = append(overlays, addr) 117 return false, nil 118 }) 119 if err != nil { 120 return nil, err 121 } 122 123 return overlays, nil 124 } 125 126 func (s *store) Addresses() (addresses []bzz.Address, err error) { 127 err = s.store.Iterate(keyPrefix, func(_, value []byte) (stop bool, err error) { 128 entry := &bzz.Address{} 129 err = entry.UnmarshalJSON(value) 130 if err != nil { 131 return true, err 132 } 133 134 addresses = append(addresses, *entry) 135 return false, nil 136 }) 137 if err != nil { 138 return nil, err 139 } 140 141 return addresses, nil 142 }