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