-
Notifications
You must be signed in to change notification settings - Fork 16
/
limited.go
98 lines (87 loc) · 3.04 KB
/
limited.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
package routinghelpers
import (
"context"
"io"
"strings"
ci "github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/routing"
)
// LimitedValueStore limits the internal value store to the given namespaces.
type LimitedValueStore struct {
routing.ValueStore
Namespaces []string
}
// GetPublicKey returns the public key for the given peer, if and only if this
// router supports the /pk namespace. Otherwise, it returns routing.ErrNotFound.
func (lvs *LimitedValueStore) GetPublicKey(ctx context.Context, p peer.ID) (ci.PubKey, error) {
for _, ns := range lvs.Namespaces {
if ns == "pk" {
return routing.GetPublicKey(lvs.ValueStore, ctx, p)
}
}
return nil, routing.ErrNotFound
}
// PutValue puts the given key in the underlying value store if the namespace
// is supported. Otherwise, it returns routing.ErrNotSupported.
func (lvs *LimitedValueStore) PutValue(ctx context.Context, key string, value []byte, opts ...routing.Option) error {
if !lvs.KeySupported(key) {
return routing.ErrNotSupported
}
return lvs.ValueStore.PutValue(ctx, key, value, opts...)
}
// KeySupported returns true if the passed key is supported by this value store.
func (lvs *LimitedValueStore) KeySupported(key string) bool {
if len(key) < 3 {
return false
}
if key[0] != '/' {
return false
}
key = key[1:]
for _, ns := range lvs.Namespaces {
if len(ns) < len(key) && strings.HasPrefix(key, ns) && key[len(ns)] == '/' {
return true
}
}
return false
}
// GetValue retrieves the given key from the underlying value store if the namespace
// is supported. Otherwise, it returns routing.ErrNotFound.
func (lvs *LimitedValueStore) GetValue(ctx context.Context, key string, opts ...routing.Option) ([]byte, error) {
if !lvs.KeySupported(key) {
return nil, routing.ErrNotFound
}
return lvs.ValueStore.GetValue(ctx, key, opts...)
}
// SearchValue searches the underlying value store for the given key if the
// namespace is supported, returning results in monotonically increasing
// "freshness". Otherwise, it returns an empty, closed channel to indicate that
// the value wasn't found.
func (lvs *LimitedValueStore) SearchValue(ctx context.Context, key string, opts ...routing.Option) (<-chan []byte, error) {
if !lvs.KeySupported(key) {
out := make(chan []byte)
close(out)
return out, nil
}
return lvs.ValueStore.SearchValue(ctx, key, opts...)
}
// Bootstrap signals the underlying value store to get into the "bootstrapped"
// state, if it implements the Bootstrap interface.
func (lvs *LimitedValueStore) Bootstrap(ctx context.Context) error {
if bs, ok := lvs.ValueStore.(Bootstrap); ok {
return bs.Bootstrap(ctx)
}
return nil
}
// Close closest the underlying value store if it implements the io.Closer
// interface.
func (lvs *LimitedValueStore) Close() error {
if closer, ok := lvs.ValueStore.(io.Closer); ok {
return closer.Close()
}
return nil
}
var _ routing.PubKeyFetcher = (*LimitedValueStore)(nil)
var _ routing.ValueStore = (*LimitedValueStore)(nil)
var _ Bootstrap = (*LimitedValueStore)(nil)