Routing Table Replacement Cache (#229)

* creating replacement cache

* wip

* wip

* rewrites replacement cache

* replacement cache tests

* update and remove node tests

* check if dropped node got added to replacement cache from add node method

* wip

* wip

* making changes based on pr
This commit is contained in:
Jennifer Li Johnson 2018-08-17 15:11:46 -04:00 committed by GitHub
parent a522cabfbd
commit 91bf6e19e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 302 additions and 150 deletions

View File

@ -104,7 +104,6 @@ func (k Kademlia) GetNodes(ctx context.Context, start string, limit int, restric
for _, r := range restrictions {
nodes = restrict(r, nodes)
}
fmt.Printf("get nodes length %v\n", len(nodes))
return nodes, nil
}

View File

@ -24,8 +24,8 @@ func StringToNodeID(s string) *NodeID {
return &n
}
// TODO@ASK: this should be removed; superseded by `CASetupConfig.Create` / `IdentitySetupConfig.Create`
// NewID returns a pointer to a newly intialized NodeID
// TODO@ASK: this should be removed; superseded by `CASetupConfig.Create` / `IdentitySetupConfig.Create`
func NewID() (*NodeID, error) {
b, err := newID()
if err != nil {

View File

@ -0,0 +1,21 @@
// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package kademlia
import (
proto "storj.io/storj/protos/overlay"
"storj.io/storj/storage"
)
func (rt *RoutingTable) addToReplacementCache(kadBucketID storage.Key, node *proto.Node) {
bucketID := string(kadBucketID)
nodes := rt.replacementCache[bucketID]
nodes = append(nodes, node)
if len(nodes) > rt.rcBucketSize {
copy(nodes, nodes[1:])
nodes = nodes[:len(nodes)-1]
}
rt.replacementCache[bucketID] = nodes
}

View File

@ -0,0 +1,30 @@
// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information
package kademlia
import (
"testing"
"github.com/stretchr/testify/assert"
proto "storj.io/storj/protos/overlay"
)
func TestAddToReplacementCache(t *testing.T) {
rt := createRT([]byte{244, 255})
kadBucketID := []byte{255, 255}
node1 := mockNode(string([]byte{233, 255}))
rt.addToReplacementCache(kadBucketID, node1)
assert.Equal(t, []*proto.Node{node1}, rt.replacementCache[string(kadBucketID)])
kadBucketID2 := []byte{127, 255}
node2 := mockNode(string([]byte{100, 255}))
node3 := mockNode(string([]byte{90, 255}))
node4 := mockNode(string([]byte{80, 255}))
rt.addToReplacementCache(kadBucketID2, node2)
rt.addToReplacementCache(kadBucketID2, node3)
assert.Equal(t, []*proto.Node{node1}, rt.replacementCache[string(kadBucketID)])
assert.Equal(t, []*proto.Node{node2, node3}, rt.replacementCache[string(kadBucketID2)])
rt.addToReplacementCache(kadBucketID2, node4)
assert.Equal(t, []*proto.Node{node3, node4}, rt.replacementCache[string(kadBucketID2)])
}

View File

@ -25,21 +25,25 @@ var RoutingErr = errs.Class("routing table error")
// RoutingTable implements the RoutingTable interface
type RoutingTable struct {
self *proto.Node
kadBucketDB storage.KeyValueStore
nodeBucketDB storage.KeyValueStore
transport *proto.NodeTransport
mutex *sync.Mutex
idLength int // kbucket and node id bit length (SHA256) = 256
bucketSize int // max number of nodes stored in a kbucket = 20 (k)
self *proto.Node
kadBucketDB storage.KeyValueStore
nodeBucketDB storage.KeyValueStore
transport *proto.NodeTransport
mutex *sync.Mutex
replacementCache map[string][]*proto.Node
idLength int // kbucket and node id bit length (SHA256) = 256
bucketSize int // max number of nodes stored in a kbucket = 20 (k)
rcBucketSize int // replacementCache bucket max length
}
//RoutingOptions for configuring RoutingTable
type RoutingOptions struct {
kpath string
npath string
idLength int
bucketSize int
kpath string
npath string
rpath string
idLength int
bucketSize int
rcBucketSize int
}
// NewRoutingTable returns a newly configured instance of a RoutingTable
@ -53,17 +57,20 @@ func NewRoutingTable(localNode *proto.Node, options *RoutingOptions) (*RoutingTa
if err != nil {
return nil, RoutingErr.New("could not create nodeBucketDB: %s", err)
}
rp := make(map[string][]*proto.Node)
rt := &RoutingTable{
self: localNode,
kadBucketDB: kdb,
nodeBucketDB: ndb,
transport: &defaultTransport,
mutex: &sync.Mutex{},
idLength: options.idLength,
bucketSize: options.bucketSize,
self: localNode,
kadBucketDB: kdb,
nodeBucketDB: ndb,
transport: &defaultTransport,
mutex: &sync.Mutex{},
replacementCache: rp,
idLength: options.idLength,
bucketSize: options.bucketSize,
rcBucketSize: options.rcBucketSize,
}
err = rt.addNode(localNode)
if err != nil {
ok, err := rt.addNode(localNode)
if ok == false || err != nil {
return nil, RoutingErr.New("could not add localNode to routing table: %s", err)
}
return rt, nil

View File

@ -6,8 +6,6 @@ package kademlia
import (
"bytes"
"math/rand"
// "strconv"
// "fmt"
"encoding/binary"
"time"
@ -19,83 +17,85 @@ import (
// addNode attempts to add a new contact to the routing table
// Requires node not already in table
func (rt *RoutingTable) addNode(node *proto.Node) error {
// Returns true if node was added successfully
func (rt *RoutingTable) addNode(node *proto.Node) (bool, error) {
rt.mutex.Lock()
defer rt.mutex.Unlock()
nodeKey := storage.Key(node.Id)
if bytes.Equal(nodeKey, storage.Key(rt.self.Id)) {
err := rt.createOrUpdateKBucket(rt.createFirstBucketID(), time.Now())
if err != nil {
return RoutingErr.New("could not create initial K bucket: %s", err)
return false, RoutingErr.New("could not create initial K bucket: %s", err)
}
nodeValue, err := marshalNode(*node)
if err != nil {
return RoutingErr.New("could not marshal initial node: %s", err)
return false, RoutingErr.New("could not marshal initial node: %s", err)
}
err = rt.putNode(nodeKey, nodeValue)
if err != nil {
return RoutingErr.New("could not add initial node to nodeBucketDB: %s", err)
return false, RoutingErr.New("could not add initial node to nodeBucketDB: %s", err)
}
return nil
return true, nil
}
kadBucketID, err := rt.getKBucketID(nodeKey)
if err != nil {
return RoutingErr.New("could not getKBucketID: %s", err)
return false, RoutingErr.New("could not getKBucketID: %s", err)
}
hasRoom, err := rt.kadBucketHasRoom(kadBucketID)
if err != nil {
return err
return false, err
}
containsLocal, err := rt.kadBucketContainsLocalNode(kadBucketID)
if err != nil {
return err
return false, err
}
withinK, err := rt.nodeIsWithinNearestK(nodeKey)
if err != nil {
return RoutingErr.New("could not determine if node is within k: %s", err)
return false, RoutingErr.New("could not determine if node is within k: %s", err)
}
for !hasRoom {
if containsLocal || withinK {
depth, err := rt.determineLeafDepth(kadBucketID)
if err != nil {
return RoutingErr.New("could not determine leaf depth: %s", err)
return false, RoutingErr.New("could not determine leaf depth: %s", err)
}
kadBucketID = rt.splitBucket(kadBucketID, depth)
err = rt.createOrUpdateKBucket(kadBucketID, time.Now())
if err != nil {
return RoutingErr.New("could not split and create K bucket: %s", err)
return false, RoutingErr.New("could not split and create K bucket: %s", err)
}
kadBucketID, err = rt.getKBucketID(nodeKey)
if err != nil {
return RoutingErr.New("could not get k bucket Id within add node split bucket checks: %s", err)
return false, RoutingErr.New("could not get k bucket Id within add node split bucket checks: %s", err)
}
hasRoom, err = rt.kadBucketHasRoom(kadBucketID)
if err != nil {
return err
return false, err
}
containsLocal, err = rt.kadBucketContainsLocalNode(kadBucketID)
if err != nil {
return err
return false, err
}
} else {
return nil
rt.addToReplacementCache(kadBucketID, node)
return false, nil
}
}
nodeValue, err := marshalNode(*node)
if err != nil {
return RoutingErr.New("could not marshal node: %s", err)
return false, RoutingErr.New("could not marshal node: %s", err)
}
err = rt.putNode(nodeKey, nodeValue)
if err != nil {
return RoutingErr.New("could not add node to nodeBucketDB: %s", err)
return false, RoutingErr.New("could not add node to nodeBucketDB: %s", err)
}
err = rt.createOrUpdateKBucket(kadBucketID, time.Now())
if err != nil {
return RoutingErr.New("could not create or update K bucket: %s", err)
return false, RoutingErr.New("could not create or update K bucket: %s", err)
}
return nil
return true, nil
}
// nodeAlreadyExists will return true if the given node ID exists within nodeBucketDB
@ -113,23 +113,42 @@ func (rt *RoutingTable) nodeAlreadyExists(nodeID storage.Key) (bool, error) {
// updateNode will update the node information given that
// the node is already in the routing table.
func (rt *RoutingTable) updateNode(node *proto.Node) error {
//TODO (JJ)
marshaledNode, err := marshalNode(*node)
if err != nil {
return err
}
err = rt.putNode(storage.Key(node.Id), marshaledNode)
if err != nil {
return RoutingErr.New("could not update node: %v", err)
}
return nil
}
// removeNode will remove nodes and replace those entries with nodes
// from the replacement cache.
// We want to replace churned nodes (no longer online)
func (rt *RoutingTable) removeNode(nodeID storage.Key) error {
//TODO (JJ)
// removeNode will remove churned nodes and replace those entries with nodes from the replacement cache.
func (rt *RoutingTable) removeNode(kadBucketID storage.Key, nodeID storage.Key) error {
err := rt.nodeBucketDB.Delete(nodeID)
if err != nil {
return RoutingErr.New("could not delete node %s", err)
}
nodes := rt.replacementCache[string(kadBucketID)]
if len(nodes) == 0 {
return nil
}
last := nodes[len(nodes)-1]
val, err := marshalNode(*last)
if err != nil {
return err
}
err = rt.putNode(storage.Key(last.Id), val)
if err != nil {
return err
}
rt.replacementCache[string(kadBucketID)] = nodes[:len(nodes)-1]
return nil
}
// marshalNode: helper, sanitizes proto Node for db insertion
func marshalNode(node proto.Node) ([]byte, error) {
// n := *node
// n.Id = "-"
node.Id = "-"
nodeVal, err := pb.Marshal(&node)
if err != nil {
@ -138,7 +157,7 @@ func marshalNode(node proto.Node) ([]byte, error) {
return nodeVal, nil
}
// putNode: helper, adds proto Node and ID to nodeBucketDB
// putNode: helper, adds or updates proto Node and ID to nodeBucketDB
func (rt *RoutingTable) putNode(nodeKey storage.Key, nodeValue storage.Value) error {
err := rt.nodeBucketDB.Put(nodeKey, nodeValue)
if err != nil {

View File

@ -37,8 +37,10 @@ func createRT(localNodeID []byte) *RoutingTable {
options := &RoutingOptions{
kpath: tempfile("Kadbucket"),
npath: tempfile("Nodebucket"),
rpath: tempfile("ReplacementCache"),
idLength: 16,
bucketSize: 6,
rcBucketSize: 2,
}
rt, _ := NewRoutingTable(localNode, options)
return rt
@ -55,9 +57,11 @@ func TestAddNode(t *testing.T) {
bucket, err := rt.kadBucketDB.Get(storage.Key([]byte{255, 255}))
assert.NoError(t, err)
assert.NotNil(t, bucket)
var ok bool
//add node to unfilled kbucket
node1 := mockNode("PO") //[80, 79] or [01010000, 01001111]
err = rt.addNode(node1)
ok, err = rt.addNode(node1)
assert.True(t, ok)
assert.NoError(t, err)
kadKeys, err := rt.kadBucketDB.List(nil, 0)
assert.NoError(t, err)
@ -68,19 +72,23 @@ func TestAddNode(t *testing.T) {
//add node to full kbucket and split
node2 := mockNode("NO") //[78, 79] or [01001110, 01001111]
err = rt.addNode(node2)
ok, err = rt.addNode(node2)
assert.True(t, ok)
assert.NoError(t, err)
node3 := mockNode("MO") //[77, 79] or [01001101, 01001111]
err = rt.addNode(node3)
ok, err = rt.addNode(node3)
assert.True(t, ok)
assert.NoError(t, err)
node4 := mockNode("LO") //[76, 79] or [01001100, 01001111]
err = rt.addNode(node4)
ok, err = rt.addNode(node4)
assert.True(t, ok)
assert.NoError(t, err)
node5 := mockNode("QO") //[81, 79] or [01010001, 01001111]
err = rt.addNode(node5)
ok, err = rt.addNode(node5)
assert.True(t, ok)
assert.NoError(t, err)
kadKeys, err = rt.kadBucketDB.List(nil, 0)
@ -92,7 +100,8 @@ func TestAddNode(t *testing.T) {
//splitting here
node6 := mockNode("SO")
err = rt.addNode(node6)
ok, err = rt.addNode(node6)
assert.True(t, ok)
assert.NoError(t, err)
kadKeys, err = rt.kadBucketDB.List(nil, 0)
@ -121,27 +130,33 @@ func TestAddNode(t *testing.T) {
//add node to full kbucket and drop
node7 := mockNode("?O")
err = rt.addNode(node7)
ok, err = rt.addNode(node7)
assert.True(t, ok)
assert.NoError(t, err)
node8 := mockNode(">O")
err = rt.addNode(node8)
ok, err = rt.addNode(node8)
assert.True(t, ok)
assert.NoError(t, err)
node9 := mockNode("=O")
err = rt.addNode(node9)
ok, err = rt.addNode(node9)
assert.True(t, ok)
assert.NoError(t, err)
node10 := mockNode(";O")
err = rt.addNode(node10)
ok, err = rt.addNode(node10)
assert.True(t, ok)
assert.NoError(t, err)
node11 := mockNode(":O")
err = rt.addNode(node11)
ok, err = rt.addNode(node11)
assert.True(t, ok)
assert.NoError(t, err)
node12 := mockNode("9O")
err = rt.addNode(node12)
ok, err = rt.addNode(node12)
assert.True(t, ok)
assert.NoError(t, err)
kadKeys, err = rt.kadBucketDB.List(nil, 0)
@ -156,9 +171,13 @@ func TestAddNode(t *testing.T) {
assert.Equal(t, 6, len(a))
//should drop
node13 := mockNode("8O")
err = rt.addNode(node13)
node13 := mockNode("8O")
ok, err = rt.addNode(node13)
assert.False(t, ok)
assert.NoError(t, err)
//check if node13 it into the replacement cache
ns := rt.replacementCache[string([]byte{63, 255})]
assert.Equal(t, node13.Id, ns[0].Id)
kadKeys, err = rt.kadBucketDB.List(nil, 0)
assert.NoError(t, err)
@ -173,21 +192,26 @@ func TestAddNode(t *testing.T) {
//add node to highly unbalanced tree
//adding to bucket 1
node14 := mockNode("KO") //75
err = rt.addNode(node14)
ok, err = rt.addNode(node14)
assert.True(t, ok)
assert.NoError(t, err)
node15 := mockNode("JO") //74
err = rt.addNode(node15)
ok, err = rt.addNode(node15)
assert.True(t, ok)
assert.NoError(t, err)
//adding to bucket 2
node16 := mockNode("]O") //93
err = rt.addNode(node16)
ok, err = rt.addNode(node16)
assert.True(t, ok)
assert.NoError(t, err)
node17 := mockNode("^O") //94
err = rt.addNode(node17)
ok, err = rt.addNode(node17)
assert.True(t, ok)
assert.NoError(t, err)
node18 := mockNode("_O") //95
err = rt.addNode(node18)
ok, err = rt.addNode(node18)
assert.True(t, ok)
assert.NoError(t, err)
b, err = rt.getNodeIDsWithinKBucket(kadKeys[1])
@ -205,7 +229,8 @@ func TestAddNode(t *testing.T) {
//split bucket 2
node19 := mockNode("@O")
err = rt.addNode(node19)
ok, err = rt.addNode(node19)
assert.True(t, ok)
assert.NoError(t, err)
kadKeys, err = rt.kadBucketDB.List(nil, 0)
assert.NoError(t, err)
@ -216,6 +241,53 @@ func TestAddNode(t *testing.T) {
assert.Equal(t, 19, len(nodeKeys))
}
func TestUpdateNode(t *testing.T) {
rt := createRT([]byte("AA"))
node := mockNode("BB")
ok, err := rt.addNode(node)
assert.True(t, ok)
assert.NoError(t, err)
val, err := rt.nodeBucketDB.Get(storage.Key(node.Id))
assert.NoError(t, err)
unmarshaled, err := unmarshalNodes(storage.Keys{storage.Key(node.Id)}, []storage.Value{val})
assert.NoError(t, err)
x := unmarshaled[0].Address
assert.Nil(t, x)
node.Address = &proto.NodeAddress{Address: "BB"}
err = rt.updateNode(node)
assert.NoError(t, err)
val, err = rt.nodeBucketDB.Get(storage.Key(node.Id))
assert.NoError(t, err)
unmarshaled, err = unmarshalNodes(storage.Keys{storage.Key(node.Id)}, []storage.Value{val})
assert.NoError(t, err)
y := unmarshaled[0].Address.Address
assert.Equal(t, "BB", y)
}
func TestRemoveNode(t *testing.T) {
rt := createRT([]byte("AA"))
kadBucketID := []byte{255, 255}
node := mockNode("BB")
ok, err := rt.addNode(node)
assert.True(t, ok)
assert.NoError(t, err)
val, err := rt.nodeBucketDB.Get(storage.Key(node.Id))
assert.NoError(t, err)
assert.NotNil(t, val)
node2 := mockNode("CC")
rt.addToReplacementCache(kadBucketID, node2)
err = rt.removeNode(kadBucketID, storage.Key(node.Id))
assert.NoError(t, err)
val, err = rt.nodeBucketDB.Get(storage.Key(node.Id))
assert.Nil(t, val)
assert.Error(t, err)
val2, err := rt.nodeBucketDB.Get(storage.Key(node2.Id))
assert.NoError(t, err)
assert.NotNil(t, val2)
assert.Equal(t, 0, len(rt.replacementCache[string(kadBucketID)]))
}
func TestCreateOrUpdateKBucket(t *testing.T) {
id := []byte{255, 255}
rt := createRT(nil)

View File

@ -39,7 +39,8 @@ func TestGetBucket(t *testing.T) {
rt := createRT([]byte("AA"))
node := mockNode("AA")
node2 := mockNode("BB")
err := rt.addNode(node2)
ok, err := rt.addNode(node2)
assert.True(t, ok)
assert.NoError(t, err)
cases := []struct {
@ -70,7 +71,8 @@ func TestGetBuckets(t *testing.T) {
rt := createRT([]byte("AA"))
node := mockNode("AA")
node2 := mockNode("BB")
err := rt.addNode(node2)
ok, err := rt.addNode(node2)
assert.True(t, ok)
assert.NoError(t, err)
expected := []*proto.Node{node, node2}
buckets, err := rt.GetBuckets()
@ -86,7 +88,8 @@ func TestFindNear(t *testing.T) {
rt := createRT([]byte("AA"))
node := mockNode("AA")
node2 := mockNode("BB")
err := rt.addNode(node2)
ok, err := rt.addNode(node2)
assert.True(t, ok)
assert.NoError(t, err)
expected := []*proto.Node{node2}
nodes, err := rt.FindNear(StringToNodeID(node.Id), 1)

View File

@ -18,7 +18,7 @@ type Node struct {
tc transport.Client
cache pool.Pool
}
//TODO: change lookup to findnear
// Lookup queries nodes looking for a particular node in the network
func (n *Node) Lookup(ctx context.Context, to proto.Node, find proto.Node) ([]*proto.Node, error) {
v, err := n.cache.Get(ctx, to.GetId())

View File

@ -16,11 +16,12 @@ type Server struct {
rt dht.RoutingTable
}
//TODO: add limit to query request proto
// Query is a node to node communication query
func (s *Server) Query(ctx context.Context, req proto.QueryRequest) (proto.QueryResponse, error) {
// TODO(coyle): this will need to be added to the overlay service
//look for node in routing table?
//If not in there, add node to routing table?
// TODO: ping sender
// Add sender to rt
// look for receiver in routing table
// return receiver or find nearest to receiver
return proto.QueryResponse{}, nil
}

View File

@ -42,10 +42,10 @@ func (x NodeTransport) String() string {
return proto.EnumName(NodeTransport_name, int32(x))
}
func (NodeTransport) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{0}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{0}
}
// NodeTyp is an enum of possible node types
// NodeType is an enum of possible node types
type NodeType int32
const (
@ -66,7 +66,7 @@ func (x NodeType) String() string {
return proto.EnumName(NodeType_name, int32(x))
}
func (NodeType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{1}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{1}
}
type Restriction_Operator int32
@ -98,7 +98,7 @@ func (x Restriction_Operator) String() string {
return proto.EnumName(Restriction_Operator_name, int32(x))
}
func (Restriction_Operator) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{11, 0}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{11, 0}
}
type Restriction_Operand int32
@ -121,7 +121,7 @@ func (x Restriction_Operand) String() string {
return proto.EnumName(Restriction_Operand_name, int32(x))
}
func (Restriction_Operand) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{11, 1}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{11, 1}
}
// LookupRequest is is request message for the lookup rpc call
@ -136,7 +136,7 @@ func (m *LookupRequest) Reset() { *m = LookupRequest{} }
func (m *LookupRequest) String() string { return proto.CompactTextString(m) }
func (*LookupRequest) ProtoMessage() {}
func (*LookupRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{0}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{0}
}
func (m *LookupRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LookupRequest.Unmarshal(m, b)
@ -175,7 +175,7 @@ func (m *LookupResponse) Reset() { *m = LookupResponse{} }
func (m *LookupResponse) String() string { return proto.CompactTextString(m) }
func (*LookupResponse) ProtoMessage() {}
func (*LookupResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{1}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{1}
}
func (m *LookupResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LookupResponse.Unmarshal(m, b)
@ -214,7 +214,7 @@ func (m *FindStorageNodesResponse) Reset() { *m = FindStorageNodesRespon
func (m *FindStorageNodesResponse) String() string { return proto.CompactTextString(m) }
func (*FindStorageNodesResponse) ProtoMessage() {}
func (*FindStorageNodesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{2}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{2}
}
func (m *FindStorageNodesResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FindStorageNodesResponse.Unmarshal(m, b)
@ -255,7 +255,7 @@ func (m *FindStorageNodesRequest) Reset() { *m = FindStorageNodesRequest
func (m *FindStorageNodesRequest) String() string { return proto.CompactTextString(m) }
func (*FindStorageNodesRequest) ProtoMessage() {}
func (*FindStorageNodesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{3}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{3}
}
func (m *FindStorageNodesRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FindStorageNodesRequest.Unmarshal(m, b)
@ -309,7 +309,7 @@ func (m *NodeAddress) Reset() { *m = NodeAddress{} }
func (m *NodeAddress) String() string { return proto.CompactTextString(m) }
func (*NodeAddress) ProtoMessage() {}
func (*NodeAddress) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{4}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{4}
}
func (m *NodeAddress) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NodeAddress.Unmarshal(m, b)
@ -359,7 +359,7 @@ func (m *OverlayOptions) Reset() { *m = OverlayOptions{} }
func (m *OverlayOptions) String() string { return proto.CompactTextString(m) }
func (*OverlayOptions) ProtoMessage() {}
func (*OverlayOptions) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{5}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{5}
}
func (m *OverlayOptions) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_OverlayOptions.Unmarshal(m, b)
@ -425,7 +425,7 @@ func (m *NodeRep) Reset() { *m = NodeRep{} }
func (m *NodeRep) String() string { return proto.CompactTextString(m) }
func (*NodeRep) ProtoMessage() {}
func (*NodeRep) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{6}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{6}
}
func (m *NodeRep) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NodeRep.Unmarshal(m, b)
@ -458,7 +458,7 @@ func (m *NodeRestrictions) Reset() { *m = NodeRestrictions{} }
func (m *NodeRestrictions) String() string { return proto.CompactTextString(m) }
func (*NodeRestrictions) ProtoMessage() {}
func (*NodeRestrictions) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{7}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{7}
}
func (m *NodeRestrictions) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NodeRestrictions.Unmarshal(m, b)
@ -507,7 +507,7 @@ func (m *Node) Reset() { *m = Node{} }
func (m *Node) String() string { return proto.CompactTextString(m) }
func (*Node) ProtoMessage() {}
func (*Node) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{8}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{8}
}
func (m *Node) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Node.Unmarshal(m, b)
@ -567,7 +567,7 @@ func (m *QueryRequest) Reset() { *m = QueryRequest{} }
func (m *QueryRequest) String() string { return proto.CompactTextString(m) }
func (*QueryRequest) ProtoMessage() {}
func (*QueryRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{9}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{9}
}
func (m *QueryRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QueryRequest.Unmarshal(m, b)
@ -613,7 +613,7 @@ func (m *QueryResponse) Reset() { *m = QueryResponse{} }
func (m *QueryResponse) String() string { return proto.CompactTextString(m) }
func (*QueryResponse) ProtoMessage() {}
func (*QueryResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{10}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{10}
}
func (m *QueryResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QueryResponse.Unmarshal(m, b)
@ -660,7 +660,7 @@ func (m *Restriction) Reset() { *m = Restriction{} }
func (m *Restriction) String() string { return proto.CompactTextString(m) }
func (*Restriction) ProtoMessage() {}
func (*Restriction) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_c519e01640e795d6, []int{11}
return fileDescriptor_overlay_54bfbe46ae104a6e, []int{11}
}
func (m *Restriction) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Restriction.Unmarshal(m, b)
@ -893,56 +893,56 @@ var _Nodes_serviceDesc = grpc.ServiceDesc{
Metadata: "overlay.proto",
}
func init() { proto.RegisterFile("overlay.proto", fileDescriptor_overlay_c519e01640e795d6) }
func init() { proto.RegisterFile("overlay.proto", fileDescriptor_overlay_54bfbe46ae104a6e) }
var fileDescriptor_overlay_c519e01640e795d6 = []byte{
// 755 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x6e, 0xd3, 0x40,
0x10, 0x8e, 0xf3, 0xe7, 0x64, 0x92, 0x58, 0xee, 0xaa, 0xb4, 0x26, 0x02, 0xd4, 0x1a, 0x2a, 0xa0,
0x48, 0x39, 0xa4, 0x55, 0xa5, 0x1e, 0x50, 0x15, 0x48, 0xa8, 0x2a, 0x42, 0x43, 0x37, 0x96, 0x38,
0x21, 0xe1, 0xc4, 0xdb, 0xd4, 0xb4, 0xf1, 0x9a, 0xf5, 0xba, 0x10, 0xde, 0x85, 0x07, 0x40, 0xe2,
0x01, 0x39, 0x21, 0xe4, 0xf5, 0xda, 0x89, 0x93, 0xb6, 0x52, 0x4f, 0xf6, 0xcc, 0xf7, 0xcd, 0xff,
0xec, 0x40, 0x83, 0x5e, 0x13, 0x76, 0x65, 0xcf, 0x5a, 0x3e, 0xa3, 0x9c, 0x22, 0x55, 0x8a, 0x4d,
0xcd, 0x09, 0x99, 0xcd, 0x5d, 0xea, 0xc5, 0x80, 0xf9, 0x1c, 0x1a, 0x7d, 0x4a, 0x2f, 0x43, 0x1f,
0x93, 0x6f, 0x21, 0x09, 0x38, 0xda, 0x80, 0xb2, 0x47, 0x1d, 0x72, 0xd2, 0x35, 0x94, 0x2d, 0xe5,
0x45, 0x15, 0x4b, 0xc9, 0xdc, 0x03, 0x2d, 0x21, 0x06, 0x3e, 0xf5, 0x02, 0x82, 0xb6, 0xa1, 0x18,
0x61, 0x82, 0x57, 0x6b, 0x37, 0x5a, 0x49, 0xc4, 0x53, 0xea, 0x10, 0x2c, 0x20, 0xf3, 0x08, 0x8c,
0x77, 0xae, 0xe7, 0x0c, 0x39, 0x65, 0xf6, 0x84, 0x44, 0x40, 0x90, 0x9a, 0x3f, 0x85, 0x52, 0xc4,
0x09, 0x0c, 0x65, 0xab, 0xb0, 0x6a, 0x1f, 0x63, 0xe6, 0x6f, 0x05, 0x36, 0x57, 0x3d, 0xc4, 0x99,
0x3e, 0x01, 0xa0, 0xa3, 0xaf, 0x64, 0xcc, 0x87, 0xee, 0xcf, 0x38, 0x8b, 0x02, 0x5e, 0xd0, 0xa0,
0x0e, 0x68, 0x63, 0xea, 0x71, 0x66, 0x8f, 0x79, 0x9f, 0x78, 0x13, 0x7e, 0x61, 0xe4, 0x45, 0xa6,
0x0f, 0x5b, 0x13, 0x4a, 0x27, 0x57, 0x24, 0xee, 0xc0, 0x28, 0x3c, 0x6f, 0x75, 0x65, 0x4f, 0xf0,
0x92, 0x01, 0x7a, 0x05, 0x45, 0xea, 0xf3, 0xc0, 0x28, 0x08, 0xc3, 0xcd, 0x34, 0xc5, 0x41, 0xfc,
0x1d, 0xf8, 0x91, 0x55, 0x80, 0x05, 0xc9, 0xfc, 0x0c, 0xb5, 0x28, 0xbf, 0x8e, 0xe3, 0x30, 0x12,
0x04, 0x68, 0x1f, 0xaa, 0x9c, 0xd9, 0x5e, 0xe0, 0x53, 0xc6, 0x45, 0x76, 0x5a, 0x7b, 0x23, 0x53,
0xa3, 0x95, 0xa0, 0x78, 0x4e, 0x44, 0x06, 0xa8, 0x76, 0xec, 0x40, 0x64, 0x5b, 0xc5, 0x89, 0x68,
0xfe, 0x53, 0x40, 0xcb, 0xc6, 0x45, 0x87, 0x00, 0x53, 0xfb, 0x47, 0xdf, 0xe6, 0xc4, 0x1b, 0xcf,
0xe4, 0x1c, 0xee, 0xa8, 0x6e, 0x81, 0x8c, 0x0e, 0xa0, 0x31, 0x75, 0x3d, 0x4c, 0xfc, 0x90, 0x0b,
0x50, 0xf6, 0x46, 0xcf, 0x4e, 0x81, 0xf8, 0x38, 0x4b, 0x43, 0x26, 0xd4, 0xa7, 0xae, 0x37, 0xf4,
0x09, 0x71, 0xde, 0x8f, 0xfc, 0xb8, 0x33, 0x05, 0x9c, 0xd1, 0x45, 0x2b, 0x64, 0x4f, 0x69, 0xe8,
0x71, 0xa3, 0x28, 0x50, 0x29, 0xa1, 0xd7, 0x50, 0x67, 0x24, 0xe0, 0xcc, 0x1d, 0x8b, 0xf4, 0x8d,
0x92, 0x4c, 0x38, 0x1b, 0x72, 0x4e, 0xc0, 0x19, 0xba, 0x59, 0x05, 0x55, 0x26, 0x65, 0x5a, 0xa0,
0x2f, 0x93, 0xd1, 0x33, 0x68, 0x9c, 0x33, 0x42, 0xde, 0xd8, 0x9e, 0xf3, 0xdd, 0x75, 0xf8, 0x85,
0xdc, 0x88, 0xac, 0x12, 0x35, 0xa1, 0x12, 0x29, 0xba, 0x6e, 0x70, 0x29, 0x4a, 0x2e, 0xe0, 0x54,
0x36, 0xff, 0x28, 0x50, 0x8c, 0xdc, 0x22, 0x0d, 0xf2, 0xae, 0x23, 0xf7, 0x3f, 0xef, 0x3a, 0xa8,
0x95, 0x1d, 0x4a, 0xad, 0xbd, 0x9e, 0xc9, 0x59, 0x4e, 0x3c, 0x1d, 0x15, 0xda, 0x81, 0x22, 0x9f,
0xf9, 0x44, 0x34, 0x47, 0x6b, 0xaf, 0x65, 0xa7, 0x3e, 0xf3, 0x09, 0x16, 0xf0, 0x4a, 0x3f, 0x8a,
0xf7, 0xeb, 0xc7, 0x17, 0xa8, 0x9f, 0x85, 0x84, 0xcd, 0x92, 0xf7, 0xb0, 0x03, 0xe5, 0x80, 0x78,
0x0e, 0x61, 0x37, 0xbf, 0x48, 0x09, 0xa2, 0x97, 0x50, 0x61, 0x64, 0x4c, 0xdc, 0x6b, 0xc2, 0x64,
0x35, 0x4b, 0xc4, 0x14, 0x36, 0x6d, 0x68, 0xc8, 0x08, 0xf2, 0xcd, 0xde, 0x27, 0x44, 0x6c, 0x62,
0xe4, 0x6f, 0x7a, 0xdd, 0x29, 0x6c, 0xfe, 0x55, 0xa0, 0xb6, 0x50, 0x23, 0x3a, 0x84, 0x0a, 0xf5,
0x09, 0xb3, 0x39, 0x65, 0xf2, 0xd1, 0x3c, 0x4e, 0x4d, 0x17, 0x78, 0xad, 0x81, 0x24, 0xe1, 0x94,
0x8e, 0x0e, 0x40, 0x15, 0xff, 0x9e, 0x23, 0xea, 0xd2, 0xda, 0x8f, 0x6e, 0xb7, 0xf4, 0x1c, 0x9c,
0x90, 0xd1, 0x3a, 0x94, 0xae, 0xed, 0xab, 0x90, 0xc8, 0x5d, 0x8e, 0x05, 0x73, 0x1f, 0x2a, 0x49,
0x0c, 0x54, 0x86, 0x7c, 0xdf, 0xd2, 0x73, 0xd1, 0xb7, 0x77, 0xa6, 0x2b, 0xd1, 0xf7, 0xd8, 0xd2,
0xf3, 0x48, 0x85, 0x42, 0xdf, 0xea, 0xe9, 0x85, 0xe8, 0xe7, 0xd8, 0xea, 0xe9, 0x45, 0x73, 0x17,
0x54, 0xe9, 0x1f, 0xad, 0x2d, 0xed, 0xa3, 0x9e, 0x43, 0xf5, 0xf9, 0xf2, 0xe9, 0xca, 0xae, 0x01,
0x8d, 0xcc, 0x19, 0x88, 0xbc, 0x58, 0x6f, 0x3f, 0xea, 0xb9, 0x5d, 0x13, 0x2a, 0xc9, 0xaa, 0xa0,
0x2a, 0x94, 0x3a, 0xdd, 0x0f, 0x27, 0xa7, 0x7a, 0x0e, 0xd5, 0x40, 0x1d, 0x5a, 0x03, 0xdc, 0x39,
0xee, 0xe9, 0x4a, 0xfb, 0x97, 0x02, 0xaa, 0x3c, 0x07, 0xe8, 0x10, 0xca, 0xf1, 0x6d, 0x46, 0xf3,
0x0b, 0x93, 0xb9, 0xea, 0xcd, 0xcd, 0x15, 0xbd, 0x9c, 0xe8, 0x27, 0xd0, 0x97, 0xef, 0x2b, 0xda,
0x4a, 0xc9, 0xb7, 0x9c, 0xde, 0xe6, 0xf6, 0x1d, 0x8c, 0xd8, 0x71, 0xfb, 0x08, 0x4a, 0xb1, 0xb7,
0x03, 0x28, 0x89, 0x25, 0x42, 0x0f, 0x52, 0xa3, 0xc5, 0xb5, 0x6d, 0x6e, 0x2c, 0xab, 0x63, 0x07,
0xa3, 0xb2, 0x38, 0x60, 0x7b, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x5e, 0xbb, 0x1e, 0xde, 0xca,
0x06, 0x00, 0x00,
var fileDescriptor_overlay_54bfbe46ae104a6e = []byte{
// 768 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xdd, 0x4e, 0xdb, 0x48,
0x14, 0x8e, 0xf3, 0xe7, 0xe4, 0xe4, 0x47, 0x66, 0xc4, 0x82, 0x37, 0xda, 0x45, 0xe0, 0x5d, 0xb4,
0xbb, 0xac, 0x14, 0xa4, 0x80, 0x90, 0xb8, 0x58, 0xa1, 0xec, 0x26, 0x8b, 0x50, 0x53, 0x52, 0x26,
0x96, 0x7a, 0x55, 0xa9, 0x4e, 0x3c, 0x04, 0x17, 0x32, 0xe3, 0x8e, 0xc7, 0xb4, 0xe9, 0xbb, 0xf4,
0x01, 0x2a, 0xf5, 0x01, 0x7b, 0x55, 0x55, 0x1e, 0x8f, 0x9d, 0x38, 0x01, 0x24, 0xae, 0xec, 0x39,
0xdf, 0x77, 0xce, 0x7c, 0xe7, 0x67, 0x0e, 0x34, 0xd8, 0x3d, 0xe1, 0x77, 0xce, 0xbc, 0xed, 0x73,
0x26, 0x18, 0xd2, 0xd5, 0xb1, 0xb5, 0x33, 0x65, 0x6c, 0x7a, 0x47, 0x0e, 0xa5, 0x79, 0x1c, 0x5e,
0x1f, 0xba, 0x21, 0x77, 0x84, 0xc7, 0x68, 0x4c, 0xb4, 0xfe, 0x80, 0xc6, 0x80, 0xb1, 0xdb, 0xd0,
0xc7, 0xe4, 0x7d, 0x48, 0x02, 0x81, 0xb6, 0xa0, 0x4c, 0x99, 0x4b, 0x2e, 0x7a, 0xa6, 0xb6, 0xab,
0xfd, 0x59, 0xc5, 0xea, 0x64, 0x1d, 0x41, 0x33, 0x21, 0x06, 0x3e, 0xa3, 0x01, 0x41, 0x7b, 0x50,
0x8c, 0x30, 0xc9, 0xab, 0x75, 0x1a, 0xed, 0x44, 0xc1, 0x25, 0x73, 0x09, 0x96, 0x90, 0x75, 0x06,
0xe6, 0xff, 0x1e, 0x75, 0x47, 0x82, 0x71, 0x67, 0x4a, 0x22, 0x20, 0x48, 0xdd, 0x7f, 0x83, 0x52,
0xc4, 0x09, 0x4c, 0x6d, 0xb7, 0xb0, 0xee, 0x1f, 0x63, 0xd6, 0x17, 0x0d, 0xb6, 0xd7, 0x23, 0xc4,
0x4a, 0x77, 0x00, 0xd8, 0xf8, 0x1d, 0x99, 0x88, 0x91, 0xf7, 0x29, 0x56, 0x51, 0xc0, 0x4b, 0x16,
0xd4, 0x85, 0xe6, 0x84, 0x51, 0xc1, 0x9d, 0x89, 0x18, 0x10, 0x3a, 0x15, 0x37, 0x66, 0x5e, 0x2a,
0xfd, 0xb9, 0x1d, 0xd7, 0xa4, 0x9d, 0xd4, 0xa4, 0xdd, 0x53, 0x35, 0xc1, 0x2b, 0x0e, 0xe8, 0x6f,
0x28, 0x32, 0x5f, 0x04, 0x66, 0x41, 0x3a, 0x6e, 0xa7, 0x12, 0x87, 0xf1, 0x77, 0xe8, 0x47, 0x5e,
0x01, 0x96, 0x24, 0xeb, 0x0d, 0xd4, 0x22, 0x7d, 0x5d, 0xd7, 0xe5, 0x24, 0x08, 0xd0, 0x31, 0x54,
0x05, 0x77, 0x68, 0xe0, 0x33, 0x2e, 0xa4, 0xba, 0x66, 0x67, 0x2b, 0x93, 0xa3, 0x9d, 0xa0, 0x78,
0x41, 0x44, 0x26, 0xe8, 0x4e, 0x1c, 0x40, 0xaa, 0xad, 0xe2, 0xe4, 0x68, 0x7d, 0xd7, 0xa0, 0x99,
0xbd, 0x17, 0x9d, 0x02, 0xcc, 0x9c, 0x8f, 0x03, 0x47, 0x10, 0x3a, 0x99, 0xab, 0x3e, 0x3c, 0x91,
0xdd, 0x12, 0x19, 0x9d, 0x40, 0x63, 0xe6, 0x51, 0x4c, 0xfc, 0x50, 0x48, 0x50, 0xd5, 0xc6, 0xc8,
0x76, 0x81, 0xf8, 0x38, 0x4b, 0x43, 0x16, 0xd4, 0x67, 0x1e, 0x1d, 0xf9, 0x84, 0xb8, 0x2f, 0xc6,
0x7e, 0x5c, 0x99, 0x02, 0xce, 0xd8, 0xa2, 0x11, 0x72, 0x66, 0x2c, 0xa4, 0xc2, 0x2c, 0x4a, 0x54,
0x9d, 0xd0, 0x3f, 0x50, 0xe7, 0x24, 0x10, 0xdc, 0x9b, 0x48, 0xf9, 0x66, 0x49, 0x09, 0xce, 0x5e,
0xb9, 0x20, 0xe0, 0x0c, 0xdd, 0xaa, 0x82, 0xae, 0x44, 0x59, 0x36, 0x18, 0xab, 0x64, 0xf4, 0x3b,
0x34, 0xae, 0x39, 0x21, 0xff, 0x3a, 0xd4, 0xfd, 0xe0, 0xb9, 0xe2, 0x46, 0x4d, 0x44, 0xd6, 0x88,
0x5a, 0x50, 0x89, 0x0c, 0x3d, 0x2f, 0xb8, 0x95, 0x29, 0x17, 0x70, 0x7a, 0xb6, 0xbe, 0x6a, 0x50,
0x8c, 0xc2, 0xa2, 0x26, 0xe4, 0x3d, 0x57, 0xcd, 0x7f, 0xde, 0x73, 0x51, 0x3b, 0xdb, 0x94, 0x5a,
0x67, 0x33, 0xa3, 0x59, 0x75, 0x3c, 0x6d, 0x15, 0xda, 0x87, 0xa2, 0x98, 0xfb, 0x44, 0x16, 0xa7,
0xd9, 0xd9, 0xc8, 0x76, 0x7d, 0xee, 0x13, 0x2c, 0xe1, 0xb5, 0x7a, 0x14, 0x9f, 0x57, 0x8f, 0xb7,
0x50, 0xbf, 0x0a, 0x09, 0x9f, 0x27, 0xef, 0x61, 0x1f, 0xca, 0x01, 0xa1, 0x2e, 0xe1, 0x0f, 0xbf,
0x48, 0x05, 0xa2, 0xbf, 0xa0, 0xc2, 0xc9, 0x84, 0x78, 0xf7, 0x84, 0xab, 0x6c, 0x56, 0x88, 0x29,
0x6c, 0x39, 0xd0, 0x50, 0x37, 0xa8, 0x37, 0xfb, 0x9c, 0x2b, 0x62, 0x17, 0x33, 0xff, 0xd0, 0xeb,
0x4e, 0x61, 0xeb, 0x9b, 0x06, 0xb5, 0xa5, 0x1c, 0xd1, 0x29, 0x54, 0x98, 0x4f, 0xb8, 0x23, 0x18,
0x57, 0x8f, 0xe6, 0xd7, 0xd4, 0x75, 0x89, 0xd7, 0x1e, 0x2a, 0x12, 0x4e, 0xe9, 0xe8, 0x04, 0x74,
0xf9, 0x4f, 0x5d, 0x99, 0x57, 0xb3, 0xf3, 0xcb, 0xe3, 0x9e, 0xd4, 0xc5, 0x09, 0x19, 0x6d, 0x42,
0xe9, 0xde, 0xb9, 0x0b, 0x89, 0x9a, 0xe5, 0xf8, 0x60, 0x1d, 0x43, 0x25, 0xb9, 0x03, 0x95, 0x21,
0x3f, 0xb0, 0x8d, 0x5c, 0xf4, 0xed, 0x5f, 0x19, 0x5a, 0xf4, 0x3d, 0xb7, 0x8d, 0x3c, 0xd2, 0xa1,
0x30, 0xb0, 0xfb, 0x46, 0x21, 0xfa, 0x39, 0xb7, 0xfb, 0x46, 0xd1, 0x3a, 0x00, 0x5d, 0xc5, 0x47,
0x1b, 0x2b, 0xf3, 0x68, 0xe4, 0x50, 0x7d, 0x31, 0x7c, 0x86, 0x76, 0x60, 0x42, 0x23, 0xb3, 0x06,
0xa2, 0x28, 0xf6, 0x7f, 0xaf, 0x8c, 0xdc, 0x81, 0x05, 0x95, 0x64, 0x54, 0x50, 0x15, 0x4a, 0xdd,
0xde, 0xcb, 0x8b, 0x4b, 0x23, 0x87, 0x6a, 0xa0, 0x8f, 0xec, 0x21, 0xee, 0x9e, 0xf7, 0x0d, 0xad,
0xf3, 0x59, 0x03, 0x5d, 0xad, 0x03, 0x74, 0x0a, 0xe5, 0x78, 0x37, 0xa3, 0xc5, 0x86, 0xc9, 0x6c,
0xf5, 0xd6, 0xf6, 0x9a, 0x5d, 0x75, 0xf4, 0x35, 0x18, 0xab, 0xfb, 0x15, 0xed, 0xa6, 0xe4, 0x47,
0x56, 0x6f, 0x6b, 0xef, 0x09, 0x46, 0x1c, 0xb8, 0x73, 0x06, 0xa5, 0x38, 0xda, 0x09, 0x94, 0xe4,
0x10, 0xa1, 0x9f, 0x52, 0xa7, 0xe5, 0xb1, 0x6d, 0x6d, 0xad, 0x9a, 0xe3, 0x00, 0xe3, 0xb2, 0x5c,
0x60, 0x47, 0x3f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xdf, 0xb1, 0xda, 0x32, 0xda, 0x06, 0x00, 0x00,
}

View File

@ -78,7 +78,7 @@ message Node {
NodeRestrictions restrictions = 4;
}
// NodeTyp is an enum of possible node types
// NodeType is an enum of possible node types
enum NodeType {
ADMIN = 0;
STORAGE = 1;